Switcher layout

스위처 레이아웃

Flips between a horizontal row and a vertical stack based purely on its own container width — no media query involved.

Also known as: Every Layout Switcher
···
html
<div class="stage" id="stage">
  <div class="switcher">
    <div class="item">One</div>
    <div class="item">Two</div>
    <div class="item">Three</div>
  </div>
</div>
css
.stage{width:20%;min-width:70px;max-width:92%;border:2px dashed var(--muted);border-radius:10px;padding:12px;
  transition:width 2.8s cubic-bezier(.4,0,.2,1)}
.stage.wide{width:92%}
.switcher{display:flex;flex-wrap:wrap;gap:8px}
.switcher .item{flex-grow:1;flex-basis:calc((220px - 100%) * 999);border-radius:8px;background:var(--accent-3);
  color:#fff;font-size:11px;font-weight:800;padding:10px;text-align:center}
js
const stage = document.getElementById('stage');
setInterval(() => stage.classList.toggle('wide'), 2400);

The core is two lines: .switcher { display: flex; flex-wrap: wrap }, and on each child, flex-grow: 1; flex-basis: calc((var(--threshold) - 100%) * 999). When the switcher's own width is wider than --threshold (say 30rem), (threshold - 100%) evaluates negative, so flex-basis comes out negative — and a negative flex-basis is treated as 0, letting items sit evenly in one row purely via flex-grow: 1.

Once the switcher's width drops below --threshold, (threshold - 100%) turns positive, and multiplying by 999 blows that value up into something enormous. With flex-basis effectively infinite, each item demands an entire row to itself, and flex-wrap: wrap drops them one by one onto the next line — a vertical stack.

The crucial difference from a media-query version is what's being measured. A media query checks the browser window's width; this calculation checks the switcher's own actual width. Put the same switcher in a wide main area and a narrow sidebar at the same time, and — at one single viewport width — one lays out horizontally while the other stacks, each responding to its own space.

When to use

Use it for reusable components with exactly two modes — row or stack — like a tab bar versus a vertical menu, or a two-column form versus one column. For more than two intermediate states, container queries express the intent more clearly.