Snippets / Layout /

Profile card with CQ

Responsive profile card that adapts layout via container queries — no media queries needed.

AC

Alex Chen

@alexchen · Product designer

Passionate about design systems and accessibility. Building tools that make the web better for everyone.

2.4kFollowers
148Following
89Posts
SJ

Sarah Johnson

@sarahj · Frontend dev

React enthusiast. CSS nerd. Writing about web performance and developer experience.

1.8kFollowers
203Following
156Posts
Widely supported
layoutno-js

Quick implementation

/* HTML: 
<div class="card-wrapper">
  <div class="profile-card">
    <div class="profile-header">
      <div class="avatar">AC</div>
      <div class="info">
        <h3>Name</h3>
        <p>Title</p>
      </div>
    </div>
    <div class="content">
      <p class="bio">...</p>
      <div class="stats">...</div>
      <div class="actions">...</div>
    </div>
  </div>
</div>
*/

.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

.profile-card {
  display: flex;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  background: var(--card);
}

.profile-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--accent);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Wide layout (container >= 18rem) */
@container card (min-width: 18rem) {
  .profile-card {
    flex-direction: row;
  }
  .profile-header {
    border-right: 1px solid var(--card-border);
    padding-right: 1rem;
  }
  .content {
    flex: 1;
  }
}

/* Narrow layout (container < 18rem) */
@container card (max-width: 17.99rem) {
  .profile-card {
    flex-direction: column;
  }
  .profile-header {
    border-right: none;
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in modern CSS layout.

Goal: Build a profile card component that adapts its layout based on available container width — no JavaScript.

Technical constraints:
- Use container-type: inline-size and @container queries to detect wrapper width.
- Structure: header (avatar + info) + content area (bio, stats, actions).
- Use oklch() for all colors — no hex or rgba().
- Layout shift: horizontal (side-by-side) when wide, vertical (stacked) when narrow.
- Include focus-visible styles for interactive elements (buttons, links).

Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept `name`, `title`, `bio`, `stats` (array), `onFollow`, `onMessage` props; include CSS as a CSS module.

Edge cases to handle:
- Disabled state: add .disabled class with opacity: 0.6 and cursor: not-allowed on actions.
- What happens if container queries are not supported? Provide a media query fallback.
- ARIA: the card should have role="article" or be wrapped in <article> for semantic meaning.

Return HTML + CSS, clearly separated.

Why this matters in 2026

Container queries flipped responsive design on its head. Instead of asking "how wide is the viewport?", you ask "how much space do I have?" — letting components self-adapt to their context. A profile card can be horizontal in a sidebar but stacked in a narrow modal, all without media queries or JS breakpoints.

This is the future of composable UI: components that know their own constraints and style accordingly. No more passing width props or fighting parent layouts.

The logic

container-type: inline-size on the wrapper establishes a sizing context. The @container card (min-width: 18rem) rule checks that context, not the viewport. When the wrapper crosses the 18rem threshold, the card switches from stacked to side-by-side layout via flex-direction.

Why not media queries? Media queries respond to viewport size — fine for page-level layouts, but useless for components embedded in varying contexts. Container queries solve that by making the component aware of its own container.

The breakpoint: 18rem is arbitrary but intentional — wide enough for side-by-side content, narrow enough to stack gracefully. Tune it based on your content's minimum readable width.

Accessibility & performance

Container queries are purely CSS — no layout thrashing, no JS observers. They're GPU-accelerated and run on the compositor thread. For accessibility, ensure the card is semantic: wrap it in <article> and use role="article" if needed. Focus rings on interactive elements (buttons, links) must be visible — don't strip :focus-visible styles.

Browser support: Container queries landed in all major browsers in 2023. For older browsers, provide a @media (min-width: 18rem) fallback that assumes the wide layout.