CSS display: contents: Grid Layout Without Wrappers

Grid layout without extra wrapper elements

Grid and flex layouts only apply to direct children. When markup wraps items in extra elements, the layout breaks. display: contents removes a wrapper from the layout tree so its children behave as if the wrapper was never there.

Old way Workaround
.grid   {  display: grid;  grid-template-columns: repeat(3, 1fr);  gap: 1rem;}.wrapper   {  display: grid;   grid-template-columns: subgrid;   grid-column: span 3; }/* no native way to flatten — restructure HTML or repeat grid on wrapper */
1 line
.wrapper   {  display: contents;}/* wrapper disappears from layout; children join parent grid */
Widely available Since 2020 96% global usage

This feature is well established and works across many devices and browser versions. It has been available across browsers since 2020.

Safe to use without fallbacks.

65+
37+
11.1+
79+
Wrapper with display: contents slots children into parent grid

3-column grid

Item 1
Item 2
Item 3 wrapped
Item 4 wrapped
Item 5
Item 6

Items 3 and 4 sit inside a wrapper div with display: contents. They still align to the grid.

No HTML restructuring

Keep semantic or component wrapper elements in the markup. The grid sees through them automatically.

Web components friendly

Custom elements and framework wrappers can opt into parent layouts without the host element creating a new stacking or formatting context.

Works with any layout

Transparent to grid, flex, and multi-column containers. Children participate as if the wrapper were absent.

Old Approach
Restructure HTML
Flatten wrapper elements
Modern Approach
display: contents
One declaration
Baseline
Widely available
Since 2020

How it works

Grid and flexbox layouts only apply to direct children of the container. When a wrapper element sits between the container and the actual items, it creates a new box in the layout tree and the children fall outside the grid tracks. The old fix was to flatten the HTML or avoid the wrapper entirely.

display: contents removes an element's principal box from the layout. The element still exists in the DOM and still holds its children, but it contributes no box to the visual formatting model. Its children are treated as direct children of the element's parent, so they slot into grid and flex layouts as expected.

One gotcha: display: contents strips box-model properties from the element itself. Backgrounds, borders, padding, and margins on the wrapper are ignored. Only apply it to elements you genuinely want to be invisible to layout. Also avoid applying it to interactive elements like <button> or <a> where it can strip the accessible role in some browsers.

ESC