Una opción muy utilizada en el ecosistema de CSS-in-JS es la conocida por CSS Modules. No se trata de una librería ni un framework, sino una estrategia con la que podemos conseguir varias cosas:
- 1️⃣ Dividir en ficheros
.module.css
separados (módulos de CSS) - 2️⃣ Conseguir «scope» local para cada módulo (evitar colisiones)
- 3️⃣ Código más fácil de mantener y escalar
Con estas ventajas, trabajar en una aplicación web con CSS se hace mucho más sencillo. Veamos que pasos podemos seguir para poder trabajar de esta forma.
Instalación
Al no ser una librería ni framework, sino una estrategia, podemos trabajar de múltiples formas, y simplemente adoptar CSS modules como enfoque complementario. Si utilizamos Vite es muy sencillo, ya que tiene integración incorporada.
Uso
Utilizar CSS Módules es muy sencillo. Se basa en crear pequeños ficheros llamados módulos CSS con la extensión .module.css
. Esto hará que nuestro proyecto identifique si se trata de un .css
normal o un fichero módulo CSS.
Al importarlo, Javascript nos devuelve un objeto con las clases de ese módulo CSS, que tendremos que asignar a la clase del elemento HTML. Veamos un ejemplo:
/* component.module.css */
.title {
background: indigo;
color: white;
padding: 1rem;
}
.warning {
background: darkred;
}
Observa que cuando importamos el fichero .module.css
con Vite, se carga ese fichero como un módulo CSS y se devuelve un objeto con las clases del módulo y la clase autogenerada por CSS módulos, para hacer la clase única y evitar colisiones de nombres de clases. Luego, a la hora de trabajar con estos estilos lo haremos de la siguiente forma:
import classes from "./component.module.css";
/*
classes = {
title: "title_13rzd_1",
warning: "warning_1csbp_8"
}
*/
const element = document.querySelector(".element");
element.classList.add(classes.title);
element.textContent = "Hello world! Styled with CSS Modules";
Esto puede ser una forma más controlada de usar CSS con un enfoque local, que puede ser interesante para utilizar en aplicaciones web. Además, recuerda que podemos utilizar CSS Nesting para dar estilo a elementos que estén incluidos en el elemento o componente.
Composición en CSS Modules
Además, CSS Modules tiene algunas características interesantes como la composición mediante la propiedad composes
. Esta propiedad no existe en CSS nativo, pero CSS Modules la añade para poder trabajar heredando estilos.
Veamos un ejemplo:
.coreTitle {
background: indigo;
color: white;
padding: 1rem;
}
.warningTitle {
composes: coreTitle;
background: darkred;
}
Observa que estamos creando una clase warningTitle
que usa composición para heredar todo lo que tiene coreTitle
. Se trata de una especie de mixin muy interesante para reutilizar estilos.
Personalización de clases
En algunos casos puede que no estemos conforme con el nombre de clases que genera CSS Modules. Esto es personalizable, editando el fichero vite.config.js
de nuestro proyecto:
export default {
css: {
modules: {
generateScopedName: 'manzdev-[name]__[local]___[hash:base64:5]'
}
}
}
Utilizamos:
[name]
para indicar el nombre del fichero original[local]
para indicar el nombre de la clase original[hash:base64:5]
para generar un hash de 5 carácteres en Base64.- Podemos usar otras configuraciones como
[ext]
,[path]
,[folder]
o[query]
, o configurar el hash consha1
,md5
,sha512
, etc. Tienes más información en opciones del hash.
Ten en cuenta, que por defecto CSS modules se procesa mediante PostCSS. También es posible configurarlo con LightningCSS, donde las opciones anteriores no tendrían efecto. En ese caso, se configuraría así:
export default {
css: {
lightningcss: {
cssModules: true
}
}
}
Si buscas una forma estándar y nativa de utilizar CSS Modules, sin necesidad de preprocesadores, te recomiendo echar un vistazo a CSSStyleSheet, donde lo explico en detalle.