Wie kann ich auf eine bestimmte Spalte oder Zeile in einem CSS-Rasterlayout abzielen?

Lesezeit: 12 Minuten

Benutzeravatar von Diode Dan
Diode Dan

Ist es möglich, eine bestimmte Rasterspalte oder -zeile mit CSS auszuwählen?

Angenommen, ich habe ein CSS-Rasterlayout mit 3 Zeilen und 2 Spalten: grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;. Wie würde ich alle Elemente aus der 2. Spalte auswählen? Zum Beispiel: grid:nth-child(column:2) (nur meine Idee, kein gültiger Code).

Ich habe versucht nth-child Selektoren auf der div Elemente, aber dies erlaubt mir nicht, Zeile oder Spalte anzugeben, wenn die Elemente automatisch von der CSS-Grid-Layout-Engine platziert werden.

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>

  • Verwendung von CSS-Selektoren in Javascript: stackoverflow.com/q/56069793

    – djvg

    7. März um 22:00 Uhr

Benutzeravatar von chipit24
chipit24

Um eine beliebige Zeile zu formatieren, könnten Sie ein Wrapper-Element mit seinem verwenden display einstellen contents. Siehe das Code-Snippet unten:

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

Wie bei allen Implementierungen sollten Sie überprüfen, ob es in Ihrer/Ihren Zielumgebung(en) funktioniert. Sie können die Kompatibilitätstabelle auf überprüfen MDN oder Kann ich benutzen zur Unterstützung für display: contents:

  • Dies sollte die richtige Antwort sein. Die Browserunterstützung ist aber nicht perfekt display: contents; wurde entwickelt, um dieses Problem ohne Hack zu lösen. Es ist großartig für DOM-Stepping, um die richtige Zeile zu stylen, aber gleichzeitig unsichtbar zu sein und vom Grid-Rendering übersprungen zu werden (es bringt nichts durcheinander).

    – Jens Törnell

    10. Juni 2019 um 7:46 Uhr

  • Sehr schöne Lösung, aber die Browserunterstützung fehlt ab Januar 2021 immer noch schmerzlich

    – Julian Suggate

    26. Januar 2021 um 5:38 Uhr

  • Nein, das ist KEINE gültige Antwort. Das Gestalten von Zeilen und Spalten mit statischem Raster ist nie ein Problem, da Sie immer wissen, wo genau jedes Element vorkommen wird. Die anfänglich gestellte Frage war, wie bestimmte Elemente, die automatisch in einer bestimmten Zeile/Spalte platziert wurden, durch ein dynamisches Raster gezielt anvisiert werden können.

    – Mesqalito

    12. Mai 2022 um 15:49 Uhr

  • Ja, das ist eine gültige Antwort! Sie können die hinzufügen grid-row-wrapper Element dynamisch.

    – chipit24

    16. Mai 2022 um 17:52 Uhr

  • Dies würde mit einem responsiven Design nicht funktionieren, wenn Sie die Anzahl der Spalten mit einer Medienabfrage ändern würden. Wenn Sie beispielsweise auf einem kleineren Bildschirm von 5 Spalten auf 3 Spalten wechseln, würden die Stile in eine andere Zeile überlaufen.

    – Christian Pavilonis

    9. September 2022 um 18:02 Uhr

Benutzeravatar von Mateusz
Mateusz

Es gibt keine Spalten- oder Zeilenelemente, auf die Sie abzielen können, aber wenn das Raster einheitlich ist (gleiche Anzahl von Zellen in jeder Zeile), können Sie Zellen auswählen. Hier sind einige Beispiele.

1. Spalten

Letzte Spalte in einem 5-Spalten-Raster:

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

Vierte (vorletzte) Spalte in einem 5-Spalten-Raster:

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

Erste (fünftletzte) Spalte in einem 5-Spalten-Raster:

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

2. Reihen

Erste Zeile in einem 5-Spalten-Raster (erste fünf Zellen):

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

Zweite Zeile in einem 5-Spalten-Raster (Zellen von 6 bis 10):

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

Dritte Zeile in einem 5-Spalten-Raster (Zellen von 11 bis 15):

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

Letzte Zeile in einem 5-Spalten-Raster mit 20 Zellen (Zellen ab 16):

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

  • funktioniert statisch, aber nicht dynamisch

    – Royer Adames

    5. Juli 2022 um 20:42 Uhr

  • Um es dynamisch zu machen, können Sie eine Klasse hinzufügen, wenn die gewünschte Gruppe von Elementen durchlaufen wird. Beispielsweise können Sie in Angular die *ngFor-Schleife ungerade oder gerade verwenden, um Ihrer Zellenreihe eine dynamische Klasse zuzuweisen und sie dann auszuwählen und zu formatieren

    – Royer Adames

    5. Juli 2022 um 21:29 Uhr

  • Ich glaube nicht, dass dies funktioniert, wenn Sie eine Zelle oder Zellen haben, die sich über mehrere Spalten erstrecken

    – JeffreyPia

    24. Oktober 2022 um 15:54 Uhr

Benutzeravatar von Michael Benjamin
Michael Benjamin

Mit CSS ist das nicht möglich.

CSS zielt auf HTML-Elemente, Attribute und Attributwerte ab.

Gitterspalten und -zeilen haben keinen dieser “Haken”.

Sie müssen die Rasterelemente direkt anvisieren.

Sie schrieben:

Angenommen, ich habe ein CSS-Grid-Layout mit 3 Zeilen und 2 Spalten: grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;. Wie würde ich alle Elemente aus der 2. Spalte auswählen?

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>

Benutzeravatar von Eugen Konkov
Eugen Konkow

Sie können nicht, weil es keine solchen Selektoren gibt.

Aber das ist seltsam, weil man die Zeile/Spalte einfach aus zielen kann CSS:

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

Daher ist es natürlich, etwas zu erwarten wie:

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

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

Ich kenne die Gründe nicht, warum noch kein Entwurf dafür vorgelegt wurde.

Es gibt einen CSSWG-Entwurf für die Spaltenauswahl

Es gibt auch eine Issue-Anfrage im W3C-Repository

Benutzeravatar von Domenik Reitzner
Dominik Reitzner

Wenn Sie jemals eine Reihe stylen möchten, gilt das gleiche Prinzip. Nehmen wir das Beispiel von oben:

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>

  • Diese “Lösung” ist an die Anzahl der Artikel gekoppelt und berücksichtigt auch keine Zeilenumbrüche (AKA wickeln), daher ist es nicht so nützlich.

    – vsync

    12. August 2018 um 16:34 Uhr

  • @vsync: Dies ist keine Flexbox, es gibt keinen Umbruch/Zeilenumbruch. Im Raster haben Sie ein festes Layout und können diesen Elementen ein festes Styling zuweisen.

    – Domenik Reitzner

    13. August 2018 um 18:15 Uhr

  • aber Sie können beispielsweise kein Hintergrundbild formatieren, das sich über eine ganze Zeile erstreckt, was Sie in css display: table können

    – James Katze

    26. Oktober 2020 um 9:53 Uhr

Benutzeravatar von Temani Afif
Temani Afif

In naher Zukunft werden wir es dank tun können die gitterstrukturellen Selektoren

Die doppelte Zuordnung einer Zelle in einem 2D-Gitter (zu ihrer Zeile und Spalte) kann nicht durch Abstammung in einer hierarchischen Auszeichnungssprache dargestellt werden. Nur eine dieser Assoziationen kann hierarchisch dargestellt werden: die andere muss explizit oder implizit in der Dokumentsprachensemantik definiert werden. Sowohl in HTML als auch in DocBook, zwei der gebräuchlichsten hierarchischen Auszeichnungssprachen, ist das Markup zeilenprimär (das heißt, die Zeilenzuordnungen werden hierarchisch dargestellt); die Spalten müssen impliziert werden. Um solche impliziten spaltenbasierten Beziehungen darstellen zu können, müssen die Spaltenkombinator und das :nth-col() Und :nth-last-col() Pseudoklassen sind definiert. In einem primären Spaltenformat stimmen diese Pseudoklassen stattdessen mit Zeilenzuordnungen überein.

Das, was Sie hier brauchen, ist :nth-col() die sich genauso verhalten wie :nth-child()

Der :nth-col(An+B) Die Pseudoklassen-Notation stellt ein Zellenelement dar, das zu einer Spalte gehört, die hat An+B-1 Spalten davor Ref

  • Diese “Lösung” ist an die Anzahl der Artikel gekoppelt und berücksichtigt auch keine Zeilenumbrüche (AKA wickeln), daher ist es nicht so nützlich.

    – vsync

    12. August 2018 um 16:34 Uhr

  • @vsync: Dies ist keine Flexbox, es gibt keinen Umbruch/Zeilenumbruch. Im Raster haben Sie ein festes Layout und können diesen Elementen ein festes Styling zuweisen.

    – Domenik Reitzner

    13. August 2018 um 18:15 Uhr

  • aber Sie können beispielsweise kein Hintergrundbild formatieren, das sich über eine ganze Zeile erstreckt, was Sie in css display: table können

    – James Katze

    26. Oktober 2020 um 9:53 Uhr

Ich werde eine weitere Antwort hinzufügen, sie basiert auf dynamisch aktualisiert css rules. Hierauf müssen wir leider zurückgreifen, da es keine Einstellmöglichkeit gibt nth-child über css variables.

const data =[{"Name":"John","Age":25,"Gender":"Male"},{"Name":"Emily","Age":33,"Gender":"Female"},{"Name":"Michael","Age":42,"Gender":"Male"},{"Name":"Sarah","Age":29,"Gender":"Female"},{"Name":"William","Age":37,"Gender":"Male"},{"Name":"Samantha","Age":26,"Gender":"Female"},{"Name":"Benjamin","Age":48,"Gender":"Male"},{"Name":"Elizabeth","Age":31,"Gender":"Female"},{"Name":"David","Age":45,"Gender":"Male"},{"Name":"Olivia","Age":28,"Gender":"Female"}]


const colors = ['255,0,0', '0,255,0', '0,0,255']
const COLUMNS = 3
let rows = 2
const wp = document.querySelector('.wrapper')
let lastSelectedColumn = null

document.querySelector('button').onclick = function(){
  if (rows > data.length -1) return
  Object.values(data[rows++])
    .map(e => Object.assign(document.createElement('div'),{textContent: e}))
    .forEach(e => wp.appendChild(e)) 
  selectColumn(lastSelectedColumn)
}

wp.onclick = function({target}){
  if (target.className !== "") return
  const index = Array.from(wp.children).indexOf(target)
  selectColumn(lastSelectedColumn = index % COLUMNS)// console.log(lastSelectedColumn)
}

function getRules(column, columns, rows, color){
  const index = (column + 1) % columns 
  const i = index  ? `+ ${index}` : ''
  return [
    `.wrapper div:nth-child(${columns}n${i}){
      border-width: 0px 3px 0 3px; 
      border-color: rgb(${color}); 
      border-style: solid;
      background: rgba(${color},.1);
    }`, /* top cell */
    `.wrapper div:nth-child(${column + 1}) {
      border-width: 3px 3px 0 3px; 
      /* font-weight: bold; */
    }`, /* bottom cell */
    `.wrapper div:nth-child(${(rows-1) * columns  + column + 1}) {
      border-width: 0 3px 3px 3px; 
    }`
  ]
}

function cleanupRules(stylesheet){
  let newRuleIndex = stylesheet.sheet.cssRules.length
  for (; newRuleIndex > 2; newRuleIndex--)
     stylesheet.sheet.deleteRule(newRuleIndex - 1)
  return newRuleIndex 
}

function selectColumn(column){
  const stylesheet = document
    .querySelector('style[title="grid-wrapper"]')
  if (!stylesheet || column === null) return
  const rules = getRules(column, COLUMNS,
    wp.children.length / COLUMNS, colors[column])
  let newRuleIndex = cleanupRules(stylesheet)
  for (const rule of rules){
    stylesheet.sheet.insertRule(rule, newRuleIndex++)
  } // console.log(stylesheet.sheet.cssRules)
}
<style title="grid-wrapper">
  .wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: fit-content;
    background: #e5e5e5;
    color: black;
    margin: 10px;
  }
  .wrapper div {
    padding: 5px;
    box-sizing:content-box;
    box-shadow: 1px 1px 1px  black;
  }
</style>  
<p>Please, select a column, and click on `Add`</p>
<div class="wrapper">
  <div>Name</div>
  <div>Age</div>
  <div>Gender</div>
  <div>John</div>
  <div>25</div>
  <div>Male</div>
  <div>Emily</div>
  <div>33</div>
  <div>Female</div>
</div>
<button>Add</button>

AKTUALISIEREN

Eine andere Möglichkeit besteht darin, nur Selektoren in vorhandenen CSS-Regeln neu zu schreiben (ohne sie hinzuzufügen oder zu entfernen):

const wp = document.querySelector('.wrapper')
const config = {
  data :[{"Name":"John","Age":25,"Gender":"Male"},{"Name":"Emily","Age":33,"Gender":"Female"},{"Name":"Michael","Age":42,"Gender":"Male"},{"Name":"Sarah","Age":29,"Gender":"Female"},{"Name":"William","Age":37,"Gender":"Male"},{"Name":"Samantha","Age":26,"Gender":"Female"},{"Name":"Benjamin","Age":48,"Gender":"Male"},{"Name":"Elizabeth","Age":31,"Gender":"Female"},{"Name":"David","Age":45,"Gender":"Male"},{"Name":"Olivia","Age":28,"Gender":"Female"}],
  colors : ['255,0,0', '0,255,0', '0,0,255'],
  cols : 3,
  rows : 3,
  lastSelectedColumn: null
}

function getSelectorTexts(column, columns, rows, color){
  const index = (column + 1) % columns 
  const i = index  ? `+ ${index}` : ''
  return [
    `.wrapper div:nth-child(${columns}n${i})`, 
    `.wrapper div:nth-child(${column + 1})`, 
    `.wrapper div:nth-child(${(rows-1) * columns  + column + 1})`
  ]
}

function selectColumn(column){
  const stylesheet = document
    .querySelector('style[title="grid-wrapper"]')
  if (!stylesheet || column === null) return
  const rules = getSelectorTexts(column, config.cols,
     wp.children.length / config.cols, config.colors[column])
  let i = 2  
  for (const rule of rules){
    stylesheet.sheet.rules[i++].selectorText = rule
  }
}

document.querySelector('button').onclick = function(){
  if (config.rows > config.data.length -1) return
  Object.values(config.data[config.rows++])
    .map(e => Object.assign(document.createElement('div'),{textContent: e}))
    .forEach(e => wp.appendChild(e)) 
  selectColumn(config.lastSelectedColumn)
}

wp.onclick = function({target}){
  if (target.className !== "") return
  const index = Array.from(wp.children).indexOf(target)
  selectColumn(config.lastSelectedColumn = index % config.cols)
}
<style title="grid-wrapper">
  .wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: fit-content;
    background: #e5e5e5;
    color: black;
    margin: 10px;
  }
  .wrapper div {
    padding: 5px;
    border-width: 3px;
    border-color: transparent; 
    box-shadow: 1px 1px 1px  black;
  }

  .rule1 {
    border-width: 0px 3px 0 3px; 
    border-color: rgb(0, 0, 255);
    border-style: solid;
    background: rgba(0, 0, 255, .1);
  }

  .rule2 {
    border-width: 3px 3px 0 3px;
    border-color: rgb(0, 0, 255);
  }

  .rule2 {
    border-width: 0 3px 3px 3px; 
    border-color: rgb(0, 0, 255);
  }
</style>   
<p>Please, select a column, and click on `Add`</p>
<div class="wrapper">
  <div>Name</div>
  <div>Age</div>
  <div>Gender</div>
  <div>John</div>
  <div>25</div>
  <div>Male</div>
  <div>Emily</div>
  <div>33</div>
  <div>Female</div>
  <div>Michael</div>
  <div>42</div>
  <div>Male</div>
</div>
<button>Add</button>

1449360cookie-checkWie kann ich auf eine bestimmte Spalte oder Zeile in einem CSS-Rasterlayout abzielen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy