Featured this week
Lisbon, 5 nights
Flight and hotel in Alfama, breakfast included.
Fjords by train, 7 nights
Bergen, Flåm and the mountain line in a panoramic car.
Image-and-text card that goes from a vertical stack to a row as soon as its container reaches 280 px, with no media query and no JavaScript.
Updated
Layout switches from column to row based on container width.
This effect is free — the Utilities category contains 43 effects total, including 3 free. Effect.Labs has 840 vanilla effects. Explore the category →
Featured this week
Flight and hotel in Alfama, breakfast included.
Bergen, Flåm and the mountain line in a panoramic car.
Drag the handle: below 280 px the card stacks its image above the text.
Two days of basket weaving in the woods.
We left the village before sunrise, headlamps on, with the col still hidden in the clouds.
By noon the path turned to scree and the first marmots whistled.
The .fx-0745-root element declares container: adc-card / inline-size: the browser measures that box, not the viewport. It takes width: 100% of its parent, on a #0a0a0f background with 14 px corners. Inside, .adc-card is a column flexbox: the .adc-img picture (80 px tall, violet-to-pink gradient) spans the full width, followed by the heading, the paragraph and the .adc-tag labels.
A single @container adc-card (min-width: 280px) rule does the job: the card switches to flex-direction: row, centred, and the picture becomes a 100 × 100 px square left of the text. Under 280 px it falls back to the stack. Because the query targets the card's own box, one card can sit as a row in a wide column while another is stacked in a sidebar, on the same page, at the same moment.
Going from one shape to the other uses an all 0.3s ease transition on the card and the picture (the picture eases to its square size). No script at all: the HTML and CSS provided are the whole thing.
<a> rather than the whole box..adc-img is a gradient div, skipped by assistive technology. If your visual carries meaning, put an <img alt="…"> inside it.prefers-reduced-motion: reduce, the card and picture transitions are switched off; the layout changes in one step.Built on container queries (container-type, @container). Measured in Chromium 151, Firefox 153 and WebKit 26.5: same switch at 280 px, no overflow at 390 px, two independent copies on one page.
An older browser ignores the @container rule: the card stays stacked, readable at any width.
Copy the two blocks (HTML and CSS) into your page. No JavaScript, no dependencies.
<div class="fx-0745-root">
<div class="adc-card">
<div class="adc-img"></div>
<div class="adc-body">
<h4>Adaptive Card</h4>
<p>Layout switches from column to row based on container width.</p>
<div class="adc-tags">
<span class="adc-tag">@container</span>
<span class="adc-tag">CSS</span>
</div>
</div>
</div>
</div>
.fx-0745-root,
.fx-0745-root *,
.fx-0745-root *::before,
.fx-0745-root *::after {
box-sizing: border-box
}
.fx-0745-root {
container: adc-card / inline-size;
display: block;
width: 100%;
background: #0a0a0f;
border-radius: 14px;
color: #fff;
font-family: sans-serif;
}
.fx-0745-root .adc-card {
display: flex;
flex-direction: column;
gap: 12px;
padding: 16px;
background: rgba(255, 255, 255, 0.04);
border-radius: 14px;
transition: all 0.3s ease;
}
.fx-0745-root .adc-img {
width: 100%;
height: 80px;
border-radius: 10px;
background: linear-gradient(135deg, #8b5cf6, #ec4899);
background-size: cover;
background-position: center;
flex-shrink: 0;
transition: all 0.3s ease;
}
.fx-0745-root .adc-body {
min-width: 0;
}
.fx-0745-root .adc-body h4 {
font-size: 0.85rem;
font-weight: 700;
color: #fff;
margin: 0 0 4px;
}
.fx-0745-root .adc-body p {
font-size: 0.72rem;
color: rgba(255, 255, 255, 0.6);
margin: 0 0 8px;
line-height: 1.5;
}
.fx-0745-root .adc-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.fx-0745-root .adc-tag {
padding: 3px 8px;
border-radius: 6px;
background: rgba(139, 92, 246, 0.15);
font-size: 0.6rem;
font-weight: 600;
color: #a78bfa;
}
@container adc-card (min-width: 280px) {
.fx-0745-root .adc-card {
flex-direction: row;
align-items: center;
}
.fx-0745-root .adc-img {
width: 100px;
height: 100px;
}
}
@media (prefers-reduced-motion: reduce) {
.fx-0745-root .adc-card,
.fx-0745-root .adc-img {
transition: none;
}
}
Pure CSS — no JavaScript needed.
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Switch point (CSS — @container adc-card (min-width: 280px)) |
280 px | Raise it to 340 px for long text, lower it to 240 px to get the row sooner. A second rule (e.g. min-width: 480px) can enlarge the picture in wide columns. |
Visual (CSS or HTML — .adc-img) |
#8b5cf6 → #ec4899 gradient |
Set your photo with style="background-image:url(…)"; background-size: cover is already there. For a meaningful picture, put an <img> inside the div. |
Picture size in the row (CSS — width/height in the @container rule) |
100 × 100 px | 120 × 120 px for a bolder thumbnail, 72 × 72 px for a dense list. |
Picture height when stacked (CSS — .adc-img { height }) |
80 px | Use 140 px for a more photographic card in narrow columns. |
Background and corners (CSS — .fx-0745-root and .adc-card) |
#0a0a0f, card rgba(255,255,255,.04), 14 px radius |
For a light theme: white root background, dark text on h4 and p. |
Labels (HTML — .adc-tag) |
2 labels | Add or remove <span class="adc-tag"> elements; the row wraps by itself. |
Transition length (CSS — transition: all 0.3s) |
0.3 s | none for an instant switch; the reduced-motion rule already does that for people who ask. |
An inline-size container does not take its width from its content. The root has width: 100%, which is enough in a block or a 1fr grid track; in a flex row, give it flex: 1 or an explicit width.
A media query looks at the window: every card would change at once. Here each card looks at the room it really has, so a sidebar card stays stacked while the one in the main content is a row.
Yes: each .fx-0745-root is its own container. In grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)), each card picks its shape from the width of its cell.