使用 CSS 网格布局使网格项内的元素高度相等

2024-05-18

我在长度超过 4 的 div 中有一系列文章,没有任何舍入行标签。我需要将其表示为每行 3 篇文章(列)的表格,可能包含display: grid。每篇文章都有页眉、章节和页脚。

如何在每行文章内实现每个标题的等高、每个部分的等高以及与文章底部对齐的等高页脚?有可能吗?我应该使用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 https://codepen.io/yudnikov/pen/mBvbGW?editors=1100#0

这个解决方案 https://stackoverflow.com/q/44488357/150926:

grid-auto-rows: 1fr; 

已被提议作为副本,但事实并非如此。它只会给文章相同的高度,而例如每篇文章的标题保持不同的大小。

我最初有这个问题:

And the grid-auto-rows: 1fr解决方案结果如下:


有可能吗?

太棒了;是的。

Codepen 演示 #1 https://codepen.io/danield770/pen/Jrqbxe

Codepen 演示#2 https://codepen.io/danield770/pen/yPLQmM?editors=1100(使用SASS并且是可配置的)


The difficulty here is that each article is a grid within itself and therefore any one article has no knowledge about another. Because of this, there is no way for a component of one article like a header to adjust according to the height of a header in another article.

实际上有一种方法可以使用 css 网格来实现此目的,并且无需更改任何标记!

我们可以使用 CSS 来“扁平化”结构,这样所有文章的所有组件都只是一个 CSS 网格(文章容器)的一部分。

这是可能的,甚至不需要通过设置文章来更改当前标记display: contents

显示:内容 https://drafts.csswg.org/css-display/#valdef-display-contents (caniuse https://caniuse.com/#feat=css-display-contents)

From Caniuse https://caniuse.com/#feat=css-display-contents:

display: contents使元素的子元素看起来就像 是元素父元素的直接子元素,忽略该元素 本身。当包装元素应该被忽略时这会很有用 当使用 CSS 网格或类似的布局技术时。

所以如果我们设置文章display: contents

.container article {
  display: contents;
}

现在所有的页眉、部分和页脚都成为(直接)网格项(容器的 - 容器具有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"
}

由于每个页眉/节/页脚恰好占用一个单元格 - 这迫使它们占用相同的垂直高度。所以例如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;
}

Demo:

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 演示) https://codepen.io/danield770/pen/pWmbNL

当然,不是使用grid-template-areas + grid-area我们可以使用以下属性grid-row + grid-column属性来达到相同的结果 -Codepen 演示 https://codepen.io/danield770/pen/Jrqbxe?editors=1100#0


Note:我确实意识到上面的内容很冗长并且不完全是最佳解决方案 - 但我的观点是有可能的. Also, 我们可以使用 SASS 循环使代码更加简洁并且可配置 https://codepen.io/danield770/pen/yPLQmM?editors=1100.

如果有什么办法的话可能会很好重复一个模式 using grid-template-areas- 就像是:

伪代码(不合法):

grid-template-areas: repeat("header1 header2 header3" 
                           "section1 section2 section3"
                           "footer1 footer2 footer3")

...然后我们可以获得一个更动态的解决方案,适用于n通过使用 nth-child 设置网格区域来解决文章问题,例如:

article:nth-child(3n + 1) header {
  grid-area: header1;
} 

等等......但我认为目前这是不可能的(或者也许没有必要,因为subgrids https://drafts.csswg.org/css-grid-2/#subgrids能够做到这一点吗?)


NB:

网格布局模块 Level 2 介绍Subgrids https://drafts.csswg.org/css-grid-2/#subgrids这将使这个问题更容易解决,而无需使用display: contents


我应该使用 display: table 吗?

对于您需要的布局 -display:table没有多大帮助。首先,您必须完全重组您的标记以进行分组文章组成部分与文章相比,您必须将表格样式设置为看起来像“文章”,但即便如此 - 表格不会换行,因此您需要将每三篇文章换行到一个单独的表格中......即使有可能,它也会非常混乱且难以维护。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 CSS 网格布局使网格项内的元素高度相等 的相关文章

随机推荐

  • Node.js 升级在 Windows 中仍然显示旧版本

    我已使用 msi 安装程序下载并安装了新版本的 nodejs 4 1 2 之后我跑了node v 但它仍然显示旧版本 0 12 2 我尝试重新启动Windows 甚至卸载nodejs并重新安装它 但仍然显示相同的内容 为什么会发生这种情况
  • NVActivityIndi​​catorView 仅适用于特定视图

    我正在使用这个库https github com ninjaprox NVActivityIndi catorView https github com ninjaprox NVActivityIndicatorView用于显示加载指示器
  • 如何隐藏 phpstorm 项目中的一些文件

    In my PhpStorm project I have a few files that sit in the root folder and are not modified often 例如在这里我很少接触像这样的文件favicon
  • 当您在数组列表上调用remove(object o)时,它如何比较对象?

    当您在 java 中的数组列表上调用remove object o 时 它如何比较对象以找到要删除的正确对象 它使用指针吗 或者它使用 Comparable 接口来比较对象吗 ArrayList remove 依赖于对象的实现Equal方法
  • YOLOv8获取预测边界框

    我想将 OpenCV 与 YOLOv8 集成ultralytics 所以我想从模型预测中获取边界框坐标 我该怎么做呢 from ultralytics import YOLO import cv2 model YOLO yolov8n pt
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 将 Firebase FCM 添加到 ReactJS 应用程序

    我正在尝试向我的 ReactJS 应用程序中的用户发送推送通知 我已添加 firebase 请求用户通知权限 这正在发挥作用 但现在我想注册设备令牌 但这给了我错误 消息传递 我们无法注册默认的 Service Worker 无法注册 Se
  • 使用 NServiceBus FileShareDataBus 时清理文件

    我在 NServiceBus 3 中使用 FileShareDataBus 是否支持清理数据总线文件 如果不是 实现此目的的最佳实践是什么 例如如何确保该文件不是错误队列中消息的一部分 鉴于不可能知道消息在错误队列中停留多长时间 我通常会在
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 如何关闭 Atom 中的片段?

    我最近开始使用Atom https atom io 我遇到的一个问题是为 Ruby 定义了太多 不明确的代码片段 这使得制表符补全变得更糟 因为有时您会得到一些不相关的代码而不是您想要的名称 我想知道如何关闭 Language Ruby 包
  • 如何在 Silverlight 中使用 LINQ 创建 ObservableCollection

    在非 Silverlight 世界中 使用 LINQ 创建 ObservableCollection 很容易 这是因为 ObservableCollection 类具有接受任何 IEnumerable 或 List 的构造函数 然而Silv
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • mysql表中的数据非常大。即使 select 语句也需要很多时间

    我正在开发一个数据库 它是一个相当大的数据库 有 13 亿行和大约 35 列 这是我检查表状态后得到的结果 Name Table Name Engine InnoDB Version 10 Row format Compact Rows 1
  • 超类与类SpecificationPolicy不匹配

    我得到了一个superclass mismatch for class SpecificationPolicy尝试安装或升级某些brew 软件包时出错 例如 更新安装 supabase CLI 时 brew install supabase
  • Pandas Merge (pd.merge) 如何设置索引和连接

    我有两个 pandas 数据框 dfLeft 和 dfRight 以日期作为索引 dfLeft cusip factorL date 2012 01 03 XXXX 4 5 2012 01 03 YYYY 6 2 2012 01 04 XX
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 检索 css3 缩放元素的宽度/高度

    我正在与 offsetWidth 属性的奇怪之处 我认为 作斗争 这是场景 比方说 我有一个span标签 在我的js中 在某个时刻我执行css3转换 对于这个元素 例如 el set styles transform scale scale
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • 如何在 Windows 7 上获得 ipython 图形控制台?

    在哪里可以找到安装所需模块的分步说明ipython qtconsole在 Windows 7 64 位 中 很抱歉这个问题很简短 我要花几个小时才能写下我尝试过的所有事情 而任何人阅读它都需要花费同样的时间 我只是注意到 我发现的所有内容甚
  • 使用 CSS 网格布局使网格项内的元素高度相等

    我在长度超过 4 的 div 中有一系列文章 没有任何舍入行标签 我需要将其表示为每行 3 篇文章 列 的表格 可能包含display grid 每篇文章都有页眉 章节和页脚 如何在每行文章内实现每个标题的等高 每个部分的等高以及与文章底部