CSS en JS

Estilizar una página web usando CSS con JavaScript, ¿es una buena idea?

css-en-js

Una página web se desarrolla a partir de código HTML, para determinar cómo estructurar la información. Unas hojas de estilo, para ayudar a mejorar la experiencia visual y código JavaScript para añadir interactividad y hacerla más dinámica.

Problemas de CSS cuando la aplicación crece

Estos tres elementos bastan para crear cualquier tipo de página web. Sin embargo, cuando las aplicaciones empiezan a crecer de tamaño y hay múltiples programadores que trabajan sobre ella al mismo tiempo surgen varios problemas. Si nos centramos a los estilos CSS específicamente, nos encontraremos con:

  • Problemas asociados a una nomenclatura global (global namespace): En CSS todas las reglas se definen en el contexto global, por lo que rápidamente pueden aparecer conflictos si usamos el mismo nombre de clases en distintos elementos HTML de nuestras páginas.
  • Dependencias: Es inviable escribir todo el CSS en una sola hoja de estilos o un solo archivo, normalmente una aplicación requerirá de múltiples hojas de estilos que además pueden depender unas de otras.
  • Eliminación de código en desuso: No existe un enlace directo entre los estilos definidos en el código CSS y su uso en los elementos HTML que nos permitan eliminar código CSS cuando lo borramos del HTML, haciendo que quede código muerto y sin usar. ¿O cómo saber si una clase está siendo usada?

En 2014, Christopher Chedeau frontend engineer de Facebook, listaba estos problemas y algunos más.

Solución: CSS en JS

Para solucionar todos estos problemas se puede usar JavaScript como un lenguaje que describa los estilos de una forma declarativa, escalable y mantenible. Esto trae un conjunto de beneficios:

  • Pensar en componentes: No es necesario gestionar múltiples hojas de estilo. Con CSS en JS se puede abstraer el modelo de CSS a nivel de componentes, en lugar de a nivel del documento (facilita la modularidad).
  • Estilos dinámicos.
  • Aprovecha el poder del ecosistema de JavaScript para mejorar CSS.
  • Selectores únicos: Generar nombres de clase únicos por defecto. Es imposible evitar colisiones de selectores en aplicaciones complejas. Convenciones de nomenclatura como BEM pueden ayudar en un proyecto, pero no al integrar código de terceros.
  • Prefijos para navegadores: Las reglas CSS se prefijan automáticamente según el navegador, así que no tienes que preocuparte por ello.
  • Compartir código: Comparte fácilmente constantes y funciones entre JavaScript y CSS.
  • Solo los estilos en uso están en el DOM.
  • Eliminación de código muerto.
  • Pruebas unitarias para CSS.

Pero también hay desventajas al usar CSS en JS

Existen algunos inconventientes al generar CSS con JS:

  • Curva de aprendizaje.
  • Nuevas dependencias.
  • Es más difícil para nuevos integrantes del equipo adaptarse a la base de código.
  • Incrementa el tamaño de la aplicación pues requiere enviar al usuario la librería que transforma los estilos de JS a CSS.

Pero el más importante es el de rendimiento. Hay que ejecutar el código JS para generar los CSS y insertarlo el DOM y esto no se puede hacer en el build time sino cuando el usuario carga la aplicación en el navegador. Esto puede entorpedecer métricas de Core Web Vitals al renderizar componentes de nuestra página.

Librerías que nos permiten usar CSS con JS

Estas son las librerías más conocidas que puedes usar.

Ejemplo

Veamos un ejemplo rápido de como se usaría styled components en React. Definimos los estilos dentro de JavaScript como si fuera un string.

const ButtonStyles = styled.a`
padding: 0.8em 1em;
color: white;
background-color: ${ ({ primary }) => ( primary ? "#07d" : "#222" ) };
`;
const App = () => {
return (
<div>
<ButtonStyles href="#">Texto</ButtonStyles>
</div>
);
}

Conclusión

CSS en JS ofrece múltiplas ventajas, como evitar conflictos con nombres de clase, estilizar con CSS a nivel de componente y estilos dinámicos entre otros. Pero también trae algunas desventajas y no menores, como el empeoramiento del rendimiento del lado del cliente, la importación de librerías y el consecuente incremento de tamaño del proyecto.

Por lo tanto hay que valorar en qué tipo de aplicación es adecuado usarlo o no.