使用 CSS `grid-template-rows: subgrid` 和跨行的项目,如何获得新的 'multi-row' 行?
With CSS `grid-template-rows: subgrid`, and items spanning rows, how do I get a new 'multi-row' row?
我正在使用 Firefox——迄今为止唯一支持 subgrid
的浏览器——并且实际上正在尝试使用 subgrid
功能:
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>
有了这个,我单击 <button>
元素并创建了一个新的 <article>
元素,给出以下 HTML(对于第一个创建的 <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>
并且 <article>
已正确附加到 <section>
。到目前为止,还不错。
但是,这些文章的样式为:
article {
display: grid;
grid-template-rows: subgrid;
grid-row: auto / span 3;
}
并且需要使用 grid-row: auto / span 3
才能使 <article>
跨越所需的三行,从而使同一行上相邻 <article>
元素的后代的元素大小保持一致。
但是,使用 <button>
添加另一个 <article>
会导致某种形式的视觉混乱,其中 <h2>
位于 <img>
元素后面,并且<img>
垂直 – 在页面上 – 低于 <p>
:
(这在上面的代码段中得到了准确的复制,但显然需要 Firefox 71 或更高版本。)
至于我的期望:我希望放置在隐式行上的元素能够准确反映第一行的布局,以及显式行。
我第一次尝试实现这一点在于添加:
section {
/* ... */
grid-auto-rows: repeat(1, 2em min-content fit-content);
}
这显然行不通。
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>
我显然遗漏了一些东西 – 但我相信这个用例已经预料到了 – 非常感谢帮助。
问题是您定义了 一个 模板,这意味着只有一行将遵循该模板,而所有其他行都将有一个隐式模板。您需要的是一个重复的模板,为此您需要去掉命名区域。
基本上,您不需要做任何事情,因为浏览器会为您完成这项工作。使文章跨越 3 行就足够了。请注意,您的 grid-template-rows (2em min-content fit-content
) 无效
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-template-columns: repeat(3, 1fr);
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
height: 2em;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>
如果您需要定义行的大小,则必须使用 grid-auto-rows: 1st 2nd 3rd;
而不是 grid-template-rows: 1st 2nd 3rd;
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-template-columns: repeat(3, 1fr);
grid-auto-rows: 2em 100px auto;
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>
应该注意的是,结果在不支持 subgrid
的浏览器上看起来也不错,因为默认情况下所有元素都会正确放置在 article
中。你只会错过间隙和对齐。
空缺可以加到article
如果需要:
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-template-columns: repeat(3, 1fr);
grid-auto-rows: 2em 100px auto;
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
gap: inherit;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>
我正在使用 Firefox——迄今为止唯一支持 subgrid
的浏览器——并且实际上正在尝试使用 subgrid
功能:
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>
有了这个,我单击 <button>
元素并创建了一个新的 <article>
元素,给出以下 HTML(对于第一个创建的 <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>
并且 <article>
已正确附加到 <section>
。到目前为止,还不错。
但是,这些文章的样式为:
article {
display: grid;
grid-template-rows: subgrid;
grid-row: auto / span 3;
}
并且需要使用 grid-row: auto / span 3
才能使 <article>
跨越所需的三行,从而使同一行上相邻 <article>
元素的后代的元素大小保持一致。
但是,使用 <button>
添加另一个 <article>
会导致某种形式的视觉混乱,其中 <h2>
位于 <img>
元素后面,并且<img>
垂直 – 在页面上 – 低于 <p>
:
(这在上面的代码段中得到了准确的复制,但显然需要 Firefox 71 或更高版本。)
至于我的期望:我希望放置在隐式行上的元素能够准确反映第一行的布局,以及显式行。
我第一次尝试实现这一点在于添加:
section {
/* ... */
grid-auto-rows: repeat(1, 2em min-content fit-content);
}
这显然行不通。
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>
我显然遗漏了一些东西 – 但我相信这个用例已经预料到了 – 非常感谢帮助。
问题是您定义了 一个 模板,这意味着只有一行将遵循该模板,而所有其他行都将有一个隐式模板。您需要的是一个重复的模板,为此您需要去掉命名区域。
基本上,您不需要做任何事情,因为浏览器会为您完成这项工作。使文章跨越 3 行就足够了。请注意,您的 grid-template-rows (2em min-content fit-content
) 无效
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-template-columns: repeat(3, 1fr);
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
height: 2em;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>
如果您需要定义行的大小,则必须使用 grid-auto-rows: 1st 2nd 3rd;
而不是 grid-template-rows: 1st 2nd 3rd;
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-template-columns: repeat(3, 1fr);
grid-auto-rows: 2em 100px auto;
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>
应该注意的是,结果在不支持 subgrid
的浏览器上看起来也不错,因为默认情况下所有元素都会正确放置在 article
中。你只会错过间隙和对齐。
空缺可以加到article
如果需要:
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-template-columns: repeat(3, 1fr);
grid-auto-rows: 2em 100px auto;
padding: 0.5em;
}
article {
border: 1px solid currentColor;
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
padding: 0.5em;
gap: inherit;
}
article h2 {
background-color: rgb(210 210 210 / 0.8);
font-weight: 600;
text-align: center;
}
article img {
object-fit: cover;
width: 100%;
height: 100%;
filter: grayscale(95%);
opacity: 0.4;
transition: filter 0.4s ease-in;
}
article p {}
<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>