El estilo te permite definir el aspecto de tu sitio web y crear una marca cohesiva y estética. Aunque varios enfoques utilizan Hojas de Estilo en Cascada (CSS, Cascading Style Sheets) para dar estilo a las páginas web, las soluciones basadas en JavaScript son más flexibles y te dan más control que las CSS estándar.

Un método popular es utilizar Hojas de Estilo JavaScript (JSS, JavaScript Style Sheets), que te permite escribir estilos CSS en JavaScript. JSS tiene varias ventajas, como el uso de variables, expresiones de JavaScript y funciones para crear estilos y temas dinámicos.

También aborda el estilo dinámico, la tematización y la optimización del rendimiento. Puedes utilizar JSS con muchos tipos de aplicaciones, pero en este artículo nos centraremos en JSS para React.

¿Qué es JSS?

Con JSS, puedes escribir estilos CSS como objetos JavaScript y utilizar estos objetos como nombres de clase en elementos o componentes. JSS es independiente del framework, por lo que puedes utilizarlo en vanilla JavaScript o con frameworks como React y Angular.

JSS tiene varias ventajas sobre el estilo CSS tradicional:

  • Estilización dinámica — Con JSS, puedes manipular los estilos basándote en las interacciones del usuario o en valores como props o contexto. Las funciones de JavaScript te ayudan a generar estilos dinámicamente en el navegador en función del estado de la aplicación, los datos externos o las API del navegador.
  • Capacidades de tematización mejoradas — puedes crear estilos específicos para un tema concreto utilizando JSS. Por ejemplo, puedes crear estilos para un tema claro y oscuro y luego aplicar estos estilos específicos de un tema a toda la aplicación según las preferencias del usuario. Si utilizas React, el paquete React-JSS admite la propagación de temas basada en el contexto. Puedes definir y gestionar el tema en un solo lugar antes de pasar la información del tema por el árbol de componentes utilizando un proveedor de temas.
  • Mantenimiento mejorado — Al definir estilos en objetos JavaScript, puedes agrupar estilos relacionados en una ubicación e importarlos a tu aplicación cuando sea necesario. Este enfoque reduce la duplicación de código y mejora la organización del mismo, facilitando el mantenimiento de los estilos a lo largo del tiempo.
  • CSS real — JSS genera CSS real en lugar de estilos inline que pueden ser desordenados y difíciles de gestionar. JSS utiliza nombres de clase únicos por defecto, lo que te ayuda a evitar colisiones de nombres causadas por la naturaleza global del CSS.

Cómo Escribir Estilos con JSS

Este artículo se basa en un proyecto React. Utiliza el paquete react-jss, que integra JSS con React utilizando la API Hooks. react-jss viene con los plugins por defecto y te permite utilizar JSS con una configuración mínima.

Sintaxis Básica y Uso de JSS en React

Para utilizar JSS en React, primero instala el paquete react-jss utilizando un gestor de paquetes como npm o Yarn.

La sintaxis para escribir estilos en JSS implica definir reglas CSS para elementos específicos dentro de un objeto JavaScript. Por ejemplo, el siguiente código define los estilos para un botón en una aplicación React.


const styles = {
      button: {
            padding: "10px 20px",
            background: "#f7df1e",
            textAlign: "center",
            border:"none"
      }
};

Nota: Las propiedades CSS están en camelcase.

Para aplicar estos estilos a un elemento HTML

  1. Genera las clases pasando los estilos a la función createUseStyles()</code method from react-jss:
import { createUseStyles } from "react-jss";
const styles = {
       button: {
             padding: "10px 20px",
             background: "#f7df1e",
             textAlign: "center",
             border:"none"
       }
};
const useStyles = createUseStyles(styles);
  1. Aplica el CSS al elemento botón utilizando el nombre de clase generado:
const App = () = > {
      const classes = useStyles();
      return (
            < button className={classes.button} > </button >
      );
};

Este código crea un componente React y aplica los estilos en el objeto styles.

Cómo Manejar Pseudoclases, Media Queries y Keyframes

JSS admite todas las funciones CSS existentes, incluidas las pseudoclases, las media queries y los keyframes. Utiliza la misma sintaxis que las reglas de estilo CSS normales para definir estilos para estas características.

Pseudoclases

Por ejemplo, supongamos que quieres añadir una pseudoclase hover al botón para cambiar el color de fondo cuando un usuario pase el ratón por encima. El siguiente código implementa esta pseudo-clase para que el fondo del botón se vuelva verde claro al pasar por encima:

const styles = {
      button: {
            padding: "10px 20px",
            background: "#f7df1e",
            textAlign: "center",
            border:"none",
            '&:hover': {
                  backgroundColor: 'lightgreen',
            }
     }
};

Keyframes

Del mismo modo, puedes aplicar una animación de keyframes a un componente utilizando la regla @keyframes. Por ejemplo, a continuación se muestra un objeto de estilo para un componente giratorio.

const styles = {
       '@keyframes spin': {
             '0%': {
                   transform: 'rotate(0deg)',
             },
             '100%': {
                   transform: 'rotate(360deg)',
             },
       },
       spinner: {
              width: "100px",
              height: "100px",
              backgroundColor: "lightgreen",
              animation: '$spin 1s linear infinite',
       },
}

Dentro de la función estilos, has definido una animación keyframe llamada spin utilizando la regla @keyframes. A continuación, creas una clase llamada spinner que aplica la animación utilizando la sintaxis $ para hacer referencia a la animación del keyframe.

Media Queries

Las media queries también utilizan la sintaxis CSS habitual en JSS. Por ejemplo, para cambiar el tamaño de la fuente de un botón en un tamaño de pantalla específico, utiliza los siguientes estilos:

const styles = {
      button: {
            fontSize: "12px",
            '@media (max-width: 768px)': {
                  fontSize: '34px',
            },
      }
};

Como acabas de ver, escribir estilos en JSS no es muy diferente de escribir CSS normal. Sin embargo, su ventaja es que puedes aprovechar la potencia de JavaScript para que tus estilos sean dinámicos.

Estilos Dinámicos con JSS

Estilos dinámicos significa crear estilos que cambian en respuesta a condiciones específicas. En React, los estilos pueden cambiar en función de valores como el estado, los props y el contexto del componente.

Cómo Crear Estilos Dinámicos con JSS

En JSS, puedes aplicar condicionalmente estilos a tus elementos con expresiones JavaScript para crear reglas de estilo dinámicas.

Digamos que tienes un botón que recibe una propiedad llamada bgColor. Su valor es el color de fondo del botón. Para crear una regla de estilo que cambie el color de fondo del botón en función de la propiedad, pasa las propiedades al método useStyles.

import { createUseStyles } from "react-jss"

const styles = {
      button: {
            padding: "10px 20px",
            background: props = >props.bgColor,
            textAlign: "center",
            border:"none"
      }
};
const Button = ({...props}) => {
  
      const useStyles = createUseStyles(styles);
      const classes = useStyles({...props});
      return (
            <button className={classes.button}>Button </button>
      );
};

A continuación, puedes hacer referencia a las props en el objeto estilos. El ejemplo anterior hace referencia a props.bgColor.

Puedes pasar el color de fondo que desees al renderizar el componente. El siguiente componente muestra dos componentes Button con los colores de fondo lightgreen y yellow.

export default function App() {
  return (
    <div >
      <Button bgColor="lightgreen" />
      <div style={{ marginTop: "10px" }}></div>
      <Button bgColor="yellow" />
    </div>
  );
}
Dos botones con estilo dinámico JSS
Dos botones con estilo dinámico JSS

Cada vez que reproduzcas el componente Button, puedes aplicar el estilo de fondo que desees.

También puedes cambiar los estilos en función del estado del componente. Supón que tienes un menú de navegación con varios elementos de enlace. Para resaltar el enlace de la página actual, define un valor de estado llamado isActive que controle si un elemento de enlace del menú está activo.

A continuación, puedes utilizar un operador ternario de JavaScript para comprobar el valor de isActive, estableciendo el color del enlace en azul si el estado es true y en rojo si es false.

const styles = {
      a: {
             color: ({ isActive }) => isActive ? 'blue' : 'red',
             padding: '10px',
      },
};

Ahora, los enlaces activos se vuelven azules y los inactivos rojos.

Del mismo modo, puedes crear un estilo dinámico basado en el contexto. Puedes dar estilo a un elemento, como UserContext, basándote en el valor de un contexto que almacena el estado online del usuario.

const { online } = useContext(UserContext);
const styles = {
      status: {
            background: online ? 'lightgreen' : '',
            width: '20px',
            height: '20px',
            borderRadius: "50%",
            display: online ? 'flex' : 'hidden'
      },
};

En este ejemplo, el elemento tiene un fondo verde si el usuario está conectado. Estableces la propiedad display como flex si el usuario está conectado y hidden si está desconectado.

Casos de Uso del Estilo Dinámico

El estilo dinámico es una potente característica del JSS que tiene muchos casos de uso:

  • Tematización — Puedes definir estilos basados en un objeto tema, como un tema claro y un tema oscuro, y pasarlo a los componentes como prop o valor de contexto.
  • Renderizado condicional — JSS te permite definir estilos basados en valores específicos. Puedes crear estilos que sólo se apliquen en determinadas condiciones, como cuando un botón está desactivado, un campo de texto está en estado de error, un menú de navegación lateral está abierto o cuando un usuario está conectado.
  • Diseño adaptable — Puedes utilizar estilos dinámicos en JSS para cambiar el estilo de un elemento en función de la anchura de la ventana gráfica. Por ejemplo, puedes definir un conjunto de estilos para un breakpoint específico mediante media queries y aplicarlos condicionalmente en función del tamaño de la pantalla.

Cómo Utilizar Temas con JSS

Utiliza temas para proporcionar una interfaz de usuario coherente en toda tu aplicación. Es fácil crear temas en JSS — basta con definir un objeto tema con valores de estilo globales, como colores, tipografía y espaciado. Por ejemplo

const theme = {
      colors: {
            primary: '#007bff',
            secondary: '#6c757d',
            light: '#f8f9fa',
            dark: '#343a40',
       },
       typography: {
             fontFamily: 'Helvetica, Arial, sans-serif',
             fontSize: '16px',
             fontWeight: 'normal',
       },
       spacing: {
             small: '16px',
             medium: '24px',
             large: '32px',
       },
};

Para aplicar temas a tus componentes, utiliza proveedores de contexto. La biblioteca JSS proporciona un componente ThemeProvider que puedes envolver alrededor de los componentes que necesiten acceder al tema.

El siguiente ejemplo envuelve el componente Button con el componente ThemeProvider y pasa el objeto theme como prop.

import { ThemeProvider } from "react-jss";
const App = () => (
      <ThemeProvider theme={theme}>
            <Button />
      </ThemeProvider>
)

Puedes acceder al tema en el componente Button utilizando un hook useTheme() y pasarlo al objeto useStyles. El siguiente ejemplo utiliza los estilos definidos en el objeto tema para crear un botón primario.

import { useTheme } from “react-jss”

const useStyles = createUseStyles({
  primaryButton: {
    background: ({ theme }) => theme.colors.primary,
    font: ({ theme }) => theme.typography.fontFamily,
    fontSize: ({ theme }) => theme.typography.fontSize,
    padding: ({ theme }) => theme.spacing.medium
  }
});

const Button = () => {
      const theme = useTheme()
      const classes = useStyles({theme})
      return (
            <div>
              <button className={classes.primaryButton}> Primary Button </button>
            </div>

      )
}

El botón debe parecerse a la imagen de abajo, con texto negro sobre un botón rectangular azul.

Un estilo de botón primario basado en el tema.
Un estilo de botón primario basado en el tema.

Si cambiaras alguno de los valores del objeto de tema, automáticamente se aplicarían nuevos estilos a todos los componentes envueltos con el componente ThemeProvider. Si cambias el valor del color primario a lightgreen, el color del botón también cambiará a verde claro, como en la imagen siguiente.

El color primario de un botón se adapta al tema.
El color primario de un botón se adapta al tema.

Aquí tienes algunas pautas a seguir cuando crees temas:

  • Define el objeto tema en un archivo independiente para mantener el código organizado y facilitar su mantenimiento.
  • Utiliza nombres descriptivos para los valores de estilo para que el objeto tema sea fácil de leer y actualizar.
  • Utiliza variables CSS para definir valores que utilices a menudo en todo tu CSS.
  • Crea valores por defecto para todas las propiedades de estilo para mantener un diseño coherente en toda tu aplicación.
  • Prueba a fondo tus temas para asegurarte de que funcionan según lo previsto en todos los dispositivos y navegadores.

Siguiendo estas prácticas recomendadas, crearás un tema sencillo de utilizar y fácil de actualizar a medida que crezca tu aplicación.

Rendimiento y Optimización

JSS es una solución de estilos de alto rendimiento. Con JSS, sólo se añaden al Modelo de Objetos del Documento (DOM, Document Object Model) los estilos utilizados actualmente en pantalla, lo que reduce el tamaño del DOM y acelera la renderización. JSS también almacena en caché los estilos renderizados, lo que significa que JSS compila el CSS sólo una vez, mejorando aún más el rendimiento.

Puedes aprovechar otras optimizaciones de rendimiento utilizando el paquete react-jss en lugar del paquete JSS paquete principal. Por ejemplo, react-jss elimina las hojas de estilo cuando se desmonta el componente. También gestiona la extracción crítica de CSS y sólo extrae estilos de los componentes renderizados. Así es como el paquete react-jss reduce el tamaño del paquete CSS y mejora los tiempos de carga.

Para reducir aún más el tamaño del paquete CSS, utiliza la división del código para cargar sólo el CSS que necesita una página o componente concretos. Una biblioteca como loadable-components puede simplificar la división del código.

JSS también te permite generar CSS del lado del servidor. Puedes agregar y encadenar el CSS adjunto utilizando la clase de registro StyleSheet de JSS, y luego enviar los componentes renderizados y la cadena CSS al cliente. Después de lanzar la aplicación, el CSS estático ya no es necesario, y puedes eliminarlo, reduciendo el tamaño del paquete.

Resumen

Has aprendido los conceptos básicos de la sintaxis JSS, cómo crear y aplicar objetos de estilo a los componentes, y cómo crear estilos dinámicos. También sabes cómo utilizar el componente ThemeProvider para aplicar temas y mejorar el rendimiento en JSS. Ahora puedes utilizar JSS para crear estilos reutilizables, mantenibles y dinámicos que se adapten a diversas condiciones.