Expandable News Card Widget
See the Pen Expandable News Card Widget.
Tech & Dependencies
Features
- ✓ State-Driven Expansion
- ✓ CSS Transitions
- ✓ Gradient UI
- ✓ Class Component
Browser Support
Core
This Expandable News Card Widget demonstrates a classic pattern for managing content density in UI design. By default, it presents a single “Headline” state to save screen space. Upon interaction, it smoothly transitions into an “Expanded” state, revealing a scrollable list of news items. It utilizes React state to handle the logic and CSS transitions for the visual effect.
Core Technique
The component relies on toggling a CSS class based on the component’s internal state, allowing CSS to handle the heavy lifting of the animation.
1. State-Driven Class Toggling
The component is built as a React Class Component. It initializes a state object with open: false. The handleClick method toggles this boolean. In the render method, a ternary operator conditionally appends the "expand" class to the container.
// Toggling logic inside render()
<div
className={"container " + (this.state.open ? "expand" : "")}
onClick={this.handleClick}
>
{/* Content... */}
</div>
2. CSS Height Transition
The animation is achieved purely through CSS. The base .container class has a fixed height of 200px and a transition property set to animate all changes over 300ms. When the .expand class is added by React, it overrides the height property.
.container {
/* Initial compacted state */
height: 200px;
overflow: hidden; /* Hides the lower content */
transition: all 300ms ease-in-out;
}
div.expand {
/* Expanded state triggered by React */
height: 797px;
}
Note: Using a fixed pixel height (797px) in the expanded state is a “magic number” technique. For dynamic content, developers often use JavaScript to calculate the scrollHeight.
Accessibility (A11y)
The component uses a div with an onClick handler, which presents significant barriers:
- Keyboard Navigation: The
divis not focusable, meaning keyboard users cannot tab to it or activate it with Enter/Space. - Semantics: Screen readers interpret it as a generic container, not an interactive button.
- State Feedback: There is no
aria-expandedattribute to inform assistive technology of the current state.
Fix: Change the container to a <button> or add role="button", tabIndex="0", and aria-expanded={this.state.open}.
Browser Support
The snippet uses standard CSS transitions and React, ensuring broad compatibility.


