HTML Formatterhtmlformatteronline.com

Responsive grid without media queries

Four grid recipes that reflow on their own, using auto-fit, minmax and container queries.

layoutgridresponsiveauto-fitcontainer query
<section>
  <h2>1. Equal columns that wrap on their own</h2>
  <p class="note">auto-fit + minmax. Cards never go below 180px; the count adjusts.</p>
  <div class="g ram">
    <div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div>
  </div>
</section>

<section>
  <h2>2. A wide first item</h2>
  <p class="note">One rule promotes the first card to full width.</p>
  <div class="g ram feature">
    <div>Featured</div><div>2</div><div>3</div><div>4</div>
  </div>
</section>

<section>
  <h2>3. Sidebar that drops below when space runs out</h2>
  <p class="note">A flex recipe: the sidebar keeps its width until the content column hits its minimum.</p>
  <div class="sidebar">
    <div class="side">Sidebar 220px</div>
    <div class="body">Content, minimum 340px</div>
  </div>
</section>

<section>
  <h2>4. Asymmetric rows that stay aligned</h2>
  <p class="note">Named lines, so the shape is readable in the CSS.</p>
  <div class="g mosaic">
    <div class="tall">Tall</div><div>A</div><div>B</div><div class="wide">Wide</div>
  </div>
</section>

How it works

Media queries respond to the viewport. Most layout problems are actually about the space a component has, which is not the same thing — a card in a sidebar and the same card full width both need to reflow, and the viewport width tells you nothing about either.

The RAM recipe. repeat(auto-fit, minmax(180px, 1fr)) — Repeat, Auto-Fit, Minmax. It fits as many 180-pixel columns as will go, then stretches them to fill the row. Six items, four items, one item: it adapts, at every width, with no breakpoints.

auto-fit versus auto-fill. With fewer items than columns, auto-fit collapses the empty tracks and stretches what is there; auto-fill keeps the empty tracks and leaves a gap. Use auto-fit for a gallery of unknown length, auto-fill when you want items to stay a consistent size regardless of how many there are.

grid-column: 1 / -1 spans an item from the first line to the last, whatever the column count happens to be at that width. That is how you feature one card without knowing how many columns there will be.

The flex sidebar. flex: 999 1 340px on the content gives it an enormous grow factor, so it takes essentially all the spare space while the sidebar keeps its basis. When the content would drop below its 340-pixel basis, both wrap. This is Heydon Pickering's "sidebar" pattern and it is the one flexbox recipe grid genuinely cannot replicate.

span for asymmetry. grid-row: span 2 and grid-column: span 2 give you a mosaic without fixed positions, so it still reflows.

Accessibility notes

Grid and flex both reorder content visually without changing the DOM. That is powerful and it is a trap: tab order and screen reader order follow the source, so a visually reordered layout can produce a tab sequence that jumps around the page.

Keep the source order matching the logical reading order, and use grid placement for visual arrangement only. If you find yourself needing a large reorder, the fix is usually to change the markup, not to fight it with order.

Making it yours

The minmax minimum is the number to tune. Too small and you get six cramped columns on a desktop; too large and you drop to one column too early. Somewhere between 180 and 280 pixels covers most card layouts.

One caveat: with minmax(180px, 1fr), a container narrower than 180 pixels will overflow. minmax(min(180px, 100%), 1fr) fixes it, at the cost of a longer line.

Container queries take this further — @container (min-width: 400px) responds to the component's own width rather than the viewport's, which is what you actually wanted all along. Support is now good across current browsers.

Related templates

Check your version

Once you have edited this, the HTML validator will catch any tag you left unclosed, and the formatter will tidy the indentation. Both run in your browser.