具有 CSS 网格布局的网格项内元素的高度相等
Equal height of elements inside grid item with CSS grid layout
我在长度超过 4 的 div 中有一系列文章,没有任何舍入行标记。我需要将其表示为每行 3 篇文章(列)的 table,可能 display: grid
。每篇文章都有一个 header、一个部分和一个页脚。
如何在每行文章中为每个 header 实现等高、每个部分的等高以及与文章底部对齐的等高页脚?有可能吗?我应该使用 display: table
吗?
PS 我需要根据屏幕宽度动态更改每行的文章数。谢谢
HTML:
body {
width: 100%;
max-width: 1024px;
margin: auto;
}
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.container article {
display: grid;
}
article header {
background-color: #eeeeee;
}
article section {
background-color: #cccccc;
}
article footer {
background-color: #dddddd;
}
<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>
注意:JS 已弃用。
https://codepen.io/yudnikov/pen/mBvbGW?editors=1100#0
:
grid-auto-rows: 1fr;
已被建议为重复项,但事实并非如此。它只会给文章相等的高度,而例如每篇文章的 header 大小保持不同。
我最初有这个问题:
grid-auto-rows: 1fr
解决方案的结果是:
Is it even possible?
tldr;是的。
Codepen Demo # 2(使用 SASS 并且是可配置的)
这里的困难在于每篇文章本身就是一个网格,因此任何一篇文章都不知道另一篇文章。因此,像header这样的一篇文章的组件无法根据另一篇文章中的header的高度进行调整。
实际上有一种方法可以在不更改任何标记的情况下使用 css 网格实现这一目标!
我们可以 'flatten' 具有 CSS 的结构,这样所有文章的所有组件都只是一个 CSS 网格的一部分 - 文章容器。
通过使用 display: contents
设置文章,甚至无需更改当前标记即可实现这一点
display: contents (caniuse)
来自 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.
因此,如果我们将文章设置为 display: contents
.container article {
display: contents;
}
现在所有 header、部分和页脚都变成(直接)网格项(容器的 - 具有 display:grid
),我们可以使用 grid-template-areas
属性.
.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"
}
由于每个 header/section/footer 正好占据一个单元格 - 这迫使它们占据 相同的垂直高度 。所以例如header1、header2 和 header3 无论内容如何,都将具有相同的高度。
现在为每个单元格设置 grid-area
属性。
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;
}
最后,设置每行文章之间的垂直间距(从第二行文章开始):
article:nth-child(n + 4) header {
margin-top: 1em;
}
演示:
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>
Codepen Demo)
当然,我们可以使用 grid-row
+ grid-column
属性来代替 grid-template-areas
+ grid-area
属性来获得相同的结果 - Codepen demo
注意:我确实意识到上面的内容很冗长,并不是最佳解决方案 - 但我的意思是这是可能的.另外,we could use SASS loops to make that code much cleaner and also configurable.
如果有某种方法可以使用 grid-template-areas
来 重复一个模式 可能会更好 - 例如:
pseudo-code(不合法):
grid-template-areas: repeat("header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3")
...然后我们可以获得更动态的解决方案,该解决方案适用于 n
文章解决方案,方法是使用 nth-child 设置 grid-area,例如:
article:nth-child(3n + 1) header {
grid-area: header1;
}
等...但我认为目前这不可能(或者可能没有必要,因为 subgrids 能够做到这一点?)
注意:
Grid Layout Module Level 2 引入了 Subgrids 这将使这个问题更容易解决并且不必使用 display: contents
Should I use display: table?
对于您需要的布局 - display:table
帮不上什么忙。首先,您必须完全重组您的标记以将 文章组件 组合在一起作为文章,您必须四处寻找 table 的样式以使其看起来像 'articles' 但即便如此 - tables 也不会换行,所以你需要将每三篇文章换行到一个单独的 table 中......即使可能也会很乱并且难以维护。
我想到的最简单的想法是使用百分比。例如:
.container{
width: 30%;
height: 80%;
}
要完全控制您的布局,请检查 CSS 默认值参考:
https://www.w3schools.com/cssref/css_default_values.asp
对于不同的设备,只需使用单独的 CSS 个文件…
我在长度超过 4 的 div 中有一系列文章,没有任何舍入行标记。我需要将其表示为每行 3 篇文章(列)的 table,可能 display: grid
。每篇文章都有一个 header、一个部分和一个页脚。
如何在每行文章中为每个 header 实现等高、每个部分的等高以及与文章底部对齐的等高页脚?有可能吗?我应该使用 display: table
吗?
PS 我需要根据屏幕宽度动态更改每行的文章数。谢谢
HTML:
body {
width: 100%;
max-width: 1024px;
margin: auto;
}
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.container article {
display: grid;
}
article header {
background-color: #eeeeee;
}
article section {
background-color: #cccccc;
}
article footer {
background-color: #dddddd;
}
<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>
注意:JS 已弃用。
https://codepen.io/yudnikov/pen/mBvbGW?editors=1100#0
grid-auto-rows: 1fr;
已被建议为重复项,但事实并非如此。它只会给文章相等的高度,而例如每篇文章的 header 大小保持不同。
我最初有这个问题:
grid-auto-rows: 1fr
解决方案的结果是:
Is it even possible?
tldr;是的。
Codepen Demo # 2(使用 SASS 并且是可配置的)
这里的困难在于每篇文章本身就是一个网格,因此任何一篇文章都不知道另一篇文章。因此,像header这样的一篇文章的组件无法根据另一篇文章中的header的高度进行调整。
实际上有一种方法可以在不更改任何标记的情况下使用 css 网格实现这一目标!
我们可以 'flatten' 具有 CSS 的结构,这样所有文章的所有组件都只是一个 CSS 网格的一部分 - 文章容器。
通过使用 display: contents
display: contents (caniuse)
来自 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.
因此,如果我们将文章设置为 display: contents
.container article {
display: contents;
}
现在所有 header、部分和页脚都变成(直接)网格项(容器的 - 具有 display:grid
),我们可以使用 grid-template-areas
属性.
.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"
}
由于每个 header/section/footer 正好占据一个单元格 - 这迫使它们占据 相同的垂直高度 。所以例如header1、header2 和 header3 无论内容如何,都将具有相同的高度。
现在为每个单元格设置 grid-area
属性。
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;
}
最后,设置每行文章之间的垂直间距(从第二行文章开始):
article:nth-child(n + 4) header {
margin-top: 1em;
}
演示:
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>
Codepen Demo)
当然,我们可以使用 grid-row
+ grid-column
属性来代替 grid-template-areas
+ grid-area
属性来获得相同的结果 - Codepen demo
注意:我确实意识到上面的内容很冗长,并不是最佳解决方案 - 但我的意思是这是可能的.另外,we could use SASS loops to make that code much cleaner and also configurable.
如果有某种方法可以使用 grid-template-areas
来 重复一个模式 可能会更好 - 例如:
pseudo-code(不合法):
grid-template-areas: repeat("header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3")
...然后我们可以获得更动态的解决方案,该解决方案适用于 n
文章解决方案,方法是使用 nth-child 设置 grid-area,例如:
article:nth-child(3n + 1) header {
grid-area: header1;
}
等...但我认为目前这不可能(或者可能没有必要,因为 subgrids 能够做到这一点?)
注意:
Grid Layout Module Level 2 引入了 Subgrids 这将使这个问题更容易解决并且不必使用 display: contents
Should I use display: table?
对于您需要的布局 - display:table
帮不上什么忙。首先,您必须完全重组您的标记以将 文章组件 组合在一起作为文章,您必须四处寻找 table 的样式以使其看起来像 'articles' 但即便如此 - tables 也不会换行,所以你需要将每三篇文章换行到一个单独的 table 中......即使可能也会很乱并且难以维护。
我想到的最简单的想法是使用百分比。例如:
.container{
width: 30%;
height: 80%;
}
要完全控制您的布局,请检查 CSS 默认值参考:
https://www.w3schools.com/cssref/css_default_values.asp
对于不同的设备,只需使用单独的 CSS 个文件…