I\'m trying to build a grid that contains card-like items. The cells of each type (headline, image, text, button, ...) should have equal height in each row, determined by th
You have already a solution now, with a not ideal browser support, but anyway working, that is display: content
You need to wrap your elements in an auxiliary div, I set those to the class card. Then, make card disappear of the layour with the display : content:
.grid {
display: grid;
grid-gap: 10px;
grid-auto-columns: 1fr;
grid-auto-flow: dense;
}
.card {
display: contents;
}
.card:nth-child(odd) * {
grid-column-start: 1;
}
.card:nth-child(even) * {
grid-column-start: 2;
}
@media screen and ( min-width: 1300px) {
.card:nth-child(3n + 0) * {
grid-column-start: 3;
}
.card:nth-child(3n + 1) * {
grid-column-start: 1;
}
.card:nth-child(3n + 2) * {
grid-column-start: 2;
}
}
<div class="grid">
<div class="card">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100">
<p class="c">text
</p>
<button class="d">Button</button>
</div>
<div class="card">
<h2 class="a">Header 2 is longer and may span multiple lines</h2>
<img class="b" src="https://placekitten.com/400/100">
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est.
</p>
<button class="d">Button</button>
</div>
<div class="card">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100">
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget.
</p>
<button class="d">Button</button>
</div>
<div class="card">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100">
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget. Suspendisse pulvinar arcu massa, quis
varius velit facilisis tincidunt. Proin sed cursus orci.
</p>
<button class="d">Button</button>
</div>
<div class="card">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100">
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<button class="d">Button</button>
</div>
</div>
Since you have already a flat HTML, and are intending to use media queries, you can just use the same idea, (nth- selectors) but on the flat HTMl
.grid {
display: grid;
grid-gap: 10px;
grid-auto-flow: dense;
grid-auto-rows: 1fr;
}
.card {
display: contents;
}
h2,
img,
p,
button {
grid-column-start: 1;
}
h2:nth-of-type(even),
img:nth-of-type(even),
p:nth-of-type(even),
button:nth-of-type(even) {
grid-column-start: 2;
}
@media screen and ( min-width: 1300px) {
h2:nth-of-type(3n + 1),
img:nth-of-type(3n + 1),
p:nth-of-type(3n + 1),
button:nth-of-type(3n + 1) {
grid-column-start: 1;
}
h2:nth-of-type(3n + 2),
img:nth-of-type(3n + 2),
p:nth-of-type(3n + 2),
button:nth-of-type(3n + 2) {
grid-column-start: 2;
}
h2:nth-of-type(3n),
img:nth-of-type(3n),
p:nth-of-type(3n),
button:nth-of-type(3n) {
grid-column-start: 3;
}
}
<div class="grid">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">text
</p>
<button class="d">Button</button>
<h2 class="a">Header 2 is longer and may span multiple lines</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est.
</p>
<button class="d">Button</button>
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget.
</p>
<button class="d">Button</button>
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget. Suspendisse pulvinar arcu massa, quis
varius velit facilisis tincidunt. Proin sed cursus orci.
</p>
<button class="d">Button</button>
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<button class="d">Button</button>
</div>
This is a good example of a situation when we need sub-grids - aligning the grid cousins is essential in layouts such as in this question.
Until browsers implement the proposed Level 2 spec of Subgrids, we can only wrap each column in an element and then wrap it using an outer grid container.
The below is an excerpt from the Editor's Draft for CSS Grid Layout Module Level 2:
2. 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, 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.
A good read that discussed this problem can be found here.
Here's a mock-up using nested grid containers (sub-grids can look like this but without breaking the non-equal cousins rule) - see demo below:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
}
.grid {
display: grid;
grid-template-rows: repeat(4, 1fr);
justify-items: flex-start;
border: 1px solid #07c;
}
img {
width: 100%;
}
button {
align-self: center;
justify-self: center;
}
p {
padding: 0 10px;
}
<div class="wrapper">
<div class="grid">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">text
</p>
<button class="d">Button</button>
</div>
<div class="grid">
<h2 class="a">Header 2 is longer and may span multiple lines</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est.
</p>
<button class="d">Button</button>
</div>
<div class="grid">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget.
</p>
<button class="d">Button</button>
</div>
<div class="grid">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et cursus ligula. Maecenas non pharetra dui, eu tincidunt mi. Vivamus vitae luctus risus. Etiam vehicula sem est, non ultricies lectus placerat eget. Suspendisse pulvinar arcu massa, quis
varius velit facilisis tincidunt. Proin sed cursus orci.
</p>
<button class="d">Button</button>
</div>
<div class="grid">
<h2 class="a">Header 1</h2>
<img class="b" src="https://placekitten.com/400/100" />
<p class="c">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<button class="d">Button</button>
</div>
</div>
A possible definition could be:
.wrapper {
display: grid; /* outer grid */
/* sets a wrapping grid container with items of width around 400px */
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
}
.grid {
grid-row: span 4; /* span 4 rows */
display: grid;
/* magic is here */
grid-template-rows: subgrid; /* create a sub-grid with the 4 parent grid rows */
}