React — Formas de diseñar componentes de React, desde estilos en línea hasta CSS in JS

Mauricio Garcia
35 min readOct 7, 2020

--

Temario

  • Introducción
  • CSS en línea
  • CSS Estándar
  • Módulos CSS (CSS modules)
  • Preprocesadores (SASS)
  • CSS en JS
  • Styled Components
  • Emotion
  • Fela
  • Aphrodite
  • Styletron
  • JSS (React-JSS)
  • Otros CSS-in-JS

i. Introducción

Sabemos que React es una librería de JS para construir interfaces de usuario, y por lo tanto al ser elementos visuales, diseñarlos, son una parte importante, que como desarrolladores no le damos la atención que realmente se merece.

A mi, personalmente, crear estilos es la parte que más pereza me da, y más por que siempre aprendí a hacerlo de la mala forma 🤦‍♂️ (ya saben… con prisas, sin conocimiento, copiando y pegando), entonces, cuando empecé con React, uno de los objetivos fue… implementar estilos de mejor calidad; así que comencé a investigar… y me lleve GRAN una sorpresa:

  • Existen bastantes formas de implementar estilos (en línea, archivos CSS, precompiladores, hasta CSS dentro de JS).
  • Puedes implementar estilos pensando cómo componentes.
  • Es tan dinámico, que no parece que estemos haciendo CSS.
  • Existen una gran variedad de paquetes (con ventajas y desventajas).
  • A React no tiene alguna opinión acerca de cuál es la mejor forma de escribir CSS, solo sugieren que para iniciar tus estilos los hagas en un archivo CSS.

Cuando descubrí todo esto, me hice la siguiente pregunta: ¿De todas las formas de implementar CSS, alguna es la mejor? La respuesta es NO, ya que siempre dependerá del proyecto (arquitectura, dependencias, reutilización, escalabilidad, etc), así como de la forma de trabajar con nuestro equipo, por lo que te recomiendo que explores y adoptes la que mejor te convenga.

Basta de tanta introducción y vamos a lo que nos interesa…

Vamos a tener un componente base llamado Component:

Y en la App, lo importamos y agregamos:

La idea es convertir el ejemplo a:

ii. CSS en línea

Esta es la forma más vieja de implementar CSS en una aplicación, dentro del atributo style, agregamos todas las propiedades dentro de una cadena de texto:

En React es ligeramente diferente, ya que nos permite agregar CSS en línea, pero no como una cadena de texto, si no como un objeto JavaScript, cuya clave es tipo camelCase text-align => textAlign y el valor va dentro de una cadena de texto; esto con la finalidad de evitar agujeros de seguridad de XSS.

Tenemos dos formas de crear los estilos en línea: Poner directamente el objeto dentro del atributo style o la otra es crear una variable y asignarla al atributo style.

:: Ejemplo

Los estilos directamente en los elementos:

Los estilos en una constante, que se le pasa a los elementos:

Los objetos de estilo y los componentes no necesariamente tienen que estar en el mismo archivo, podemos crear un archivo .js separado para los estilos, y luego importarlos al componente donde vamos a usarlos, con la ventaja de hacerlos reutilizables.

:: Ejemplo completo

:: Ventajas y desventajas

  • No se recomienda usar el atributo style para estilizar elementos, ya que está pensando para cosas simples.
  • Los selectores como :hover, :blur, :after, etc no son posibles utilizar (hay que agregar estados y validaciones extras en JavaScript para que funcionen[ref][ref])
  • Otra desventaja es que no reciben automáticamente los prefijos de compatibilidad, por lo que se deben de agregar manualmente las propiedades.
  • Su mayor uso, es para añadir estilos que necesitan calcularse dinámicamente al momento de renderizarse (fondos de pantalla dinámicos, calculo de tamaño de un modal, posición del scroll, etc).
  • Se recomienda usar className, para hacer referencia a clases definidas de CSS externos, ya que generalmente son mejores en rendimiento.

iii. CSS Estándar[ref]

Importar un archivo CSS es otra forma de agregar estilos a la aplicación, tan sencillo como, crear un archivo CSS, agregar estilos, y finalmente importarlo.

:: Ejemplo

Dentro de la hoja de estilos App.css , agregamos el siguiente código:

Lo importamos en el componente App.js :

Gracias a webpack[ref], podemos importarlo dentro del componente, ya que nos da la oportunidad de “extender” el import mas allá de JavaScript.

Y por último en el componente Component, agregamos las clases a los elementos con el atributo className:

Otra opción es generar por cada componente una hoja de estilos, algo así:

Importante: Tener cuidado de hacerlo de esta forma, ya que webpack al momento de generar el proyecto para producción, lo que hace es juntar todos los archivos en uno solo, por lo que sí tenemos clases genéricas, es seguro que se tenga problemas de visualización.

:: Ejemplo completo

:: Ventajas y desventajas

  • Una ventaja es mantener separado el CSS con JavaScript, al menos en el ambiente de desarrollo.
  • Una de las grandes desventajas, es que al final todos los archivos CSS en producción, se van a empaquetar y minificar en uno solo archivo, por lo que puede haber conflicto en los estilos.
  • Mantener separado CSS con JavaScript en React no es necesario, ya que nos permite crear todo en uno (veremos más abajo CSS in JS).

iv. Módulos CSS [ref]

Al usar CSS estándar, vimos que su gran desventaja es que empaqueta todos los estilos en un solo archivo, y que hay una gran posibilidad de que estos choquen. Con CSS modules no debemos de preocuparnos por eso

CSS Module es un archivo CSS en el que todos los nombres de clase y nombres de animación tienen un ámbito local de forma predeterminada.[ref].

Los CSS Modules son archivos .css, se les llama “CSS Module” , por que se compilan en un formato de intercambio de bajo nivel llamado ICSS[ref], pero realmente están escritos como archivos .css.

:: Sintaxis

Es importante que todos los archivos css, que se generen lleven la siguiente sintaxis:

:: ¿Cómo es que CSS Modules puede generar las clases en un ámbito local?

Cuando importamos un archivo CSS Modules a la aplicación o componente, y utilizamos alguna de las clases, pasa algo así:

Donde:

  • ButtonEs el nombre del componente
  • buttonEs el nombre de la clase
  • 2Ce79Es un hash aleatorio

Podemos observar que genera una clase única .Button_button__2Ce79 a nivel global, y al ser única, no hay forma de que choque con algún otra (con esto logra el “alcance local”).

Al momento de compilar, los nombres de las clases locales se asignan a los componentes y se crea un archivo JavaScript para React, que es un objeto que se va a encargar de mapear el nombre original de la clase con el nombre renombrado.

Es interesante como funciona, ya que las librerías de CSS-in-JS funcionan de manera MUY similar.

:: Ejemplo 1

Tenemos el archivo css llamado Button.module.css

Y el componente Button, donde vamos a importar y utilizar el css :

De esta forma la variable styles (puedes llamarle como quieras), se convierte en un objeto donde va a tener cada una de las clases que tiene el archivo.

En el componente App , importamos el componente Button :

En la imagen de arriba, podemos observar:

  • Del lado izquierdo, está el botón
  • En la parte media el HTML, donde, tiene asignada la clase Button_button_2Ce79
  • En la parte derecha los estilos de esa clase.

Ahora si observamos la imagen de abajo, el archivo CSS, tiene el mapeo de la clase original con la generada "button": "Button_button__2Ce79"

:: Ejemplo 2

Además CSS Modules también nos da la oportunidad de importar solo las clases que necesitemos.

Imagina que tenemos en una hoja de estilos todas las clases, y realmente solo vamos a ocupar algunas clases:

:: Ejemplo 3

Otra ventaja que nos da usar CSS Modules, es que podemos utilizar variables con @values, y heredar estilos con modules.

:: Sintaxis

Crear una variable o importar una hoja de estilos :

Cómo heredar de una clase de otro archivo:

:: Ejemplo

Imaginemos que tenemos colors.module.css (No olvidemos la sintaxis ${name}.module.css)

Estamos creando variables llamadas background, secondBackground, color, secondColor con sus respectivos valores (en este caso son colores).

Tenemos otra hoja de estilos con propiedades “basemixins.module.css

Y finalmente la hoja de estilo Component.module.css , donde vamos a importar colors.module.css y mixins.module.css

Vamos a explicar paso a paso la parte de arriba:

  • En la línea 1 estamos creando una variable de tipo object llamada colors
  • En la línea 2 estamos obteniendo cada una de las variables que vienen en el objeto colors (es una especie de desestructuración)
  • Podemos dejar la línea 1, y donde se necesite alguno usar colors.background, colors.color, ...
  • En la línea 2 le estamos indicando que va a heredar la clase container del archivo mixins.module.css.

En la imagen de abajo, podemos ver como nos ha creado clases únicas:

:: Ejemplo completo

Nota: codesandbox.io al parecer no soporta al 100% CSS Modules, por lo que tuve que poner todas las hojas de estilo en una sola

Si quieres saber más a fondo de CSS Modules puedes revisar la documentación [ref][ref].

:: Ventajas y desventajas

  • Una buena ventaja es que soporta pre-procesadores (SASS, LESS), lo cual puedes trabajar tus estilos con ellos, y utilizarlos como CSS Modules.
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Para proyectos estáticos y componentes aislados, puede ser una buena opción, para aplicaciones grandes quizás no sea la adecuada.
  • Si usas visual code, la extensión CSS Modules[ref], nos va ayudar a autocompletar las clases en el componente de React.

v. Preprocesador (SASS)[ref]

SASS es una herramienta muy poderosa, siempre y cuando sepamos usarla, de lo contrario puede ser un desastre.

Vamos a usar SASS con React, por lo que el primer paso es crear un proyecto:

Limpiamos la App.js:

Así como el archivo App.css :

Ahora sí, una vez que se han instalado todas las dependencias y ajustado la aplicación, procedemos a instalar SASS[ref]:

Para saber que realmente funcionó:

  • Cambiar el nombre del archivo src/App.css por src/App.scss
  • En el archivo src/App.js, cambiar import './App.css' por import './App.scss'
  • Abrimos el archivo src/App.scss, y hacemos el siguiente cambio:

Lo que estamos haciendo es crear dos variables $background y $color, donde se están utilizando en la etiqueta html

  • Levantamos el servidor

Si se ha instalado correctamente SASS, debes ver la aplicación de la siguiente manera:

a — ¿Qué es SASS ?

Sass (Syntactically Awesome Style Sheets) is the most mature, stable, and powerful professional grade CSS extension language in the world.[ref]

O como me gusta más decirlo es un CSS con superpoderes!, ya que agrega un conjunto de características a la hoja de estilos, haciendo que sea más atractivo crear estilos.

Nota: En esta story vamos las características básicas de SASS, y quizás en otra story lo toquemos a fondo.

b — Variables con SASS

SASS permite generar variables tipo Global scope y Block scope, así es como en JavaScript:

c — Reglas en SASS

Antes de continuar, regresemos al ejemplo base, donde, tenemos un componente llamado Component (recuerden crear la carpeta components y agregar el componente ahí)

La App, lo importamos y agregamos:

Si revisamos el navegador, debe verse así:

Ahora si, continuemos…

Otra ventaja de SASS, son las funcionalidades que tiene extra que se usan como “at-rules”[ref].

:: @Import[ref]

La regla @Import nos permite importar un archivo scss en otro archivo scss

Vamos a separar las variables de la aplicación, primero crearemos una carpeta llamada components/styles y dentro de ella el archivo variables.scss, donde agregaremos los colores base:

Ahora vamos a crear otro archivo styles/Component.scss, donde vamos a importar los colores:

El siguiente paso es importarlo en el componente Component y agregar las clases con el atributo className

Si revisamos nuestro navegador:

:: @mixin e @include[ref]

Los @mixin nos van a permitir definir estilos que puedan reutilizarse en cualquier hoja de estilos, y el @include para agregarlos en el código.

Vamos a crear una hoja de estilos que contenga algunos mixins, styles/mixins.scss

Y el CSS del archivo Component.scss

SASS nos permite inicializar argumentos por default (sí! como en JavaScript), hagamos el cambio en mixins.scss

Entonces, en el archivo Component.scss, podemos incluir el mixin sin argumentos a los que queremos que tengan valores por default:

La clase .title y .paragraph van a tener propiedades específicas, mientras que .button y .link van a tener las de default.

Si quieres ver todas las at-rules que tiene SASS[ref]

c — Selector &[ref]

Este selector es bastante útil, ya que con él podemos anidar pseudo-clases, agregar un selector antes del padre o selectores.

Para crear estilos a los selectores como :hover, :blur, :after, etc, en CSS lo hacemos de la siguiente manera:

Con SASS lo simplifica usando el selector &

Entonces, hagamos unos cambios en el código:

mixins.scss

Component.scss

Nota: Esta solo es una forma básica de hacer los estilos con SASS, por lo cual solo está adaptado para el ejemplo, te invito a que leas la documentación y mejores el código del ejemplo :)

:: Ejemplo completo

Si quieres saber más a fondo de SASS puedes revisar la documentación [ref].

— SASS & CSS Modules

Podemos usar SASS con CSS Modules, vamos a convertir la aplicación:

  • Debemos renombrar el archivo Component.scss por Component.module.scss
  • Cambiar el import en el componente Component de import "../styles/Component.scss" por import styles from "../styles/Component.scss"
  • Utilizar el objeto styles en cada className

:: Ejemplo completo SASS con CSS Modules

:: Ventajas y desventajas

  • Una de sus mayores ventajas es todas las funcionalidades extras que tiene (at-rules, anidamiento de código, funciones, mixins, extends, …), lo que lo hace más limpio y fácil.
  • Es compatible con todas las versiones de CSS, y genera los prefijos de compatibilidad.
  • Si un desarrollador no lee la documentación o no entiende cómo funciona, puede generar mucho código basura.
  • El patrón BEM[ref][ref] puede ir bien, siempre y cuando todos los desarrolladores tengan esa forma de pensar.
  • Una ventaja es que es compatible con CSS Modules.

vi. CSS en JS

:: Introducción

Recuerdo que cuando me enseñaron CSS (y me parece que hasta la fecha se sigue enseñando igual), en una hoja de estilos llamada styles.css vamos a meter todo, que necesitamos una lista, una galería o cualquier otra cosa, íbamos a styles.css y a crear CSS. El proyecto en el que estaba en aquel entonces era pequeño, por lo que solo éramos dos personas, así que no había tanto problema. El proyecto comenzó a crecer, ya éramos 3 desarrolladores, seguíamos manteniendo cierto orden y control; pero luego el proyecto comenzó a crecer que de una semana a otra ya éramos 15 (¿te suena?), empezó el caos…

  • Código CSS duplicado a lo largo de todo el style.css
  • Ese &#$%& !important escondido que afectaba a todo el proyecto
  • Muchísimo estilo basura, que no hacía absolutamente nada
  • Un archivo con más de 999 líneas
  • Estilos “en duro” inline

Entonces cambiamos la estrategia, separar por bloques el código, algo así: footer.css, sidebar.css, container.css, form.css,... hasta aquí ya se tenía un poco más de orden, pero aún así, se tenían (a menor escala) los problemas de duplicación de código…así que seguimos evolucionando y es cuando empezamos a crear CSS a nivel “componente”:

  • Creamos componentes con estilos básicos, que mediante un tema podía cambiar su apariencia.
  • Teníamos mayor control sobre cada componente.
  • Había aproximadamente 40 componentes genéricos y +200 componentes únicos.
  • El HTML tenía que importar todos los CSS o nosotros juntarlos mediante algún comando bash en consola.

A nivel componente no se pensó en el nombre de las clases, así que imagina +10 componentes con la clase .container cada uno con características diferentes… entonces el último en cargarse era el que mandaba a todos los .container, por fortuna, nos dimos cuenta a tiempo, así que agregamos un prefijo o una clase contenedora única (nombre del componente), así que con eso evitamos muchos problemas; después llegaron las metodologías, donde adoptamos BEM[ref] y nuestra vida con CSS comenzaba a ser más llevadera.

Después nos migramos a los empaquetadores (Gulp, Grunt) que nos ayudaron bastante a automatizar muchos procesos, usando ya SASS

Entonces llega la siguiente etapa, ya usando ahora sí componentes de verdad, llegó: CSS in JS

:: CSS in JS

CSS in JS nos va a servir para estructurar y abstraer CSS a nivel componente, aprovechando las bondades de JavaScript para describir estilos de una manera declarativa y sostenible. CSS in JS es un compilador JS a CSS de alto rendimiento que funciona en tiempo de ejecución y del lado del servidor.[ref]

¿CSS in JS soluciona todos los problemas? la verdad, no… pero sí trae bastantes beneficios.

Nota: Recuerda CSS in JS, NO es necesariamente la mejor solución, siempre dependerá de las necesidades que tengas en tú proyecto. Así que analiza las ventajas y desventajas de usarlo. Y de todas las formas de implementar CSS adopta la que más te beneficie.

:: Ventajas y desventajas

  • CSS in JS abstrae el modelo CSS al nivel de componente, en lugar del nivel de documento.
  • No necesitamos mantener separado los archivos CSS, ya que crearemos CSS usando JavaScript.
  • Crea un “ámbito local” por cada una de las clases del componente, pero todo de manera automática.
  • La mayoría de las librerías CSS in JS generan hojas de estilo dinámicas, insertando y eliminando reglas en tiempo de ejecución; entonces, NO se está generando CSS inline.
  • CSS in JS solo carga estilos que están actualmente en uso, mejorando el rendimiento de la aplicación

Nota: Para cada una de las librerías estaré usando create-react-app[ref], así como el componente base que mencione al principio, puedes clonar la semilla de GitHub[ref], dónde master es el proyecto base, y he creado una rama por cada librería.

vii. Styled Components[ref]

Styled-components es el resultado de la pregunta ¿Cómo se podría mejorar CSS para diseñar componentes en React?.[ref]

Los styled-components utiliza literales de plantilla (JavaScript — ES6 (Parte I)[ref]) para diseñar los componentes.

  • Las propiedades CSS se agregan como lo haríamos en una hoja de estilo h1, div, span, p, etc
  • Cuando definimos los estilos, realmente estamos creando componentes de React.
  • Cuando se renderiza el componente los styled-components genera nombres de clases únicos e inyectarán el CSS en el DOM.

:: Sintaxis

:: Ejemplo

El primer paso es instalar el paquete:

Vamos a crear el componente Welcome dentro de la carpeta src/components y lo agregamos en el componente App

— Básico

Vamos al componente Welcome e importamos styled-components

El siguiente paso es crear un styled-components :

Se lee así: Crearemos un styled-component llamado Title, que va a representar la etiqueta h1 con algunos estilos font-size, text-align, color.

Entonces, el código completo del componente Welcome queda de la siguiente manera:

Se ha creado la constante Title, que es un styled-component que a su vez es un elemento de React, por lo que dentro del componente funcional Welcome se utiliza como un componente.

— Pasando atributos al componente

La ventaja de utilizar styled-components, es de que le podemos pasar atributos y leerlas como propiedades (Recordemos que es un componente de React), con la finalidad de hacer validaciones y/o poder generar CSS dinámico.

Imagina que debemos de validar: name === 'Stranger' ? 'Color rosa' : 'Color azul'.

Donde:

  • (A) — Hacemos la validación name === 'Stranger'
  • (B) — Al atributo primary le pasamos el valor de la constante isStranger
  • (C) — Leemos las propiedades props y validamos si props.primary es true/false y asignamos color.

En la App agregamos el componente Welcome, pero, agregando el atributo name="Mauricio"

— Heredando estilos

Con styled-component, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Vamos a generar otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Podemos observar que a styled le estamos pasando todos los estilos de Button.

Entonces, completo, quedaría:

Podemos observar que ha heredado todos los estilos de Button y además ha agregado los propios (en una nueva clase).

— Cambiando el tipo de elemento

Styled-components tiene un atributo llamado as[ref], que nos va a permitir cambiar de manera sencilla y hasta dinámica el tipo de elemento.

Continuando con el ejemplo el styled-component Link actualmente es un botón button, vamos a cambiarlo a un link a:

Así de fácil podemos cambiar de elemento.

— Agregando selectores como :hover, :blur, :after, etc

Con styled-components podemos agregar los selectores como lo hacemos con SASS:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a styled-components:

:: Ejemplo completo

— Creando un tema con styled-components

Crear un tema con styled-components es bastante sencillo, ya que internamente tiene un componente llamado ThemeProvider, que hace la función de Context.

Lo primero, es importarlo en la App y agregarlo al JSX:

Creamos la paleta de colores, y la agregamos al ThemeProvider

Ahora vamos al componente Component, y en nuestros styled-components usamos las propiedades que vienen de theme :

:: Ejemplo completo

Si quieres saber más a fondo de styled-components puedes revisar la documentación[ref].

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama styled-component)

:: Ventajas y desventaja

  • Genera los prefijos de compatibilidad.
  • Con attrs podemos usar cualquier marco de CSS (bootstrap, skeleton, foundation, etc).
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Solo inyecta los estilos que se están ocupando de manera automática, esto quiere decir que los usuarios cargaran la menor cantidad de código.
  • Es fácil adaptar el estilo de un componente a un tema global.
  • Al estar todo en un solo componente, es más fácil darle mantenimiento

viii. Emotion[ref]

Emotion es una librería diseñada para escribir estilos CSS in JS, proporciona una composición de estilos predecible.[ref]

Con un núcleo totalmente renovado (funcionando con stylis.js[ref]), le da bastante potencia, agregando características como: prefijo de estilos basados en tiempo de ejecución sin necesidad de un complemento de babel, mapas de origen, etiquetado, utilidades de prueba y soporta estilos como literales de plantilla (JavaScript — ES6 (Parte I) [ref]) y objetos de JS.

  • Las propiedades CSS se agregan como lo haríamos en una hoja de estilo h1, div, span, p, etc
  • Cuando definimos los estilos, realmente estamos creando componentes normal de React.
  • Cuando se renderizan los componentes de emotion generan nombres de clases únicos e inyectan el CSS en el DOM.

:: Sintaxis

Literales de plantilla:

Objetos JS:

:: Ejemplo

El primer paso es instalar el paquete:

Vamos a crear el componente Welcome dentro de la carpeta src/components y lo agregamos en el componente App

— Básico

Vamos al componente Welcome e importamos emotion

El siguiente paso es crear un emotion-component :

Como objeto JS:

Importante: Cuando se usa en modo objeto, no debemos olvidar las propiedades deben ser en camelCase y los valores deben de ir entre comillas.

Se lee así: Crearemos un emotion-component llamado Title, que va a representar la etiqueta h1 con algunos estilos font-size, text-align, color.

Entonces, el código completo del componente Welcome queda de la siguiente manera:

En el ejemplo de arriba, podemos observar que es MUY similar a styled-components.

Dentro del componente funcional Welcome, estamos agregando el emotion-component Title

Podemos observar que el componente Title (h1) lo genera diferente a styled-components.

— Pasando atributos al componente

La ventaja de utilizar emotion, es de que le podemos pasar atributos y leerlas como propiedades (Recordemos que es un componente de React), con la finalidad de hacer validaciones y/o poder generar CSS dinámico.

Imagina que debemos de validar: name === 'Stranger' ? 'Color rosa' : 'Color azul'.

Si usamos literales de plantillas, es exactamente igual a styled-components, por lo que veremos el ejemplo con objetos de JS

Donde:

  • (A) — Hacemos la validación name === 'Stranger'
  • (B) — Al atributo primary le pasamos el valor de la constante isStranger
  • (C)— A diferencia de literales de patilla, podemos mandar las propiedades props a nivel componente, en vez de propiedad, y validar si props.primary es true/false y asignar el color.

En la App agregamos el componente Welcome, pero, agregando el atributo name="Mauricio"

— Heredando estilos

Con emotion, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Vamos a generar otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Podemos observar que a styled le estamos pasando todos los estilos de Button.

Entonces, completo, quedaría:

A diferencia de styled-components, emotion va a generar una nueva clase, donde va a encimar los nuevos valores.

— Cambiando el tipo de elemento

Emotion tiene un atributo llamado as[ref], que nos va a permitir cambiar de manera sencilla y hasta dinámica el tipo de elemento.

Continuando con el ejemplo el emotion-component Link actualmente es un botón button, vamos a cambiarlo a un link a:

— Agregando selectores como :hover, :blur, :after, etc

Con emotion podemos agregar los selectores muy parecido a como lo hacemos con SASS:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a emotion, con objetos JS:

:: Ejemplo completo

— Creando un tema con emotion

Para poder usar ThemeProvider desde emotion, debemos instalar el siguiente paquete:

El componente ThemeProvider hace la función de Context, entonces, lo importamos en la App y lo agregamos al JSX:

Creamos la paleta de colores, y la agregamos al ThemeProvider

Ahora vamos al componente Component, y en los emotions-components usamos las propiedades que vienen de theme:

:: Ejemplo completo

Si quieres saber más a fondo de emotion puedes revisar la documentación[ref].

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama emotion)

:: Ventajas y desventaja

  • Genera los prefijos de compatibilidad.
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Solo inyecta los estilos que se están ocupando de manera automática, esto quiere decir que los usuarios cargaran la menor cantidad de código.
  • Es fácil adaptar el estilo de un componente a un tema global.
  • Al estar todo en un solo componente, es más fácil darle mantenimiento
  • La documentación no es muy buena que digamos, (si comparamos con otras librerías de CSS in JS)

ix. Fela[ref]

Fela ha sido creado para manejar el estilo basado en estado de JavaScript, es dinámico por diseño y representa los estilos dependiendo del estado de la aplicación.[ref]

Una de sus principales características es la generación de CSS atómico (Atomic CSS[ref]), y además admite todas las características comunes de CSS.

:: Ejemplo

El primer paso es instalar el paquete:

Lo primero que tenemos que hacer es ir al componente App, donde le vamos a indicar que usaremos fela :

Donde:

  • createRenderer Crea un renderizador de fela, que va a representar los selectores, animaciones, estilos, y además va a almacenar todos los estilos renderizados para reutilizarlos en la aplicación.
  • RendererProviderSe utiliza para pasar el renderizador de fela a todos los componentes secundarios, es como el Context de React.

El siguiente paso es crear el componente Welcome dentro de la carpeta src/components y lo agregamos en el componente App

— Básico

Vamos al componente Welcome e importamos fela

Ahora creamos los estilos:

Importante: Cuando se usa en modo objeto, no debemos olvidar las propiedades deben ser en camelCase y los valores deben de ir entre comillas.

Vamos a utilizar FelaComponent, para crear el componente y pasarle los estilos:

— Cambiando el tipo de elemento

Fela también cuenta con el atributo as, cuando no lo asignamos, por default crea un elemento de tipo div.

Entonces, el código completo del componente Welcome queda de la siguiente manera:

También podemos crear componentes que sean más descriptivos:

Dentro del componente funcional Welcome, estamos agregando el fela-component Title

En la imagen de arriba podemos observar que genera CSS atómico (Atomic CSS[ref]), una clase por propiedad.

Podemos observar que el componente Title (h1) lo genera diferente a los otros CSS in JS.

— Pasando atributos al componente

La ventaja de utilizar fela, es de que le podemos pasar atributos y leerlas como propiedades (Recordemos que es un componente de React), con la finalidad de hacer validaciones y/o poder generar CSS dinámico.

Imagina que debemos de validar: name === 'Stranger' ? 'Clase rosa' : 'Clase azul'.

Donde:

  • (A) — Hacemos la validación name === 'Stranger'
  • (B) — Al atributo primary le pasamos el valor de la constante isStranger
  • (C)— A diferencia de literales de patilla, podemos mandar las propiedades props una sola vez, y validar si props.primary es true/false y asignar el color.

En la App agregamos el componente Welcome, pero, agregando el atributo name="Mauricio"

— Heredando estilos

Con fela, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Vamos a generar otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Le estamos asignando los estilos de button con el operador spread de ES6

Entonces, completo, quedaría:

A diferencia de los CSS in JS anteriores, fela va a generar una nueva clase por cada una de las propiedades, y las que no apliquen no las agrega.

— Agregando selectores como :hover, :blur, :after, etc

Con fela podemos agregar los selectores muy parecido a como lo hacemos con SASS:

— Simplificando los componentes con connect

Creo que una de las desventajas que tiene fela al crear elementos con FelaComponent, es de que se va volviendo más complicado de leer (basta con mirar los ejemplos que hemos hecho), por fortuna, cuenta con un componente llamado connect, este, es especialmente útil cuando queremos diseñar un gran árbol de elementos DOM primitivos.

connectEs un componente de orden superior, que tiene la capacidad de asignar clases renderizadas a los componentes por medio de la propiedad style, devolviendo un componente puro.

:: Sintaxis

Vamos a crear el ejemplo anterior desde cero:

  • Primero vamos a crear el componente Welcome, donde va a tener un botón y un link:
  • El siguiente paso es crear los estilos:

Lo único que hicimos fue pasar los estilos a una arrow function (JavaScript — Funciones [ref]).

  • El siguiente paso es importar connect, y utilizar el componente de orden superior connect, mandando los estilos rules y al componente que va a aplicar Welcome
  • El componente connect, se encarga de pasar los estilos, por medio de la propiedad styles:

El código completo quedaría así:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a fela, con objetos JS:

:: Ejemplo completo

— Creando un tema con fela

Crear un tema con fela es bastante sencillo, ya que internamente tiene un componente llamado ThemeProvider, que hace la función de Context, lo primero que necesitamos hacer es importarlo en la App y agregarlo al JSX:

Creamos la paleta de colores, y la agregamos al ThemeProvider

Ahora en el componente Component, y en la constante rules utilizamos las propiedades que vienen de theme:

:: Ejemplo completo

Si quieres saber más a fondo de fela puedes revisar la documentación[ref].

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama fela)

:: Ventajas y desventaja

  • CSS atómico de manera automática.
  • Genera los prefijos de compatibilidad.
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Solo inyecta los estilos que se están ocupando de manera automática, esto quiere decir que los usuarios cargaran la menor cantidad de código.
  • La documentación no es muy buena que digamos, (si comparamos con otras librerías de CSS in JS)
  • Soporte i18n.

x. Aphrodite[ref]

Aphrodite es un CSS-in-JS independiente del marco con soporte para renderizado del lado del servidor, prefijos del navegador y generación mínima de CSS.

Aphrodite utiliza StyleSheet para definir los estilos y en los componentes el método css, dentro de className.

  • Solo es necesario agrupar los estilos y utilizarlos en los componentes
  • Podemos combinar estilos de manera sencilla

:: Sintaxis

:: Ejemplo

El primer paso es instalar el paquete:

Vamos a crear el componente Welcome dentro de la carpeta src/components y lo agregamos en el componente App

— Básico

Vamos al componente Welcome e importamos aphrodite

Por default, aphrodite agrega a cada una de las propiedades el !important:

Si no queremos que se agregue, entonces debemos de importar aphrodite/no-important:

El siguiente paso es crear los estilos:

Agregamos los estilos al componente:

Entonces, el código completo del componente Welcome queda de la siguiente manera:

En el componente funcional Welcome, al atributo className mediante el método css se agregan los estilos.

— Pasando atributos al componente

Con aphrodite, no es necesario pasarle propiedades, podemos concatenar todos los estilos que sean necesarios.

Imagina que debemos de valida: name === 'Stranger' ? 'Color rosa' : 'Color azul'.

Donde:

  • (A) — Mediante la validación, agregamos styles.pink o styles.blue
  • (B) — Primero estamos agregando los estilos de styles.h1 , después concatenamos el estilo de la validación nameStyle.

En la App agregamos el componente Welcome, pero, agregando el atributo name="Mauricio"

Podemos observar que está usando h1_68r49 para ambos casos, pero cambia el pink_/blue_, dependiendo la validación.

— Heredando estilos

Con aphrodite, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Vamos a generar otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Para poder heredar los estilos de button , solo es necesario concatenarlos en el método css

Entonces, completo, quedaría:

— Agregando selectores como :hover, :blur, :after, etc

Con aphrodite podemos agregar los selectores:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a aphrodite:

:: Ejemplo completo

— Creando un tema con aphrodite

Por si sola aphrodite no tiene la opción para crear un tema, así que ocuparemos el paquete react-with-styles[ref].

react-with-styles es un CSS in JS para componentes en React sin estar estrechamente acoplado a una implementación[ref].

Lo primero que tenemos que hacer es instalar dos paquetes:

Donde:

  • react-with-styles: Es el paquete que nos va a permitir crear el tema.
  • react-with-styles-interface-aphrodite : La interfaz que vamos a usar, para nuestro ejemplo es aphrodite (tienen para JSS[ref], React Native[ref] y CSS[ref]).

Importante: Aún depende del paquete aphrodite

Entonces, en la App importamos WithStyleContext que hace la función de Context, y la interfaz AphroditeInterface:

WithStyleContext, necesita un objeto con dos propiedades:

  • stylesInterfaceAphroditeInterface.
  • stylesTheme — El tema a utilizar.

Entonces, creamos la paleta de colores, y la agregamos:

Ahora vamos al componente Component , y hacemos los siguientes cambios:

  • Importamos react-with-styles, y mandamos a llamar el componente de orden superior withStyles:
  • Envolvemos los estilos en una arrow function y quitamos StyleSheet, ya que internamente withStyles lo utiliza:

El export del componente vamos a cambiarlo:

¿ Recuerdan el connect de fela?, básicamente es lo mismo…

Por último (de acuerdo a la documentación[ref]), debemos de pasar por parámetros el método css que ocupamos en aphrodite, así como los estilos:

El resultado del método css es un objeto, por lo que se desestructurar el resultado dentro de los elementos con la finalidad de que los estilos se pasen mediante atributos y así aphrodite pueda aplicarlos.

El componente completo quedaría así:

:: Ejemplo completo

Si quieres saber más a fondo de aphrodite[ref] y saber más de react-with-styles[ref]

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama aphrodite)

:: Ventajas y desventaja

  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • No es tan sencillo adaptar el estilo de un componente a un tema global.
  • Funciona muy bien con y sin React
  • Respeta el orden de precedencia al especificar varios estilos
  • Inyecta solo los estilos exactos necesarios para el renderizado en el DOM.
  • Se puede usar para la representación del servidor
  • Es bastante útil si vas a crear aplicaciones con estilos estáticos, ya que es muy liviano.

xi. Styletron[ref]

Styletron es un grupo de herramientas para el diseño orientado a componentes. Se puede usar junto con JavaScript, React o cualquier otro marco.[ref]

Los styletron utiliza objetos de JS.

  • Las propiedades CSS se agregan como lo haríamos en una hoja de estilo h1, div, span, p, etc
  • Cuando definimos los estilos, realmente estamos creando componentes normal de React.
  • Cuando se renderiza el componente los styletron utiliza el patrón de Atomic CSS[ref], por lo que va a generar una clase por propiedad.

:: Sintaxis

Cuando no se le pasa propiedades:

Cuando se le pasa propiedades props:

:: Ejemplo

El primer paso es instalar el paquete:

Ir al componente App, donde le vamos a indicar que usaremos styletron :

Donde:

  • Styletron Crea un renderizador de styletron, que va a representar los selectores, animaciones, estilos, y además va a almacenar todos los estilos renderizados para reutilizarlos en la aplicación.
  • StyletronProviderSe utiliza para pasar el renderizador de styletron a todos los componentes secundarios, funciona como el Context de React.

Podemos observar que la implementación es muy parecida a fela.

El siguiente paso es crear el componente Welcome dentro de la carpeta src/components y lo agregamos en el componente App

— Básico

Vamos al componente Welcome e importamos styletron

El siguiente paso es crear un styletron-component :

Importante: Cuando se usa en modo objeto, no debemos olvidar las propiedades deben ser en camelCase y los valores deben de ir entre comillas.

Se lee así: Crearemos un styletron-component llamado Title, que va a representar la etiqueta h1 con algunos estilos font-size, text-align, color.

Entonces, el código completo del componente Welcome queda de la siguiente manera:

Dentro del componente funcional Welcome, estamos agregando el styletron-component Title

— Pasando atributos al componente

La ventaja de utilizar styletron, es de que le podemos pasar atributos y leerlas como propiedades (Recordemos que es un componente de React), con la finalidad de hacer validaciones y/o poder generar CSS dinámico.

Imagina que debemos de validar, que si name === 'Stranger' ? 'Color rosa' : 'Color azul'.

Donde:

  • (A) — Hacemos la validación name === 'Stranger'
  • (B) — Al atributo $primary le pasamos el valor de la constante isStranger
  • (C) — Leemos las propiedades props y validamos si props.$primary es true/false y asignamos color.

Importante: Todos los accesorios que comienzan con $se filtran y NO se pasan al elemento subyacente, siendo este el único propósito de $. Styletron podría incluir en la lista de todos los atributos DOM y filtrar otros accesorios, pero eso se considera un antipatrón.

En la App agregamos el componente Welcome, pero, agregando el atributo name="Mauricio"

— Heredando estilos

Con styletron, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Importamos withStyle:

Generamos otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Podemos observar que a withStyle le estamos pasando el elemento Button y le agregamos los nuevos estilos.

Entonces, completo, quedaría:

Podemos observar que ha heredado todos los estilos de Button y además los estilos propios los ha agregado en clases nuevas.

— Cambiando el tipo de elemento

Styletron tiene un atributo llamado $as[ref], que nos va a permitir cambiar de manera sencilla y hasta dinámica el tipo de elemento.

Continuando con el ejemplo el styletron-component Link actualmente es un botón button, vamos a cambiarlo a un link a:

— Agregando selectores como :hover, :blur, :after, etc

Con styletron podemos agregar los selectores:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a styletron:

:: Ejemplo completo

— Creando un tema con styletron

Para crear un ThemeProvider styletron recomienda lo siguiente:

  • Utilizar el createContext de React
  • Sobrescribir el método styled, con la finalidad de envolver el tema en toda la aplicación.
  • Utilizar el método styled personalizado

Entonces, primero vamos a crear la carpeta context, donde crearemos nuestro theme.js

El siguiente paso será crear nuestro ThemeProvider, styled personalizado, donde va a tener el nombre de context.js .

Importamos lo necesario:

Donde:

  • createStyled — Es el método que nos va a permitir hacer nuestro propio styled
  • driver y getInitialStyle son necesarios para extender nuestro styled
  • THEME el tema que creamos en el paso anterior.

Utilizamos lo que importamos:

Donde:

  • (A) — Creamos el context con React.
  • (B) — Es el encargado de crear los componentes de styletron, por lo que le está agregando el $theme y las propiedades que le pasamos a cada componente.
  • (C) — Componente que le pasamos el tema (en los CSS in JS anteriores lo hacemos directamente en la App)
  • (D) — Por último creamos nuestro propio método de styled, donde le pasamos el wrapper (B), getInitialStyle y driver

Lo siguiente, será abrir App, donde vamos a importar context, el objetivo de agregar nuestro ThemeProvider :

Abrimos el componente Component, donde vamos a utilizar el método styled personalizado (es importante quitar el styled del import de styletron-react )

El código completo, quedaría de la siguiente manera:

:: Ejemplo completo

Si quieres saber más a fondo de styletron puedes revisar la documentación[ref].

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama styletron)

:: Ventajas y desventaja

  • No necesita ninguna dependencia adicional para poder trabajar (ej. Babel)
  • Utiliza el patrón de Atomic CSS, lo cual garantiza que solo va a tener siempre lo que está usando, mejorando la carga de la aplicación y reduciendo el tamaño.
  • Genera los prefijos de compatibilidad.
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Hay que hacer un poco de código extra para adaptar el estilo de un componente a un tema global.
  • Al estar todo en un solo componente, es más fácil darle mantenimiento
  • Su documentación es sencilla y muy fácil de seguir.

xii. JSS (React-JSS)[ref]

JSS es una herramienta de creación de CSS que le permite usar JavaScript para describir estilos de manera declarativa, libre de conflictos y reutilizable. Se puede compilar en el navegador, del lado del servidor o en el momento de la compilación en Node.[ref]

react-jss utiliza createUseStyles para definir los estilos y en los componentes dentro de className para agregarlos.

  • Solo necesitamos agrupar los estilos y utilizarlos en los componentes
  • Podemos combinar estilos de manera sencilla

:: Sintaxis

:: Ejemplo

El primer paso es instalar el paquete:

Vamos a crear el componente Welcome dentro de la carpeta src/components y agregarlo al componente App

— Básico

Vamos al componente Welcome e importamos react-jss

El siguiente paso es crear los estilos:

Agregamos los estilos al componente:

Entonces, el código completo del componente Welcome queda de la siguiente manera:

Dentro del componente funcional Welcome, al atributo className estamos agregando estilos.

— Pasando atributos al componente

La ventaja de utilizar react-jss, es de que le podemos pasar propiedades, con la finalidad de hacer validaciones y/o poder generar CSS dinámico.

Imagina que debemos de validar, que si name === 'Stranger' ? 'Color rosa' : 'Color azul'.

Donde:

  • (A) — Hacemos la validación name === 'Stranger'
  • (B) — Le pasamos un objeto con la propiedad primary con el valor de isStranger
  • (C)— Leemos las propiedades props y validamos si props.primary es true/false y asignamos color.

En la App agregamos el componente Welcome, agregando el atributo name="Mauricio"

— Heredando estilos

Con react-jss, podemos crear los estilos de un componente a partir de otro; imagina que tenemos el siguiente botón:

Vamos a generar otro botón, con las características del primero, pero a su vez con nuevos estilos, sin afectar al original:

Para poder heredar los estilos de button , solo es necesario utilizar la propiedad compose[ref] dentro link: e indicarle de qué propiedad vamos a heredar, en este caso es button, pero para que react-jss pueda interpretarlo, es necesario agregarle $ , entonces quedaría así:

El componente completo:

— Agregando selectores como :hover, :blur, :after, etc

Con reat-jss podemos agregar los selectores de una manera bastante simple[ref]:

:: Ejemplo

Retomando el ejemplo base, actualmente está así:

Vamos a convertirlo de manera básica a react-jss:

:: Ejemplo completo

— Creando un tema con react-jss

Crear un tema con react-jss es bastante sencillo, ya que internamente tiene un componente llamado ThemeProvider, que hace la función de Context, lo primero que necesitamos hacer, es importarlo en la App y agregarlo al JSX:

Creamos la paleta de colores, y la agregamos al ThemeProvider

Ahora vamos al componente Component, donde usaremos el hook useTheme, que tiene react-jss :

El código completo:

:: Ejemplo completo

Si quieres saber más a fondo de react-jss puedes revisar la documentación[ref].

:: Descargar proyecto

Puedes clonar la aplicación desde GitHub[ref] (en la rama react-jss)

:: Ventajas y desventaja

  • Solo se extrae CSS de componentes renderizados.
  • Las hojas de estilo se crean cuando un componente se monta y se elimina cuando se desmonta.
  • La parte estática de una hoja de estilo se compartirá entre todos los elementos.
  • Genera los prefijos de compatibilidad.
  • Ya no debemos de preocuparnos por que los estilos vayan a chocar, o declarar el famoso y odiado !important
  • Podemos enfocarnos en crear estilos para un componente, con la seguridad de que no vamos afectar a la aplicación.
  • Soporta muy bien los pseudo selectores, pseudo elementos y las media queries.
  • Es fácil adaptar el estilo de un componente a un tema global, permite la propagación de temas basados ​​en el contexto y las actualizaciones en tiempo de ejecución.
  • Al estar todo en un solo componente, es más fácil darle mantenimiento
  • Su documentación es sencilla y muy fácil de seguir.
  • Tiene una API similar a los styled-component[ref], pero gracias al núcleo JSS, admite todas las características y complementos que JSS admite[ref]

xiii. Otros CSS-in-JS

  • Michele Bertoli, tiene un compilado de todos los CSS in JS que están actualmente[ref].
  • Otra guia para comparar CSS in JS[ref]
  • Una buena discusión de cómo seleccionar el “mejorCSS in JS[ref]
  • Un ejemplo muy atractivo, donde puedes comparar varios CSS in JS[ref]

Bibliografía y links que te puede interesar…

--

--

Responses (4)