Let's consider example of cards with only subgrid feature.
body {
max-width: 500px;
margin: 1rem auto;
}
.container {
display: grid;
grid-template-columns: 2fr 1fr;
grid-gap: 1rem;
}
.card {
border: 1px solid #ccc;
padding: 1rem;
display: grid;
grid-gap: 1rem;
grid-row: span 3;
grid-template-rows: subgrid;
}
<div class="container">
<div class="card">
<h2>Title Similique quisquam nesciunt</h2>
<p>
Body Lorem ipsum dolor sit, amet consectetur adipisicing elit. Similique quisquam nesciunt nihil totam laborum corporis animi expedita molestias, accusantium amet libero at neque id voluptatum, numquam, natus blanditiis eos sit!
</p>
<p>Footer nesciunt nihil</p>
</div>
<div class="card">
<h2>Title accusantium amet libero at neque</h2>
<p>
Body Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quisquam minima ducimus numquam deleniti perspiciatis expedita nam commodi laboriosam illo! Blanditiis in dolorem eius. Hic assumenda architecto quidem magnam?
</p>
<p>Footer dolor sit amet consectetur adipisicing elit</p>
</div>
</div>
This generates perfectly what I want (title, body and footer are align vertically):
Codesanbox for first implementation (https://codesandbox.io/s/silent-voice-cklrms), at time of 23.07.2023 I suggest to open it in Chrome Canary or Firefox.
Problem
When I try to add to my example CSS @container query I don't know how to keep the previous functionality of subgrid.
Consider this modification to HTML, addition of .card-outer-wrapper
, reference why I had to add this wrapper:
body {
max-width: 500px;
margin: 1rem auto;
}
.container {
display: grid;
grid-template-columns: 2fr 1fr;
grid-gap: 1rem;
}
.card {
border: 1px solid #ccc;
padding: 1rem;
display: grid;
grid-gap: 1rem;
grid-row: span 3;
grid-template-rows: subgrid;
}
.card-outer-wrapper {
container-type: inline-size;
}
@container (min-width: 300px) {
.card {
background-color: aqua;
}
}
<div class="container">
<div class="card-outer-wrapper">
<div class="card">
<h2>Title Similique quisquam nesciunt</h2>
<p>
Body Lorem ipsum dolor sit, amet consectetur adipisicing elit. Similique quisquam nesciunt nihil totam laborum corporis animi expedita molestias, accusantium amet libero at neque id voluptatum, numquam, natus blanditiis eos sit!
</p>
<p>Footer nesciunt nihil</p>
</div>
</div>
<div class="card-outer-wrapper">
<div class="card">
<h2>Title accusantium amet libero at neque</h2>
<p>
Body Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quisquam minima ducimus numquam deleniti perspiciatis expedita nam commodi laboriosam illo! Blanditiis in dolorem eius. Hic assumenda architecto quidem magnam?
</p>
<p>Footer dolor sit amet consectetur adipisicing elit</p>
</div>
</div>
</div>
It properly shows background color on wider card but it lacks of subgrid functionality:
Here is code sandbox for second example: https://codesandbox.io/s/nifty-feynman-n42s5p
Question
How to modify my second example to achieve subgrid alignment and @container query together?
It is my understanding that what you are trying to do is currently not possible.
If you set the value
subgrid
ongrid-template-columns
and/orgrid-template-rows
, the nested grid uses the tracks defined for its parent instead of creating a new track listing. This allows two sibling nested grids to have the same structure.Container queries enable you to apply styles to an element based on the size of the element's container. In other words, you can apply styles to the descendent elements of the container, not the container itself.
However, when a wrapper
div
is added to be the container element for container queries, the wrapperdiv
is the child of the grid container. The two carddiv
s are no longer siblings and no longer share the same internal grid structure.Additionally, I discovered through testing that the subgrid structure is lost if
container-type
is also declared on that element. Therefore, the following idea currently does not maintain subgrid structure:I came up with a "hack" (workaround). If it's known what fraction of the grid container the column is, you can calculate how wide the grid container has to be in order for the column to be the targeted width. Therefore, you can get a result similar to the desired container query by applying the container query to the grid container and using pseudo-classes (such as
:first-child
,:nth-child()
) to target individual columns.Declare
container-type
for the grid container. Since you are usinggrid-template-columns: 2fr 1fr
, the first column's width is 2/3 of the grid container (before factoring in padding and gap, which I won't address.) Therefore, you can calculate the min-width value of the container to be 3/2 times the targeted min-width of the first column. Finally, use the:first-child
pseudo-class in the container query to target the first column.(If every column is
1fr
, then multiply the number of columns by the targeted min-width for each column and there's no need to use a pseudo-class.)