Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
ainergiz avatar

Expandable Card

  • 7 installs
  • 6 repo stars
  • Updated February 8, 2026
  • ainergiz/design-inspirations

expandable-card is a Claude Code skill that builds expandable and collapsible cards using CSS grid-rows animation for smooth transitions.

About

expandable-card is a Claude Code skill that builds smooth expand and collapse cards using a CSS grid-rows animation. The technique animates between grid-rows [0fr] and [1fr] to avoid height:auto animation problems. A developer uses it when building accordions, collapsible panels, or show/hide card sections.

  • Uses grid-rows [0fr] to [1fr] to animate to and from auto height
  • Includes accordion, accessibility, and nested-content stopPropagation variants
  • Timing-duration recommendation table for different content sizes

Expandable Card by the numbers

  • 7 all-time installs (skills.sh)
  • Ranked #1,756 of 2,244 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

expandable-card capabilities & compatibility

Capabilities
expandable card · accordion · css animation
Use cases
frontend · ui design
Pricing
Free
From the docs

What expandable-card says it does

Creates expandable/collapsible cards using CSS grid-rows animation with smooth transitions.
SKILL.md
Build smooth expand/collapse animations using CSS grid-rows, avoiding height:auto animation issues.
SKILL.md
npx skills add https://github.com/ainergiz/design-inspirations --skill expandable-card

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs7
repo stars6
Last updatedFebruary 8, 2026
Repositoryainergiz/design-inspirations

What it does

Building smooth expand/collapse cards and accordions using the CSS grid-rows animation technique.

Who is it for?

Accordions and collapsible panels needing smooth animation to and from auto height.

Skip if: Complex multi-panel state managers or virtualized lists.

When should I use this skill?

When building accordions, expandable panels, collapsible sections, or show/hide card content.

What you get

A card that expands and collapses smoothly using grid-rows animation.

  • ExpandableCard component
  • accordion and accessibility variants

By the numbers

  • 4 timing-duration recommendations
  • grid-rows [0fr] to [1fr] technique

Files

SKILL.mdMarkdownGitHub ↗

Expandable Card Pattern

Build smooth expand/collapse animations using CSS grid-rows, avoiding height:auto animation issues.

Why grid-rows?

Traditional height animation requires explicit pixel values. The grid-rows technique allows smooth animation to/from auto height:

  • grid-rows-[0fr] + overflow-hidden = collapsed (0 height)
  • grid-rows-[1fr] = expanded (natural height)

Core Implementation

"use client";

import { useState } from "react";
import { ChevronDown } from "lucide-react";

function ExpandableCard() {
  const [expanded, setExpanded] = useState(true);

  return (
    <div className="rounded-xl border overflow-hidden transition-all duration-300">
      {/* Header - clickable toggle */}
      <div
        className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-zinc-50 transition-colors"
        onClick={() => setExpanded(!expanded)}
      >
        <span className="font-medium">Card Title</span>
        <ChevronDown
          className={`w-5 h-5 transition-transform duration-200 ${
            expanded ? "rotate-180" : ""
          }`}
        />
      </div>

      {/* Content - animated container */}
      <div
        className={`grid transition-all duration-300 ease-in-out ${
          expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
        }`}
      >
        <div className="overflow-hidden">
          <div className="px-4 py-4 border-t">
            {/* Your content here */}
            <p>Expandable content goes here.</p>
          </div>
        </div>
      </div>
    </div>
  );
}

Key Elements

1. State Management

const [expanded, setExpanded] = useState(true); // Start expanded
// or
const [expanded, setExpanded] = useState(false); // Start collapsed

2. Header Click Handler

<div
  className="cursor-pointer hover:bg-zinc-50 transition-colors"
  onClick={() => setExpanded(!expanded)}
>

3. ChevronDown Rotation

<ChevronDown
  className={`transition-transform duration-200 ${
    expanded ? "rotate-180" : ""
  }`}
/>

4. Grid Container Animation

<div
  className={`grid transition-all duration-300 ease-in-out ${
    expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
  }`}
>
  <div className="overflow-hidden">
    {/* Content wrapper - REQUIRED for animation */}
  </div>
</div>

Timing Recommendations

DurationUse Case
duration-150Small cards, quick feedback
duration-200Chevron rotation
duration-300Content expansion (recommended)
duration-500Large content areas

Shadow Transition (Optional)

Add shadow that changes with state:

<div
  className={`rounded-xl border overflow-hidden transition-all duration-300 ${
    expanded ? "shadow-lg" : "shadow-sm hover:shadow-md"
  }`}
>

Accessibility Considerations

<div
  role="button"
  tabIndex={0}
  aria-expanded={expanded}
  onClick={() => setExpanded(!expanded)}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      setExpanded(!expanded);
    }
  }}
>

Common Variations

Multiple Cards (Accordion)

const [expandedId, setExpandedId] = useState<string | null>("first");

// Toggle logic
onClick={() => setExpandedId(expandedId === id ? null : id)}

Nested Content Protection

Prevent clicks on interactive content from toggling:

<a
  href="..."
  onClick={(e) => e.stopPropagation()}
>

Important: Always add stopPropagation to:

  • Links (<a>)
  • Buttons that perform actions other than toggling
  • Form inputs
  • Any interactive element that shouldn't trigger expand/collapse
// Full example with multiple interactive elements
<div className="overflow-hidden">
  <div className="px-4 py-4 border-t">
    <a
      href="https://example.com"
      onClick={(e) => e.stopPropagation()}
      className="text-blue-500 hover:underline"
    >
      External link
    </a>

    <button
      onClick={(e) => {
        e.stopPropagation();
        // Handle button action
      }}
    >
      Action Button
    </button>
  </div>
</div>

Checklist

  • [ ] overflow-hidden on inner wrapper (required for animation)
  • [ ] transition-all on grid container
  • [ ] ChevronDown has transition-transform
  • [ ] Header has cursor-pointer and hover state
  • [ ] Timing consistent (300ms recommended)

Related skills

FAQ

Why use grid-rows instead of height?

grid-rows [0fr] to [1fr] animates smoothly to and from auto height, which a plain height transition cannot.

Can it build accordions?

Yes, it includes a multiple-cards accordion variant using a single expandedId state.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.