How to target a specific column or row in CSS Grid Layout?

早过忘川 提交于 2019-11-26 01:00:58

问题


Is it possible to select a specific grid column or row with CSS?

For example, say I have a 3 row by 2 column CSS Grid Layout: grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;. How would I select all elements from the 2nd column? For example: grid:nth-child(column:2) (just my idea, not valid code).

I have tried nth-child selectors on the div elements, but this does not allow me to specify row or column when the items are automatically placed by the Grid Layout engine.

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>

回答1:


Not possible with CSS.

CSS targets HTML elements, attributes and attribute values.

Grid columns and rows have none of these "hooks".

You'll have to target the grid items directly.

You wrote:

For example, say I have a 3 row by 2 column CSS Grid Layout: grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;. How would I select all elements from the 2nd column?

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>



回答2:


To style an arbitrary row, you could use a wrapper element with its display set to contents. See the code snippet below:

.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>

EDIT: As with all implementations, you should check to ensure it works in your target environment(s). You can check the compatibility table on MDN or caniuse.com for support for display: contents:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/display#Browser_compatibility
  • https://caniuse.com/#search=display%3A%20contents



回答3:


There are no column or row elements that you can target but if the grid is uniform (same number of cells in each row) you can select cells. Here are some examples.

1. Columns.

Last column in a 5-column grid:

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

Fourth (2nd last) column in a 5-column grid:

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

First (5th last) column in a 5-column grid:

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

2. Rows

First row in a 5-column grid (first five cells):

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

Second row in a 5-column grid (cells from 6 to 10):

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

Third row in a 5-column grid (cells from 11 to 15):

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

Last row in a 5-column grid with 20 cells (cells from 16 onward):

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



回答4:


If you ever want to style a row the same principal applies. Taking that example from above:

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>



回答5:


You can not. You have no such selectors.

But that is strange, because you can easily target row/colum from CSS

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

This is natural to expect something:

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

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

Do not the reasons that draft for this is not proposed yet

UPD
Seems there are for columns: https://drafts.csswg.org/selectors-4/#the-nth-col-pseudo

UPD
Issue at W3C repo




回答6:


CSS Grid excludes the concept of a row by design, so you have to add that semantic relationship to the markup explicitly.

If you are controlling the list creation, you can add a even or odd property e.g. (in JSX generator for illustration/simplicity):

for (const rowIndex in items) {
  const row = items[rowIndex]
  const parity = {[rowIndex % 2 ? 'odd' : 'even']: ''}
  for (const col in row.columns) {
     yield <div class='col' {...parity}>{col}</div>
  }
}

Which will output something like:

<div class='col' even>...</div>
<div class='col' even>...</div>
<div class='col' even>...</div>
<div class='col' odd>...</div>
<div class='col' odd>...</div>
<div class='col' odd>...</div>
<div class='col' even>...</div>
<div class='col' even>...</div>
<div class='col' even>...</div>

Then in your CSS:

.col[even] { ... }
.col[odd] { ... }


来源:https://stackoverflow.com/questions/46308048/how-to-target-a-specific-column-or-row-in-css-grid-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!