【问题标题】:How to target a specific column or row in CSS Grid Layout?如何定位 CSS 网格布局中的特定列或行?
【发布时间】:2018-02-28 16:30:53
【问题描述】:

是否可以使用 CSS 选择特定的网格列或行?

例如,假设我有一个 3 行 x 2 列的 CSS 网格布局:grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;。如何从第二列中选择所有元素?例如:grid:nth-child(column:2)(只是我的想法,无效代码)。

我在div 元素上尝试了nth-child 选择器,但是当网格布局引擎自动放置项目时,这不允许我指定行或列。

body {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr;
  grid-gap: 10px;
}

.item {
  background: #999;
}
<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>

<div class="item">
  <p>Right Justify</p>
  <p>Element 1 | Element 2</p>
</div>

<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>

<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>
<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>
<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>
<div class="item">
  <p>Customer Name</p>
  <p>Element 1 | Element 2</p>
</div>

【问题讨论】:

    标签: html css css-selectors css-grid


    【解决方案1】:

    要设置任意行的样式,您可以使用包装器元素,并将其display 设置为contents。见下面的代码sn-p:

    .grid-container {
      display: grid;
      grid-template-columns: repeat(5, 1fr);
      grid-gap: 2px;
    }
    
    .grid-item {
      border: 1px solid black;
      padding: 5px;
    }
    
    .grid-row-wrapper {
      display: contents;
    }
    
    .grid-row-wrapper > .grid-item {
      background: skyblue;
    }
    <div class="grid-container">
      <div class="grid-item">1</div>
      <div class="grid-item">2</div>
      <div class="grid-item">3</div>
      <div class="grid-item">4</div>
      <div class="grid-item">5</div>
      <div class="grid-row-wrapper">
        <div class="grid-item">6</div>
        <div class="grid-item">7</div>
        <div class="grid-item">8</div>
        <div class="grid-item">9</div>
        <div class="grid-item">10</div>
      </div>
      <div class="grid-item">11</div>
      <div class="grid-item">12</div>
      <div class="grid-item">13</div>
      <div class="grid-item">14</div>
      <div class="grid-item">15</div>
      <div class="grid-item">16</div>
      <div class="grid-item">17</div>
      <div class="grid-item">18</div>
      <div class="grid-item">19</div>
      <div class="grid-item">20</div>
    </div>

    编辑:与所有实现一样,您应该检查以确保它在您的目标环境中工作。您可以查看 MDN 或 caniuse.com 上的兼容性表以获取对 display: contents 的支持:

    【讨论】:

    • 这应该是正确的答案。浏览器支持并不完美,但display: contents; 是为了解决这个问题而无需破解。它非常适合 DOM 步进以设置正确行的样式,但同时不可见并从网格渲染中跳过(它不会弄乱任何东西)。
    • 非常好的解决方案,但截至 2021 年 1 月仍然严重缺乏浏览器支持
    【解决方案2】:

    CSS 不可能。

    CSS 以 HTML 元素、属性和属性值为目标。

    网格列和行没有这些“钩子”。

    您必须直接定位网格项目。

    你写的:

    例如,假设我有一个 3 行乘 2 列的 CSS 网格布局:grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;。如何从第二列中选择所有元素?

    grid-container {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr;
      grid-gap: 10px;
      padding: 10px;
      height: 50vh;
      background-color: gray;
    }
    
    grid-item {
      background-color: lightgreen;
    }
    
    grid-item:nth-child(2n) {
      border: 2px dashed red;
    }
    <grid-container>
      <grid-item></grid-item>
      <grid-item></grid-item>
      <grid-item></grid-item>
      <grid-item></grid-item>
      <grid-item></grid-item>
      <grid-item></grid-item>
    </grid-container>

    【讨论】:

      【解决方案3】:

      没有可以定位的列或行元素,但如果网格是统一的(每行中的单元格数量相同),您可以选择单元格。以下是一些示例。

      1。列。

      5 列网格中的最后一列:

          .item:nth-child(5n) { /* ... */ }
      

      5 列网格中的第四列(倒数第二):

          .item:nth-child(5n-1) { /* ... */ }
      

      5 列网格中的第一列(倒数第五):

          .item:nth-child(5n-4) { /* ... */ }
      

      2。行

      5 列网格中的第一行(前五个单元格):

          .item:nth-child(-n+5) { /* ... */ }
      

      5 列网格中的第二行(单元格从 6 到 10):

          .item:nth-child(n+6):nth-child(-n+10) { /* ... */ }
      

      5 列网格中的第三行(单元格从 11 到 15):

          .item:nth-child(n+11):nth-child(-n+15) { /* ... */ }
      

      5 列网格中的最后一行,包含 20 个单元格(从 16 个单元格开始):

          .item:nth-child(n+16) { /* ... */ }
      

      【讨论】:

        【解决方案4】:

        如果您想为一行设置样式,同样的原则也适用。 以上面的例子为例:

        grid-container {
          display: grid;
          grid-template-columns: 1fr 1fr;
          grid-template-rows: 1fr 1fr 1fr 1fr;
          grid-gap: 10px;
          padding: 10px;
          height: 50vh;
          background-color: gray;
        }
        
        grid-item {
          background-color: lightgreen;
        }
        
        grid-item:nth-child(4n+3),grid-item:nth-child(4n) {
          border: 2px dashed red;
        }
        <grid-container>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
          <grid-item></grid-item>
        </grid-container>

        【讨论】:

        • 这个“解决方案”与项目的数量相关,并且没有考虑任何换行符(AKA wrap),因此它不是那么有用。
        • @vsync:这不是 flexbox,没有换行/换行。在网格中,您有一个固定的布局,并且可以对这些项目应用固定的样式。
        • 但是你不能例如设置一个跨越整行的背景图像,你可以在 css 中显示:table
        【解决方案5】:

        你不能。你没有这样的选择器。

        但这很奇怪,因为您可以轻松地从 CSS 定位行/列

        #item3 {
          background-color: blue;
          grid-row: span 2 / 7;
        }
        

        这是很自然的期待:

        div[style*="display:grid"]:grid-row(3) {
            background-color: blue;
        }
        
        div[style*="display:grid"]:grid-column(3) {
            background-color: green;
        }
        

        不要因为这个草案尚未提出的原因

        UPD
        似乎有列:https://drafts.csswg.org/selectors-4/#the-nth-col-pseudo

        UPD
        Issue 在 W3C 存储库

        【讨论】:

          【解决方案6】:

          在不久的将来,感谢the Grid-Structural Selectors,我们将能够做到这一点

          二维网格中单元格的双重关联(与其行和列)不能用分层标记语言中的父级来表示。这些关联中只有一个可以分层表示:另一个必须在文档语言语义中显式或隐式定义。在 HTML 和 DocBook 这两种最常见的分层标记语言中,标记是行为主的(即,行关联是分层表示的);列必须是隐含的。为了能够表示这种隐含的基于列的关系,定义了 列组合器 和 :nth-col():nth-last-col() 伪类。在列主格式中,这些伪类改为与行关联匹配。

          这里需要的是:nth-col(),其行为方式与:nth-child()相同

          :nth-col(An+B) 伪类表示法表示一个单元格元素,它属于前面有 An+B-1 列的列ref

          【讨论】:

          • 这个很有意思,有没有实现demo可以指出来?
          • @DiodeDan 还没有,我们离任何实现还很远,因为目前没有浏览器支持这个,但很快我们将在一些浏览器中拥有这样的功能,我们可以测试它
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多