Variables CSS y Emotion en Svelte: Mejora tus Componentes

Clase 23 de 28Curso de Frameworks y Librerías de JavaScript

Contenido del curso

Contexto y funcionamiento de los Frameworks JavaScript

Resumen

Combinar variables nativas de CSS con Emotion dentro de un proyecto Svelte permite escribir colores y valores una sola vez y reutilizarlos en cualquier componente, eliminando la repetición y manteniendo un código limpio. A continuación se explica paso a paso cómo lograrlo, desde la declaración de variables globales hasta la integración de CSS in JS con Emotion.

¿Cómo funcionan las variables nativas de CSS en Svelte?

Las variables de CSS (también llamadas custom properties) ya son una realidad en los navegadores modernos. Antes era necesario recurrir a PostCSS, un postprocesador que permite usar sintaxis de CSS del futuro en el presente [0:12]. Hoy basta con declararlas directamente.

En Svelte, los estilos se agregan dentro de la etiqueta <style> de cada componente. Para que una regla sea global y no quede encapsulada, se usa la pseudo-clase :global() seguida del selector deseado [1:24]:

css

<style> :global(body) { --bg: #1b1b2f; --color: #e43f5a; --color2: #6b4226; background: var(--bg); color: var(--color); } </style>
  • --bg almacena el color de fondo.
  • --color y --color2 guardan los colores principales.
  • Se invocan con la función var(--nombre) [2:24].

Al definirlas en el body, quedan disponibles para cualquier componente hijo sin necesidad de volver a declararlas [3:52].

¿Qué es Emotion y cómo se integra con Svelte?

Emotion es la segunda herramienta más popular de CSS in JS [0:36]. En lugar de escribir archivos .css, se crean archivos .js donde los estilos se definen como cadenas de texto con template literals y se exportan como variables.

¿Cómo instalar Emotion en el proyecto?

Desde CodeSandbox se añade como dependencia buscando @emotion/css; en terminal se usa npm install @emotion/css [5:10]. Una vez instalada, se crea un archivo styles.js:

js import { css } from "@emotion/css";

export const form = css` background: var(--bg); color: var(--color2); border: 1px solid var(--color); /* demás propiedades */

&:hover { transform: scale(1.2); } `;

  • La función css recibe los estilos entre comillas invertidas (backticks), igual que en styled-components [5:52].
  • El símbolo & referencia al propio elemento, permitiendo anidar pseudo-clases como :hover [6:28].
  • Dentro de Emotion se siguen usando var(--color) para aprovechar las variables nativas [8:12].

¿Cómo conectar los estilos de Emotion con los componentes?

En el archivo .svelte se importa la variable y se pasa al atributo class entre llaves [7:08]:

svelte

<script> import { form, button } from "./styles.js"; </script> <form class={form}> <button class={button}>Enviar</button> </form>

Emotion genera automáticamente una clase CSS única que encapsula los estilos. No es necesario mantener la etiqueta <style> del componente para esas reglas; pueden eliminarse sin que la aplicación se rompa [7:30].

¿Cómo aplicar estilos al botón y al título con esta técnica?

Para el botón se exporta otra constante desde styles.js con sus estados :hover y :disabled [8:00]:

js export const button = css` background: var(--color); /* propiedades base */

&:hover { border-color: var(--color2); }

&:disabled { opacity: 0.5; } `;

Para el título se sigue el mismo patrón, añadiendo un border-bottom y padding-bottom con la variable --color2 [9:30]:

js export const title = css border-bottom: 1px solid var(--color2); padding-bottom: 10px; margin: 0; font-family: sans-serif;;

En App.svelte se importa title y se asigna al <h2> con class={title} [9:18].

Esta combinación ofrece lo mejor de ambos mundos: las variables nativas garantizan consistencia de colores sin dependencias extra, mientras que Emotion aporta la potencia de escribir estilos dinámicos directamente en JavaScript. Como reto, intenta que al pasar el mouse sobre cada película cambie el esquema de color de toda la aplicación, tal como se hizo con styled-components en React. Comparte tu solución en los comentarios.