CSS Decoration Gaps

Decoraciones de huecos (gaps) en Flex, Grid y otros


Al utilizar sistemas de maquetación como Flex, Grid, MultiColumn (o incluso el futuro Masonry), uno de los principales problemas que nos encontrábamos era el de añadirle lineas de decoración entre elementos a nuestro diseño, es decir, decorar los huecos o gaps.

Observa el siguiente ejemplo para entender la problemática que teníamos hasta ahora. En él, creamos un grid de 5x5 donde hay sólo 8 celdas (para que se vea bien). Como no tenemos mecanismo para añadir líneas al grid, las podemos simular con los bordes de las celdas interiores:

.box {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
  width: max-content;
  border: 2px solid black;

  .cell {
    background: #ccc;
    border: 2px solid indigo;
  }
}
<div class="box">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

Esto daba bastantes problemas cuando simplemente buscabamos decorar con líneas y no complicar o afectar al tamaño o diseño de nuestro grid.

Veamos como podemos resolver esto.

Decoraciones de huecos (gaps)

Para definir estas decoraciones necesitaremos utilizar las propiedades de la familia column-rule-* y row-rule-*, así como tener un gap mayor de 0 (en caso contrario, se ocultarán). Aunque estas propiedades llevan implementadas durante bastante tiempo en los navegadores, recientemente se han añadido algunas otras como column-rule-break, column-rule-outset o rule-overlap, por lo que el soporte en navegadores que no estén actualizados puede ser incompleto.

Veamos que propiedades tenemos a nuestra disposición:

PropiedadDescripción
column-rule-width / row-rule-widthDefine el grosor de la decoración del gap.
column-rule-style / row-rule-styleDefine el estilo de la decoración del gap.
column-rule-color / row-rule-colorDefine el color de la decoración del gap.
⚠️ column-rule-break / row-rule-breakDefine si la decoración del gap debe romperse o no.
⚠️ column-rule-outset / row-rule-outsetDefine hasta donde llegará la decoración del gap.
⚠️ rule-overlapIndica que decoración debe estar por encima de la otra, columna o fila.

Veamos cada uno de ellos con ejemplos para entenderlos mejor.

Las propiedades individuales

Las 3 propiedades individuales son column-rule-width, column-rule-style y column-rule-color. No obstante, si sólo indicamos la propiedad column-rule-style será suficiente, ya que por defecto, column-rule-color será black y column-rule-width será 3px:

.box {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
  width: max-content;
  border: 2px solid black;

  gap: 1px;
  column-rule-width: 1px;
  column-rule-style: dotted;
  column-rule-color: black;
}
<div class="box"></div>

De la misma forma, cambiando column- por row- podemos añadir las decoraciones de gaps en horizontal:

.box {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
  width: max-content;
  border: 2px solid black;

  gap: 1px;
  column-rule-width: 1px;
  column-rule-style: dotted;
  column-rule-color: black;
  row-rule-width: 1px;
  row-rule-style: dashed;
  row-rule-color: darkred;
}
<div class="box"></div>

Patrones alternos

Las propiedades *-rule-width, *-rule-style y *-rule-color permiten definir patrones y no sólo un único valor. De forma que si indicamos, por ejemplo, un valor grey grey red red en column-rule-color significa que las dos primeras líneas serán grises, y las dos siguientes serán rojas y vuelta a empezar.

De la misma forma se puede hacer con los anchos y con los estilos:

.box {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
  width: max-content;
  border: 2px solid black;

  gap: 1px;
  column-rule-width: 4px;
  column-rule-style: dashed dashed solid solid;
  column-rule-color: grey grey red red;
}
<div class="box"></div>

Ten en cuenta que también puedes utilizar la función repeat() para definir patrones. Por ejemplo, el valor red red red blue green green puede reemplazarse por repeat(3, red) blue repeat(2, green)

La propiedad column-rule-break y column-rule-outset

Estas propiedades permiten definir como se van a «partir» las decoraciones de gaps de las columnas y/o filas y se suelen utilizar en conjunto. Por un lado, column-rule-outset permite definir un tamaño, en negativo o positivo, mientras que column-rule-break debe definir uno de los siguientes valores:

ValorDescripción
noneModifica en los extremos de las decoraciones de gap.
spanning-itemIdem al anterior, respetando si se cruza una columna/fila.
intersectionModifica en las intersecciones de las columnas y filas.

Recuerda que al igual que usamos propiedades prefijadas por column- también podemos usar propiedades prefijadas por row-.

La propiedad rule-overlap

Con la propiedad rule-overlap podemos establecer si las decoraciones de gap de columnas o de filas estarán superpuestas por encima de la otra. Los valores posibles que podemos usar son los siguientes:

ValorDescripción
row-over-columnLas decoraciones de filas están sobre las de las columnas. Valor por defecto.
column-over-rowLas decoraciones de columnas están sobre las de las filas.

La propiedad rule-overlap es el nuevo nombre que tendrá esta propiedad. Antiguamente era llamada gap-rule-paint-order o rule-paint-order. Es posible que algunos navegadores no soporten aún el nuevo nombre.

Atajos

Ahora que ya conocemos el funcionamiento de estas propiedades, vamos a dar un repaso a las diferentes propiedades de atajo o shorthands que tenemos a nuestra disposición.

PropiedadDescripción
column-rule / row-rulePropiedad de atajo donde podemos usar width, style y color por cada eje.
rule-colorPropiedad de atajo que permite indicar el color para columnas y filas a la vez.
rule-stylePropiedad de atajo que permite indicar el style para columnas y filas a la vez.
rule-widthPropiedad de atajo que permite indicar el width para columnas y filas a la vez.
ruleAtajo global: puedes establecer un color, estilo y ancho tanto para columnas como para filas.

Las propiedades rule-color, rule-style y rule-width

En primer lugar, podemos utilizar las propiedades rule-color, rule-style y rule-width para indicar los colores, estilos y ancho de grosor tanto para las columnas como para las filas si ambos son idénticos. De esta forma te ahorras tener que hacerlo de forma separada:

.element {
  column-rule-width: 1px;
  column-rule-style: dotted;
  column-rule-color: black;
  row-rule-width: 1px;
  row-rule-style: dotted;
  row-rule-color: black;

  /* Shorthand */
  rule-width: 1px;
  rule-style: dotted;
  rule-color: black;
}

La propiedad column-rule y row-rule

Por otro lado, si lo prefieres, puedes utilizar las propiedades column-rule y row-rule para reducir el número de propiedades a utilizar, si la configuración de las filas es diferente al de las columnas, pero utilizando una sola propiedad para la configuración de cada eje:

.element {
  column-rule-width: 1px;
  column-rule-style: dotted;
  column-rule-color: black;
  row-rule-width: 1px;
  row-rule-style: dotted;
  row-rule-color: black;

  /* Shorthand */
  column-rule: 1px dotted black;
  row-rule: 1px dotted black;
}

La propiedad rule

Por último, si la configuración de las columnas es exactamente igual que la de las filas, puedes utilizar la propiedad rule y ahorrarte todo en una sola propiedad.

Observa el siguiente ejemplo, donde retomamos el ejemplo inicial y lo convertimos en una sopa de letras, añadiendo un poco de Javascript:

<div class="box"></div>

<style>
.box {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
  place-items: center;
  width: max-content;
  border: 2px solid black;

  rule: 1px dotted black;
  gap: 2px;
}
</style>
const SIZE = 5;
const CELL_SIZE = 40;
const box = document.querySelector(".box");

const getRandomChar = () => String.fromCharCode(65 + Math.floor(Math.random() * 26));

box.innerHTML = [...Array(SIZE * SIZE)]
  .map(() => `<div>${getRandomChar()}</div>`)
  .join("");

Aunque no se muestra en el ejemplo, la propiedad rule permite indicar múltiples valores, separados por comas, de modo que 1px solid black, 1px solid red crearía linea negra, linea roja tanto en columnas como en filas, y así de forma repetitiva.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev