What Is an Alternative to CSS Subgrid

Position deeply nested elements in a higher level grid container

display: subgrid

From the CSS Grid Level 2 draft spec:

2. Grid Containers

Subgrids provide the ability to pass grid parameters down through nested elements, and content-based sizing information back up to their parent grid.

If the element is a grid item (i.e. it is in-flow and its parent is a
grid container), display: subgrid makes the element a subgrid (which is a
special type of grid container box) and consequently ignores its
grid-template-* and grid-*-gap properties in favor of adopting the
parent grid tracks that it spans.

3. Subgrids

A grid item can itself be a grid container by giving it display: grid. In this case the layout of its contents will be independent of the layout of the grid it participates in.

In some cases it might be necessary for the contents of multiple grid items to align to each other. A grid container that is itself a grid item can defer the definition of its rows and columns to its parent grid container by using display: subgrid, making it a subgrid.

In this case, the grid items of the subgrid participate in sizing the grid of the parent grid container, allowing the contents of both grids to align. Read more.

This feature has not yet been implemented in major browsers. Who knows when it will be.

In Grid, only the in-flow children of the container become grid items and can accept grid properties.

With display: subgrid on a grid item, the children of the item respect the lines of the container.

According to the Grid Level 1 spec, display: subgrid has been deferred to Level 2.

For now, display: grid on grid items (i.e., nested grid containers) may be useful in some cases.

Another possible workaround is display: contents. The method is explained here:

  • What is an alternative to css subgrid?

More information:

  • https://blogs.igalia.com/mrego/2016/02/12/subgrids-thinking-out-loud/
  • https://bugzilla.mozilla.org/show_bug.cgi?id=1240834

Equal height children of grid items

Unless you can use display: subgrid or display: contents (more info below), the only way to achieve this behavior with CSS alone would be to put all children of the various grid items in a single grid container. In other words, make them all siblings.

The problem is that an element in one container has no idea what its cousin in another container is doing. They have no direct connection, which prevents them from working together. Siblings, on the other hand, have no problem working together.

Note that "flattening" HTML documents for the purposes of CSS is not recommended as it damages semantics and accessibility.

More information:

  • Positioning content of grid items in primary container (subgrid feature)
  • What is an alternative to css subgrid?

css grid with nested div structure

Nested grids are possible, but make sure that the parent of the innermost divs does itself have display:grid. If you don't,

As these items are not direct children of the grid they do not participate in grid layout and so display in a normal document flow.

(from MDN: Basic concepts of grid layout.)

So all you need to do is assign those styles to the parent of the left and right divs.

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-gap: 10px;

grid-template-rows: 1;

}

.cent {

grid-column: 2;

grid-row: 1;

}

.cent + div { /* this works for now, but you should choose a better selector for this one */

display: grid;

grid-column: 1 / 4;

grid-row: 1;

}

.left {

grid-column: 1;

grid-row: 1;

}

.right {

grid-column: 3;

grid-row: 1;

}
<div class="wrapper">

<div class="cent">center</div>

<div>

<!-- in reality there would be more divs and rows, I already have problems with one -->

<div class="left">left</div>

<div class="right">right</div>

</div>

</div>

Equal height of elements inside grid item with CSS grid layout

Is it even possible?

tldr; Yes.

Codepen Demo #1

Codepen Demo # 2 (Uses SASS and is configurable)


The difficulty here is that each article is a grid within itself and therefore any one article has no knowledge about another. Because of this, there is no way for a component of one article like a header to adjust according to the height of a header in another article.

There is actually a way to pull this off with css grids & without changing any markup!

We could 'flatten' the structure with CSS such that all the components of all the articles are part of just one CSS grid - the article container.

This is possible without even changing the current markup by setting the articles with display: contents

display: contents (caniuse)

From Caniuse:

display: contents causes an element's children to appear as if they
were direct children of the element's parent, ignoring the element
itself. This can be useful when a wrapper element should be ignored
when using CSS grid or similar layout techniques.

So if we set the articles with display: contents

.container article {
display: contents;
}

Now all of the headers, sections and footer become (direct) grid items (of the container - which has display:grid) which we can arrange using the grid-template-areas property.

.container {
display: grid;
grid-column-gap: 1em; /* horizontal gap between articles */
grid-template-columns: repeat(3, 1fr);

grid-template-areas: "header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3"
"header4 header5 header6"
"section4 section5 section6"
"footer4 footer5 footer6"
}

Since each header/section/footer take up exactly one cell - this forces them to take up the same vertical height. So e.g. header1,header2 and header3 will all have the same height regardless of their content.

Now set the grid-area properties on each of the cells.

article:nth-child(1) header {
grid-area: header1;
}
article:nth-child(2) header {
grid-area: header2;
}
article:nth-child(3) header {
grid-area: header3;
}
article:nth-child(4) header {
grid-area: header4;
}
article:nth-child(1) section {
grid-area: section1;
}
...
article:nth-child(4) section {
grid-area: section4;
}
article:nth-child(1) footer {
grid-area: footer1;
}
...
article:nth-child(4) footer {
grid-area: footer4;
}

Finally, set a vertical gap between each row of articles (starting from the second row of articles):

article:nth-child(n + 4) header {
margin-top: 1em;
}

Demo:

body {

width: 100%;

max-width: 1024px;

margin: auto;

}

.container {

display: grid;

grid-column-gap: 1em;

grid-template-columns: repeat(3, 1fr);

grid-template-areas: "header1 header2 header3"

"section1 section2 section3"

"footer1 footer2 footer3"

"header4 header5 header6"

"section4 section5 section6"

"footer4 footer5 footer6"

}

.container article {

display: contents;

}

article header {

background-color: #eeeeee;

}

article section {

background-color: #cccccc;

}

article footer {

background-color: #dddddd;

}

article:nth-child(n + 4) header {

margin-top: 1em;

}

article:nth-child(1) header {

grid-area: header1;

}

article:nth-child(2) header {

grid-area: header2;

}

article:nth-child(3) header {

grid-area: header3;

}

article:nth-child(4) header {

grid-area: header4;

}

article:nth-child(1) section {

grid-area: section1;

}

article:nth-child(2) section {

grid-area: section2;

}

article:nth-child(3) section {

grid-area: section3;

}

article:nth-child(4) section {

grid-area: section4;

}

article:nth-child(1) footer {

grid-area: footer1;

}

article:nth-child(2) footer {

grid-area: footer2;

}

article:nth-child(3) footer {

grid-area: footer3;

}

article:nth-child(4) footer {

grid-area: footer4;

}
<div class="container">

<article>

<header>

<h2>Header</h2>

<h2>Header</h2>

</header>

<section>

<p>Content</p>

</section>

<footer>

<p>Footer</p>

</footer>

</article>

<article>

<header>

<h2>Header</h2>

</header>

<section>

<p>Content</p>

<p>Content</p>

<p>Content</p>

<p>Content</p>

<p>Content</p>

</section>

<footer>

<p>Footer</p>

<p>Footer</p>

</footer>

</article>

<article>

<header>

<h2>Header</h2>

</header>

<section>

<p>Content</p>

<p>Content</p>

<p>Content</p>

</section>

<footer>

<p>Footer</p>

</footer>

</article>

<article>

<header>

<h2>Header</h2>

</header>

<section>

<p>Content</p>

<p>Content</p>

<p>Content</p>

<p>Content</p>

</section>

<footer>

<p>Footer</p>

<p>Footer</p>

</footer>

</article>

</div>

Can't solve grid problems

I changed percentages a bit. I am not sure if there is better way of sorting those grids but I managed to find percentages for some of them, you could use this and finish all 12.

preview - updated



Related Topics



Leave a reply



Submit