Volver a las notas

CSS gap decorations: líneas entre celdas sin trucos

31 de octubre de 2026·
cssgriduxlayout
Demo en vivoAbrir a pantalla completa

Dibujar una línea entre las celdas de un grid siempre ha sido un apaño: bordes en la mitad de los elementos, reglas con :nth-child() para quitar los que sobran o un fondo de color asomando por los huecos. Desde Chrome y Edge 149 hay una propiedad de verdad para eso: row-rule y column-rule ya funcionan en contenedores grid y flex, no solo en texto a varias columnas.

Me gusta porque resuelve un problema muy de diario. Bentos, dashboards, tablas de precios, footers con columnas: todos quieren separadores, y los separadores son cosa del hueco, no de los elementos.

Qué son las gap decorations

column-rule no es nuevo. Lleva años pintando la línea entre columnas de un texto multicolumna. El módulo CSS Gaps coge esa idea y la extiende a grid y flexbox, añade la dirección de las filas con row-rule y te deja controlar dónde se cortan las líneas, en qué huecos se pintan y cuánto se recogen sus extremos.

Hay dos reglas de la especificación que conviene saber antes de empezar:

  • No ocupan espacio. Una decoración nunca mueve nada. Si es más ancha que el hueco, los elementos de al lado simplemente la tapan.
  • Se pintan justo encima del borde del contenedor, y en un contenedor con scroll se desplazan con los elementos.

El código que usa la demo

La demo de arriba es un grid de cuatro columnas y cuatro filas con nueve tarjetas. El núcleo son tres declaraciones:

.bento {
  display: grid;
  gap: 18px;
  row-rule: 2px solid #FF5200;
  column-rule: 2px solid #00D4AA;
}

row-rule y column-rule son atajos de -width, -style y -color, igual que border. Los valores por defecto también son los de un borde: medium, none y currentcolor. Así que si te olvidas del estilo, no se pinta nada. Si quieres la misma línea en las dos direcciones, rule pone las dos a la vez.

Lo que no tiene equivalente con bordes es que el valor es una lista. Elige el patrón «Listas» en la demo y tienes esto:

.bento {
  row-rule: 3px solid #FF5200, repeat(auto, 1px dashed #94A3B8), 3px solid #FF5200;
  column-rule: 2px dotted #00D4AA, 2px dashed #FF7E41;
}

Cada valor va a un hueco, en orden. Cuando hay más huecos que valores, la lista vuelve a empezar, así que las columnas alternan punteado y discontinuo. repeat(auto, …) rellena lo que no cubren los demás valores: aquí, el primer y el último hueco entre filas son gruesos y continuos, y todo lo de en medio es una línea fina discontinua, haya las filas que haya. Solo se permite un repeat(auto, …) por valor. También existe repeat(3, …) con un número fijo.

Cortes, celdas vacías y recortes

Los otros tres controles de la demo corresponden a estas propiedades:

  • rule-break: none, normal o intersection. Con none, cada línea va de un extremo al otro del hueco. Con intersection, se corta en cada T y en cada cruce. normal depende del contenedor: en grid corta en las T pero atraviesa los cruces; en flexbox se comporta como none.
  • rule-visibility-items: all, around o between. Decide si se pinta una línea junto a una celda vacía. Toca la tarjeta grande para quitarla y cambia a between: las líneas alrededor del hueco desaparecen, porque ya no hay un elemento a cada lado. El valor inicial, normal, se comporta como all en grid. Esta solo se aplica a contenedores grid y multicolumna.
  • rule-inset: mueve los extremos de cada segmento. Un valor positivo los recoge desde el cruce, y los porcentajes se calculan sobre el ancho del hueco que se cruza. También existe la palabra clave overlap-join, y propiedades largas que separan los extremos en los bordes del contenedor (cap) de los que están en los cruces (junction).

Cuando las líneas no se cortan, rule-overlap decide qué dirección se pinta encima. El valor inicial es row-over-column.

Cambia de patrón en la demo y verás que el color y el grosor se animan: la especificación hace animables -color y -width como listas, y comprobé en Chromium que una transition sobre row-rule-color pasa por colores intermedios. El estilo cambia sin interpolar.

Soporte y trampas

  • De momento, solo Chrome y Edge 149. Los datos de compatibilidad de MDN marcan row-rule, rule-break, rule-inset y compañía como experimentales, sin soporte en Firefox ni Safari. La especificación es un Editor's Draft que sigue cambiando: el último Working Draft es del 24 de junio de 2026.
  • No detectes el soporte con column-rule. Existe para multicolumna desde mucho antes, así que el navegador dirá que sí aunque no pinte nada en un grid. Pregunta por row-rule (los ejemplos de MDN hacen lo mismo con @supports):
const supported = CSS.supports('row-rule', '1px solid red');
  • El fallback sale gratis, pero no es nada. En un navegador que no conoce estas propiedades, las declaraciones se ignoran y los huecos se quedan vacíos. Para líneas decorativas, suele bastar. Si el separador aporta significado, necesitas un plan B. La demo usa el de siempre cuando la detección falla: pintar el contenedor con el color de la línea recortado a content-box, con elementos opacos y de esquinas rectas tapándolo. Solo sirve para líneas continuas en todos los huecos: sin discontinuas, sin cortes y sin celdas vacías limpias. Lo probé en Chromium forzando el plan B.
  • Las líneas no hacen sitio. Si subes el grosor sin subir el gap, los elementos tapan la línea. Mantén el gap al menos igual de ancho que la línea.

Qué vigilar

  • Que Firefox y Safari lo implementen. Hasta entonces, úsalo como mejora progresiva y nada más.
  • Cambios en la especificación: los nombres y comportamientos aún se están puliendo, incluido cómo funciona con los nuevos contenedores grid lanes.
  • Si los sistemas de diseño que hoy dibujan separadores con bordes en cada elemento empiezan a pasar eso al contenedor.

Fuentes