Dentro del ecosistema de CSS-in-JS, una de las librerías más populares es Vanilla Extract. Entre las ventajas de esta solución están las siguientes:
- Estilos generados de forma estática (como Sass) pero con los beneficios de Typescript.
- Posibilidad de crear temas con tokens tipados, con autocompletado, etc.
- Agnóstico al framework. Puedes usarlo con React, Webpack, Vite, NextJS, etc.
Instalación
La instalación de Vanilla Extract es muy sencilla. Básicamente, se trata de instalar dos paquetes: el primero @vanilla-extract/css
que es el core que se necesita para utilizar la librería, y @vanilla-extract/vite-plugin
que es el plugin que permite integrar la librería con Vite. Esas instalaciones las hacemos desde una terminal así:
$ npm install -D @vanilla-extract/css @vanilla-extract/vite-plugin
Si queremos utilizar otra herramienta en lugar de Vite, en su documentación oficial tienes otras integraciones. En el caso de Vite, debemos ir a nuestro fichero vite.config.js
y escribir lo siguiente:
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
export default {
plugins: [vanillaExtractPlugin()]
};
Con esto estaremos listos para comenzar a usar la librería.
Uso de la librería
Como hemos mencionado anteriormente, CSS-in-JS es una forma de utilizar CSS dentro de nuestros ficheros Javascript. En este caso, casi hablamos de CSS-in-TS, ya que se aprovechan algunos de los beneficios de Typescript. Para utilizar Vanilla Extract, creamos un fichero component.css.ts
con el siguiente contenido:
/* component.css.ts */
import { style } from '@vanilla-extract/css';
export const styles = style({
display: "flex",
backgroundColor: "indigo",
color: "white",
padding: "1rem" // Si se añade como número, se asume que son "px"
});
/* component.ts */
import { styles } from "./components/component.css.ts";
const component = document.createElement("div");
component.textContent = "Contenido de texto";
component.classList.add(styles);
document.body.append(component);
Este es el fichero que contiene los estilos CSS en forma de objeto de Javascript, de forma muy similar a los módulos CSS, ya que sólo tenemos que añadir la clase que nos devuelve en styles
al elemento HTML.
Observa que las propiedades del objeto son las propiedades CSS, pasadas del formato kebab-case a camelCase, que es más apropiado para Javascript. En algunos casos, como variables CSS, pseudoclases u otros, debemos crear objetos anidados:
import { style } from '@vanilla-extract/css';
const base = style({
padding: 12
});
export const styles = style([base, {
display: "flex",
":hover": {
backgroundColor: "deeppink"
},
"::before": {
content: ""
},
"@media": {
"(width <= 800px)": {
backgroundColor: "red"
}
}
}]);
Al estar trabajando con Typescript, estaremos aprovechando las características de tipado que tiene, así como los beneficios del autocompletado, por lo que tras escribir los :
podemos pulsar CTRL+ESPACIO para ver las opciones disponibles.
Además, observa que en este caso hemos creado dos objetos, y en el segundo de ellos, utilizamos un array para utilizar composición y fusionar los estilos de cada uno.
Creación de temas
Otro detalle muy interesante de Vanilla Extract es la posibilidad de crear temas. Para ello, creamos un objeto utilizando la función createTheme()
, pasándole también un objeto:
import { createTheme } from "vanilla-extract/css";
export const [themeClass, vars] = createTheme({
color: {
brand: "blue" // --color-brand__[hash]: blue
},
font: {
body: "arial, sans-serif" // --font-body__[hash]: arial, sans-serif;
}
});
Con la información de este objeto se crearán variables CSS para utilizar como tema. Observa que las propiedades del objeto mencionado son el namespace (la primera parte) de la variable CSS, mientras que se continua la variable CSS con los nombres de las propiedades del objeto de su interior.
La ventaja principal de crear estos objetos (y no una variable CSS directamente) es que podremos aprovechar el autocompletado de nuestro editor para completar estos nombres de temas y utilizarlas con seguridad en el resto de nuestra aplicación.
Alternativas a Vanilla Extract
Existen muchas otras librerías CSS-in-JS alternativas que permiten trabajar con objetos Javascript (o de forma muy similar). Veamos algunas de ellas:
Librería | Genera CSS estático | Sintaxis de objetos | Sintaxis de templates | GitHub |
---|---|---|---|---|
Vanilla Extract | ✅ | ✅ | ❌ | GitHub |
Panda CSS | ✅ | ✅ | ✅ | GitHub |
ECCStatic | ✅ | ✅ | ❌ | GitHub |
Linaria | ✅ | ✅ | ✅ | GitHub |
Emotion | ❌ | ✅ | ✅ | GitHub |
Styled Components | ❌ | ✅ | ✅ | GitHub |
❌ | ✅ | ✅ | GitHub |
Si no lo has visto aún, echa un vistazo a ECSStatic, un post donde vemos una librería CSS-in-JS con sintaxis de string templates.