Dan de diodo
¿Es posible seleccionar una columna o fila de cuadrícula específica con CSS?
Por ejemplo, supongamos que tengo un diseño de cuadrícula CSS de 3 filas por 2 columnas: grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;
. ¿Cómo seleccionaría todos los elementos de la segunda columna? Por ejemplo: grid:nth-child(column:2)
(solo mi idea, no es un código válido).
Yo he tratado nth-child
selectores en el div
elementos, pero esto no me permite especificar una fila o columna cuando el motor de diseño de cuadrícula CSS coloca automáticamente los elementos.
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>
chipit24
Para diseñar una fila arbitraria, puede usar un elemento contenedor con su display
ajustado a contents
. Vea el fragmento de código a continuación:
.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>
Al igual que con todas las implementaciones, debe verificar que funcione en los entornos de destino. Puedes consultar la tabla de compatibilidad en MDN o Puedo usar para el apoyo a display: contents
:
- mostrar (MDN)
- ¿Puedo usar display: contenidos (requiere JavaScript de caniuse.com)
-
Esta debería ser la respuesta correcta. El soporte del navegador no es perfecto, pero
display: contents;
está hecho para resolver este problema sin piratear. Es excelente para los pasos de DOM para diseñar la fila correcta, pero al mismo tiempo es invisible y se omite de la representación de la cuadrícula (no estropea nada).– Jens Tornell
10 de junio de 2019 a las 7:46
-
Muy buena solución, pero la compatibilidad con el navegador todavía es muy escasa a partir de enero de 2021
– Julián Suggate
26 de enero de 2021 a las 5:38
-
No, esta NO es una respuesta válida. Diseñar filas y columnas con una cuadrícula estática nunca es un problema, ya que siempre sabe dónde aparecerá exactamente cada elemento. La pregunta que se planteó inicialmente es cómo apuntar a elementos específicos que se colocaron en una fila/columna en particular automáticamente mediante una cuadrícula dinámica.
– Mesqalito
12 mayo 2022 a las 15:49
-
¡Sí, esta ES una respuesta válida! Puedes agregar el
grid-row-wrapper
elemento de forma dinámica.– chipit24
16 mayo 2022 a las 17:52
-
Esto no funcionaría con un diseño receptivo si cambiara la cantidad de columnas con una consulta de medios. Si, por ejemplo, pasó de 5 columnas a 3 en una pantalla más pequeña, los estilos pasarían a otra fila.
– Christian Pavilonis
9 sep 2022 a las 18:02
Mateusz
No hay elementos de columna o fila a los que pueda apuntar, pero si la cuadrícula es uniforme (la misma cantidad de celdas en cada fila), puede seleccionar celdas. Aquí hay unos ejemplos.
1. Columnas
Última columna en una cuadrícula de 5 columnas:
.item:nth-child(5n) { /* ... */ }
Cuarta (penúltima) columna en una cuadrícula de 5 columnas:
.item:nth-child(5n-1) { /* ... */ }
Primera (quinta última) columna en una cuadrícula de 5 columnas:
.item:nth-child(5n-4) { /* ... */ }
2. Filas
Primera fila en una cuadrícula de 5 columnas (primeras cinco celdas):
.item:nth-child(-n+5) { /* ... */ }
Segunda fila en una cuadrícula de 5 columnas (celdas de 6 a 10):
.item:nth-child(n+6):nth-child(-n+10) { /* ... */ }
Tercera fila en una cuadrícula de 5 columnas (celdas de 11 a 15):
.item:nth-child(n+11):nth-child(-n+15) { /* ... */ }
Última fila en una cuadrícula de 5 columnas con 20 celdas (celdas desde la 16 en adelante):
.item:nth-child(n+16) { /* ... */ }
-
funciona estáticamente pero no dinámicamente
–Royer Adames
5 de julio de 2022 a las 20:42
-
para hacerlo dinámico, puede agregar una clase cuando el grupo de elementos que desea esté recorriendo. Por ejemplo, en Angular, puede usar el bucle * ngFor par o impar para dar una clase dinámica a su fila de celdas y luego seleccionarlas y diseñarlas.
–Royer Adames
5 de julio de 2022 a las 21:29
-
No creo que esto funcione si tiene una celda o celdas que abarcan varias columnas
– Jeffrey Pia
24/10/2022 a las 15:54
miguel benjamin
No es posible con CSS.
CSS apunta a elementos HTML, atributos y valores de atributos.
Las columnas y filas de la cuadrícula no tienen ninguno de estos “ganchos”.
Tendrá que apuntar directamente a los elementos de la cuadrícula.
Tu escribiste:
Por ejemplo, supongamos que tengo un diseño de cuadrícula CSS de 3 filas por 2 columnas:
grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr;
. ¿Cómo seleccionaría todos los elementos de la segunda columna?
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>
eugenio konkov
No se puede porque no existen tales selectores.
Pero eso es extraño, porque puede apuntar fácilmente a la fila/columna desde CSS:
#item3 {
background-color: blue;
grid-row: span 2 / 7;
}
Por lo tanto, es natural esperar algo como:
div[style*="display:grid"]:grid-row(3) {
background-color: blue;
}
div[style*="display:grid"]:grid-column(3) {
background-color: green;
}
No sé las razones por las que aún no se ha propuesto un borrador para esto.
domenik reitzner
Si alguna vez desea diseñar una fila, se aplica el mismo principio. Tomando ese ejemplo de arriba:
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>
-
Esta “solución” está acoplada a la cantidad de elementos y tampoco tiene en cuenta los saltos de línea (AKA envoltura), por lo que no es tan útil.
– vsync
12 de agosto de 2018 a las 16:34
-
@vsync: esto no es flexbox, no hay ajuste/salto de línea. En la cuadrícula, tiene un diseño fijo y puede aplicar un estilo fijo a esos elementos.
– Domenik Reitzner
13 de agosto de 2018 a las 18:15
-
pero no puede, por ejemplo, diseñar una imagen de fondo que abarque una fila completa, lo que puede hacer en css display: table
– Gato James
26 de octubre de 2020 a las 9:53
Temani Afif
En un futuro próximo podremos hacerlo gracias a los selectores estructurales de rejilla
La doble asociación de una celda en una cuadrícula 2D (a su fila y columna) no se puede representar por parentesco en un lenguaje de marcado jerárquico. Solo una de esas asociaciones puede representarse jerárquicamente: la otra debe estar explícita o implícitamente definida en la semántica del lenguaje del documento. Tanto en HTML como en DocBook, dos de los lenguajes de marcado jerárquico más comunes, el marcado es primario de fila (es decir, las asociaciones de fila se representan jerárquicamente); las columnas deben estar implícitas. Para poder representar tales relaciones implícitas basadas en columnas, el combinador de columnas y el :
nth-col()
y:nth-last-col()
se definen pseudoclases. En un formato de columna principal, estas pseudoclases coinciden con las asociaciones de fila.
El que necesitas aquí es :nth-col()
que se comportan de la misma manera que :nth-child()
El
:nth-col(An+B)
La notación de pseudoclase representa un elemento de celda que pertenece a una columna que tieneAn+B-1
columnas antes árbitro
-
Esta “solución” está acoplada a la cantidad de elementos y tampoco tiene en cuenta los saltos de línea (AKA envoltura), por lo que no es tan útil.
– vsync
12 de agosto de 2018 a las 16:34
-
@vsync: esto no es flexbox, no hay ajuste/salto de línea. En la cuadrícula, tiene un diseño fijo y puede aplicar un estilo fijo a esos elementos.
– Domenik Reitzner
13 de agosto de 2018 a las 18:15
-
pero no puede, por ejemplo, diseñar una imagen de fondo que abarque una fila completa, lo que puede hacer en css display: table
– Gato James
26 de octubre de 2020 a las 9:53
Agregaré otra respuesta, se basa en actualización dinámica css rules
. Desafortunadamente, tenemos que recurrir a esto, ya que no hay forma de configurar nth-child
a través de 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>
ACTUALIZAR
Otra forma es reescribir solo los selectores en las reglas CSS existentes (sin agregarlas ni eliminarlas):
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>
usando selectores css en javascript: stackoverflow.com/q/56069793
– djvg
7 mar a las 22:00