CSS网格与动态定义列表自动放置

2022-04-02 00:00:00 css css-grid

免责声明:根据spec,可以将dt + dd对包装成div,这将允许我使用floatclear、Flexbox甚至是CSS网格来简单地解决我的问题。

也有像this这样的替代方法,它将每组2个dt + dd对包装到单独的ul标记中。这也是可行的,尽管它在语义上不是100%准确。

现在我真正想做的就是使用css网格找到问题的解决方案,而不是求助于上述任何一种技术。


我的HTML中有以下结构:

dl
  dt
  dd

  dt
  dd

  dt
  dd

  dt
  dd

  ...

我想将它们分成2列2行显示,如下所示:

dt    dt
dd    dd

dt    dt
dd    dd

..    ..

我设法找到了一个解决方案,当我有4个配对并希望将它们显示在2x2网格中时:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
body {
  font-family: sans-serif;
}

dl {
  display: grid;
  grid-gap: 0 1rem;
  grid-template-columns: [col] 1fr [col] 1fr [col];
  grid-template-rows: repeat(auto-fill, 1fr);
  text-align: center;
}

dt {
  padding: 0.25rem 1rem;
  background: lightcoral;
}

dt:nth-of-type(2n + 1) {
  counter-increment: left;
  grid-column: col 1 / span 1;
}

dt:nth-of-type(2n) {
  counter-increment: right;
  grid-column: col 2 / span 1;
}


/* Comment out the following 2 selectors to see the "automatic behavior */

dt:nth-of-type(2) {
  grid-row: 1;
}

dt:nth-of-type(4) {
  grid-row: 3;
}


/* /Comment out */

dd {
  margin: 0 0 1rem;
  padding: 0.25rem 1rem;
  background: lightcyan;
}

dd:nth-last-of-type(-n + 2) {
  margin-bottom: 0;
}

dd:nth-of-type(2n + 1) {
  grid-column: col 1 / span 1;
}

dd:nth-of-type(2n) {
  grid-column: col 2 / span 1;
}
<!DOCTYPE html>
<html>

<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" type="text/css" href="src/styles.css" />
</head>

<body>
  <div id="app">
    <dl>
      <dt>Item 1</dt>
      <dd>Nunc ut quam at sem vehicula hendrerit sed vitae risus</dd>
      <dt>Item 2</dt>
      <dd>
        uisque a maximus mauris. Quisque metus quam, auctor ac porttitor.
      </dd>
      <dt>Item 3</dt>
      <dd>
        Aliquam varius est ac lectus malesuada, a sagittis arcu laoreet.
      </dd>
      <dt>Item 4</dt>
      <dd>Etiam et sapien at mi ultrices maximus vitae vel arcu.</dd>
    </dl>
  </div>
</body>

</html>

然而,这只是因为我手动定义了特定dt元素所在的行:

dt:nth-of-type(2) {
  grid-row: 1;
}

dt:nth-of-type(4) {
  grid-row: 3;
}

如果没有它,我将得到:

右侧项目的行位置偏离了%1。

有没有办法以一般方式将grid-row的值"移位"-1

我还尝试将grid-row值与counter配对,但似乎不支持这样做。


解决方案

grid-auto-flow: dense

如果指定,则自动放置算法使用"密集"打包算法,如果较小的项目较晚出现,该算法会尝试在网格中较早地填充空洞。这可能会导致项目显示为无序,因为这样做会填补较大项目留下的空白。ref

我还稍微简化了代码:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
body {
  font-family: sans-serif;
}

dl {
  display: grid;
  grid-gap: 0 1rem;
  grid-template-columns: 1fr 1fr;
  text-align: center;
  grid-auto-flow: dense;
}

dt {
  padding: 0.25rem 1rem;
  background: lightcoral;
}
dl > :nth-of-type(2n + 1) {
  grid-column: 1;
}

dl > :nth-of-type(2n) {
  grid-column: 2;
}

dd {
  margin: 0 0 1rem;
  padding: 0.25rem 1rem;
  background: lightcyan;
}

dd:nth-last-of-type(-n + 2) {
  margin-bottom: 0;
}
  <div id="app">
    <dl>
      <dt>Item 1</dt>
      <dd>Nunc ut quam at sem vehicula hendrerit sed vitae risus</dd>
      <dt>Item 2</dt>
      <dd>
        uisque a maximus mauris. Quisque metus quam, auctor ac porttitor.
      </dd>
      <dt>Item 3</dt>
      <dd>
        Aliquam varius est ac lectus malesuada, a sagittis arcu laoreet.
      </dd>
      <dt>Item 4</dt>
      <dd>Etiam et sapien at mi ultrices maximus vitae vel arcu.</dd>
    </dl>
  </div>

相关文章