I'm using Firefox – as yet the only browser to support the subgrid
– and actually trying to use that subgrid
feature:
const D = document,
gen = function*() {
let start = 125;
while (true) {
yield ++start;
}
},
imgNum = gen(),
create = (tag) => document.createElement(tag),
addCard = (evt) => {
let article = create('article'),
main = evt.currentTarget.closest('main'),
articleCount = main.querySelectorAll('article').length,
h2 = create('h2'),
img = create('img'),
p = create('p');
h2.textContent = `Title ${articleCount + 1}`;
img.src = `https://picsum.photos/id/${imgNum.next().value}/200/`;
p.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!";
article.append(h2, img, p);
main.querySelector('section').append(article);
}
document.querySelector('button').addEventListener('click', addCard);
*, ::before, ::after {
box-sizing: border-box;
font-family: Montserrat, Roboto, system-ui;
font-size: 16px;
font-weight: 400;
margin: 0;
padding: 0;
}
main {
display: grid;
margin-block: 1em;
margin-inline: auto;
width: clamp(20em, 70vw, 1000px);
}
section {
display: grid;
gap: 0.5em;
grid-auto-columns: 1fr;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 2em min-content fit-content;
grid-template-areas: 'header' 'image' 'description';
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: auto / span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
grid-area: header;
font-weight: 600;
text-align: center;
}
article img {
grid-area: image;
object-fit: cover;
width: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {
grid-area: description;
}
<main>
<button>Add new card</button>
<section>
<article>
<h2>Title 1</h2>
<img src="https://picsum.photos/id/123/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
<article>
<h2>Title 2</h2>
<img src="https://picsum.photos/id/124/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
<article>
<h2>Title 3</h2>
<img src="https://picsum.photos/id/125/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
</section>
</main>
With this, I click the <button>
element and a new <article>
element is created, giving the following HTML (for the first created <article>
):
<article>
<h2>Title 4</h2>
<img src="https://picsum.photos/id/125/200/">
<p>Lorem ipsum dolor sit amet <!-- removed for brevity --></p>
</article>
and that <article>
is correctly appended to the <section>
. So far, so good.
But, these articles are styled with:
article {
display: grid;
grid-template-rows: subgrid;
grid-row: auto / span 3;
}
And that use of grid-row: auto / span 3
is required to have the <article>
span the three rows required to enable the consistent element-sizing of adjacent <article>
element's descendants on the same row.
Using the <button>
to add another <article>
, however, causes some form of visual chaos, in which the <h2>
is located behind the <img>
element, and the <img>
vertically – on the page – lower down than the <p>
:
(This is accurately reproduced in the above Snippet, though obviously does require Firefox, version 71 or later.)
As for my expectations: I would like the elements placed on the implicit rows to accurately reflect the layout of the first row, with the explicit rows.
My first attempt to implement this lay in adding:
section {
/* ... */
grid-auto-rows: repeat(1, 2em min-content fit-content);
}
This, obviously, did not work.
const D = document,
gen = function*() {
let start = 125;
while (true) {
yield start++;
}
},
imgNum = gen(),
create = (tag) => document.createElement(tag),
addCard = (evt) => {
let article = create('article'),
main = evt.currentTarget.closest('main'),
articleCount = main.querySelectorAll('article').length,
h2 = create('h2'),
img = create('img'),
p = create('p');
h2.textContent = `Title ${articleCount + 1}`;
img.src = `https://picsum.photos/id/${imgNum.next().value}/200/`;
p.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!";
article.append(h2, img, p);
main.querySelector('section').append(article);
}
document.querySelector('button').addEventListener('click', addCard);
*,
::before,
::after {
box-sizing: border-box;
font-family: Montserrat, Roboto, system-ui;
font-size: 16px;
font-weight: 400;
margin: 0;
padding: 0;
}
main {
display: grid;
margin-block: 1em;
margin-inline: auto;
width: clamp(20em, 70vw, 1000px);
}
section {
display: grid;
gap: 0.5em;
grid-auto-columns: 1fr;
grid-auto-rows: repeat(1, 2em min-content fit-content);
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 2em min-content fit-content;
grid-template-areas: 'header' 'image' 'description';
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: auto / span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
grid-area: header;
font-weight: 600;
text-align: center;
}
article img {
grid-area: image;
object-fit: cover;
width: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {
grid-area: description;
}
<main>
<button>Add new card</button>
<section>
<article>
<h2>Title 1</h2>
<img src="https://picsum.photos/id/123/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
<article>
<h2>Title 2</h2>
<img src="https://picsum.photos/id/124/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
<article>
<h2>Title 3</h2>
<img src="https://picsum.photos/id/125/200/" alt="">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis maxime corporis eius qui eligendi, autem tenetur consectetur, eum officiis impedit dolorum ipsum ullam illum at alias hic facilis! Impedit, sint!</p>
</article>
</section>
</main>
I'm clearly missing something – but I trust that this use-case has been anticipated – and would very much appreciate help.