Codificación de apps React más rápida: Cómo migrar de Emotion CSS-in-JS a Stylify Utility-First CSS
¿Quieres dar estilo a tu aplicación React más rápido? Aprende cómo migrar fácilmente de Emotion CSS-in-JS a Stylify utility-first CSS para un mejor desarrollo de React.
¿Buscas una forma mejor de gestionar tu CSS en React? Aprende a migrar de Emotion CSS-in-JS al enfoque utility-first de Stylify CSS y agiliza tu flujo de trabajo de desarrollo.
Puedes probar los ejemplos de este artículo en el Playground On Stackblitz 🚀.
💎 Introducción
Stylify es una librería que utiliza selectores similares a CSS para generar CSS optimizado basado en lo que escribes.
Características:
- ✅ Módulo de construcción. Sin script en tiempo de ejecución.
- ✅ Selectores tipo CSS
- ✅ Sin framework que estudiar.
- ✅ Menos tiempo invertido en docs.
- ✅ CSS manoseado y extremadamente pequeño
- ✅ No es necesario purgar CSS
- ✅ Componentes, variables, selectores personalizados
- ✅ Puede generar múltiples paquetes de CSS.
🔗 Componentes
En Emotion, los componentes se definen a menudo de esta manera:
const Title = styled.h1`
color: blue
font-weight: bold
@media (max-width: 640px) {
color:red
}
`;
<Title>¡Hola Mundo!🎉</Title>
Stylify proporciona una característica similar. Los Componentes pueden ser definidos dentro de un archivo (usando content options), donde son usados, o globalmente dentro de una config.
Ejemplo con la configuración dentro de un archivo. El contenido entre stylify-components
espera objeto javascript sin corchetes circundantes:
<!--
stylify-components
title: 'color:blue font-weight:bold md:color:red'
/stylify-components
-->
<h1 class="title"></h1>
Ejemplo en una configuración global del compilador:
const compilerConfig = {
title: 'color:blue font-weight:bold md:color:red'
};
Uso:
<h1 class="title"></h1>
Los componentes son “lazy” (generados bajo demanda). Esto significa, que incluso si los configuras (en un archivo o globalmente), se generarán sólo si coinciden dentro del contenido. No se generará CSS no utilizado. Lo mismo ocurre con las utilidades. Si la utilidad de un componente no coincide directamente con el contenido, no se generará el selector y sólo se añadirá el selector del componente a la salida CSS.
La salida CSS de producción tendrá este aspecto en producción:
.a,.d {color:blue}
.b,.d {font-weight:bold}
@media (max-width: 768px) {
.c,.d {color:red}
}
La salida html:
<h1 class="d"></h1>
Selectores
En Emotion, puedes usar CSS prop para dar estilo a un elemento directamente así:
<div css={css`
color: blue;
font-weight: bold;
@media (min-width: 640px) {
color: red;
}
`}></div>
Stylify te permite usar utilidades directamente dentro del contenido. Así que el ejemplo anterior puede ser refactorizado a esto:
<div className="color:blue font-weight:bold md:color:red"></div>
La salida de producción del CSS será similar al ejemplo de los componentes. El HTML sin embargo se verá así:
<div className="a b c"></div>
Estilos globales
A veces necesitamos dar estilo a algunas partes de la aplicación de forma global. Para hacerlo dentro de Emotion, necesitamos usar el componente Global:
<Global
styles={css`
.some-class {
color: hotpink !important;
}
`}
/>
En el caso de Stylify, puedes usar custom selectors para resolver este problema. Estos selectores pueden ser definidos directamente dentro del atributo class o en la configuración global.
Ejemplo con el atributo class:
<div className="[.button_.icon]{font-size:14px}">
<button className="
[.icon]{color:#fff;border-radius:12px}
[&+button]{margin-left:24px}
">
<i className="icon"></i>
</button>
<button></button>
<div>
El patrón sintáctico en el atributo class tiene el siguiente aspecto:
[selectores css]{selectores de estilización divididos por ;}
El _
(guión bajo) se utiliza en lugar del espacio en ambos selectores CSS y Stylify y el carácter &
siempre se refiere al elemento actual.
El mismo código pero en la configuración global se vería así
const compilerConfig = {
customSelectors: {
'.buttons-wrapper .button .icon': 'font-size:14px',
'.button': `
.icon { color:#fff border-radius:12px }
& + button { margin-left:24px }
`,
}
}
Al definir customSelectors
en la configuración global, la sintaxis permite utilizar una función de anidamiento. Los caracteres & hacen referencia al nivel superior.
Uso de la configuración global:
<div className="buttons-wrapper">
<button className="button">
<i className="icon"></i>
</button>
<button></button>
</div>
💲Variables
Cuando necesites pasar un color al componente usando props, entonces en lugar de hacer esto color: ${props => props.textColor};
, puedes usar variables CSS nativas:
<div
style={{ '--localTextColor': props.textColor }}
className="title color:$localTextColor"
>
</div>
Sólo tenemos que decirle a Stylify que el localTextColor
es externo:
const compilerConfig = {
externalVariables: ['localTextColor']
}
La variable externa también se puede definir sólo en el archivo donde se utiliza:
<!--
stylify-externalVariables
localTextColor
/stylify-externalVariables
-->
<div
style={{ '--localTextColor': props.textColor }}
className="title color:$localTextColor"
>
Stylify también proporciona una opción para configurar variables personalizadas. Se puede hacer en el fichero donde se usan, de la misma forma que los componentes o en la configuración global:
En el archivo:
<!--
stylify-variables
primary: '#000',
secondary: '#444'
/stylify-variables
-->
<div class="color:$primary"></div>
En Compiler Config:
const compilerConfig = {
primary: '#000'
}
📦 Dividir CSS
Emotion divide el CSS automáticamente y lo inyecta directamente en el documento basándose en los componentes renderizados.
Stylify no tiene ningún script de ejecución, por lo que tienes que configurar el Bundler y la división manualmente.
Sin embargo, la salida de Stylify es tan pequeña (puede ser incluso 10 Kb (gzipped) para un sitio web grande), que está bien tener sólo un paquete para todo el proyecto. Eventualmente, puedes ver consejos para dividir los paquetes CSS.
Ejemplo de configuración de paquetes:
const bundles = [
{
outputFile: 'path/to/layout.css',
files: ['path/to/layout.jsx']
},
// Bundler utiliza https://npmjs.com/package/fast-glob
// Puedes usar su sintaxis glob
{
outputFile: 'path/to/global.css',
files: ['path/**/*.jsx']
}
]);