A veces utilizamos propiedades CSS por uso y costumbre y no nos planteamos hasta dónde las podemos llevar, y la respuesta es, en general, que hasta donde nuestra creatividad y los límites definidos nos permitan.

La creatividad dependerá del día pero los límites son fijos y puedes encontrarlos declarados en la especificación y su sintaxis formal, aunque puede ser algo críptica, sobre todo para aquellas propiedades que más posibilidades ofrecen.

Cómo leer la sintaxis

Algunos símbolos significan lo mismo que en las expresiones regulares de JavaScript así que es fácil interpretarlos

Símbolo Significado Ejemplo
<nombre> Tipo de dato <number>, <angle>
nombre (sin <>) Palabra clave literal none
() Cosas literales de la sintaxis como los paréntesis de una función oklch()
[] Agrupación [ a b ]
| Alternativa (una u otra) <number> | <angle>
? Valor opcional (0 ó 1) [ /alpha ]?
! Valor requerido
* 0 o más veces
+ 1 o más veces
# Lista separada por comas <value>#
{n} / {n,m} Repeticiones exactas o en rango <number>{3}
&& Todos, en cualquier orden a && b
|| Uno o más, en cualquier orden a || b
[n,m] Especifica un rango numérico. El valor mínimo y el máximo <integer [0,∞]>

Ya podemos leer con facilidad la especificación, por ejemplo, la función oklch y entenderemos por qué oklch(none none none) es un valor igual de válido que oklch(70% 0.1 200) o oklch(70% 0.1 200deg / 50%).

<oklch()> =
  oklch([<percentage>|<number>| none][<percentage>|<number>| none][ <hue>| none][ /[ <alpha-value>| none]]? )

<hue> = <number>|<angle>

<alpha-value> = <number>|<percentage>

O que las transiciones van separadas por comas

transition =
  <single-transition>#

O que el orden en el que escribes las propiedades del shorthand transition no es tan estricto como pensabas, y que all 200ms linear 50ms normal es igual de válido que 200ms 50ms normal all linear

<single-transition> =
  [ none | <single-transition-property> ]  ||
  <time>                                   ||
  <easing-function>                        ||
  <time>                                   ||
  <transition-behavior-value>

En este caso, hay una trampa. Para los dos valores de tipo <time> la gramática no los distingue y cuál es cada uno lo decide la posición: el primero es duration y el segundo delay. Es lo que hay, la gramática por sí misma no lo expresa, por eso hay que leer también la spec.

Algo parecido ocurre con grid-template-columns, que leyendo la sintaxis no queda suficientemente claro que auto-fill y auto-fit solo pueden aparecer una vez, y solo dentro de <auto-track-list>.

Conclusión

Conocer las bases de un sistema nos permite construir un conocimiento sólido y sano sobre el propio sistema. Por eso es importante leer detenidamente las especificaciones del lenguaje que utilizamos.

En los tiempos de la IA cabe preguntarse si es necesario estudiar un lenguaje de programación o leer con atención una aburrida especificación, porque asumámoslo, la mayoría lo son. No lo hagas, si crees que ese es el camino. Nosotros por el momento seguiremos apostando por entender los fundamentos porque pensamos que cuanto menor es la distancia entre tu conocimiento y lo que subyace, menos espacio hay para la magia.

Desde luego con la IA se gana velocidad, es evidente, pero conocer en detalle un proceso permite entenderlo mejor y tomar decisiones fundamentadas y contrastadas, y a menudo, más acertadas y a la primera.

Recursos