Original article: How to Style Your React App – 5 Ways to Write CSS in 2021

Cuando se trata de agregar estilos a una aplicación de React, existen diferentes maneras de hacerlo. ¿Cuál eliges tú?

He desglosado las 5 principales formas, entre las que debe elegir al escribir css.

No hay una única manera de agregar estilos a cada aplicación de React. Cada proyecto es diferente. Es por eso que al final de cada sección, abordaré las ventajas y desventajas de cada una para ayudarte a elegir la opción que mejor se adapte a tus proyectos.

¡Empecemos!

Lo que estaremos codificando

Para ver como cada código de CSS es diferente, crearemos el mismo ejemplo: una tarjeta testimonial simple, pero limpia.

image-2
¿Quieres desarrollar cada uno de estos ejemplos? Puedes ir a react.new para crear una nueva aplicacion de React instantáneamente✨.

Estilos en línea

Los estilos en línea es una de las maneras directas de dar estilo a cualquier aplicación de React.

Agregar estilos de esta manera no requiere crear una hoja de estilos (CSS) por separado.

Esta forma de aplicar los estilos directamente a los elementos, es de alguna manera similar a tener una hoja de estilos, debido a que también tiene mayor prioridad. Esto significa que "anulan" otras reglas de estilos que pueden ser aplicadas a un elemento.

Aquí esta nuestra carta testimonial con sus estilos en línea:

export default function App() {
  return (
    <section
      style={{
        fontFamily: '-apple-system',
        fontSize: "1rem",
        fontWeight: 1.5,
        lineHeight: 1.5,
        color: "#292b2c",
        backgroundColor: "#fff",
        padding: "0 2em"
      }}
    >
      <div
        style={{
          textAlign: "center",
          maxWidth: "950px",
          margin: "0 auto",
          border: "1px solid #e6e6e6",
          padding: "40px 25px",
          marginTop: "50px"
        }}
      >
        <img
          src="https://randomuser.me/api/portraits/women/48.jpg"
          alt="Tammy Stevens"
          style={{
            margin: "-90px auto 30px",
            width: "100px",
            borderRadius: "50%",
            objectFit: "cover",
            marginBottom: "0"
          }}
        />
        <div>
          <p
            style={{
              lineHeight: 1.5,
              fontWeight: 300,
              marginBottom: "25px",
              fontSize: "1.375rem"
            }}
          >
            ¡Este es uno de los mejores blogs de desarrolladores del planeta!
             Lo leo a diario para mejorar mis habilidades.
          </p>
        </div>
        <p
          style={{
            marginBottom: "0",
            fontWeight: 600,
            fontSize: "1rem"
          }}
        >
          Tammy Stevens
          <span style={{ fontWeight: 400 }}> · Desarrolladora frontend</span>
        </p>
      </div>
    </section>
  );
}

A pesar de algunos beneficios rápidos, los estilos en línea son solo una opción aceptable para aplicaciones muy pequeñas. Las dificultades con esto son evidentes a medida que su aplicación crece.

Como muestra el código anterior, incluso un componente pequeño se convierte en uno grande si los estilos son en línea.

Sin embargo, un truco fácil y rápido de implementar es poner estilos en línea en variables reutilizables, que se pueden almacenar en un archivo diferente.

const estilos = {
  seccion: {
    fontFamily: "-apple-system",
    fontSize: "1rem",
    fontWeight: 1.5,
    lineHeight: 1.5,
    color: "#292b2c",
    backgroundColor: "#fff",
    padding: "0 2em"
  },
  contenedor: {
    textAlign: "center",
    maxWidth: "950px",
    margin: "0 auto",
    border: "1px solid #e6e6e6",
    padding: "40px 25px",
    marginTop: "50px"
  },
  avatar: {
    margin: "-90px auto 30px",
    width: "100px",
    borderRadius: "50%",
    objectFit: "cover",
    marginBottom: "0"
  },
  cita: {
    lineHeight: 1.5,
    fontWeight: 300,
    marginBottom: "25px",
    fontSize: "1.375rem"
  },
  nombre: {
    marginBottom: "0",
    fontWeight: 600,
    fontSize: "1rem"
  },
  posicion: { fontWeight: 400 }
};

export default function App() {
  return (
    <section style={estilos.seccion}>
      <div style={estilos.contenedor}>
        <img
          src="https://randomuser.me/api/portraits/women/48.jpg"
          alt="Tammy Stevens"
          style={estilos.avatar}
        />
        <div>
          <p style={estilos.cita}>
            ¡Este es uno de los mejores blogs de desarrolladores del planeta!
             Lo leo a diario para mejorar mis habilidades.
          </p>
        </div>
        <p style={estilos.nombre}>
          Tammy Stevens
          <span style={estilos.posicion}>·Desarrolladora frontend</span>
        </p>
      </div>
    </section>
  );
}

A pesar de esta mejora, los estilos en línea no tienen un número esencial de características que cualquier hoja de estilo CSS simple podría proporcionar

Por ejemplo, no puedes escribir animaciones, estilos para elementos anidados (todos los elementos hijos, primer hijo, último hijo), pseudoclases (como :hover), y pseudo elementos (::first-line), por nombrar algunos.

Si estás creando un prototipo de aplicación, los estilos en linea son una buena opción. Sin embargo, a medida que avanzas en el desarrollo de este, necesitarás cambiar de opción para obtener las funciones básicas de CSS.

? Ventajas:

  • La forma más rápida de escribir estilos.
  • Bueno para crear aplicaciones pequeñas (escriba estilos en línea y luego muévase a una hoja de estilos).
  • Tiene una gran preferencia (puede anular estilos de una hoja de estilo CSS).

? Desventajas:

  • Es tedioso convertir CSS plano a estilos en linea.
  • Un montón de estilos en línea hacen que JSX (React) sea ilegible.
  • No puedes usar características básicas de CSS como animaciones, selectores,etc
  • No escala bien

CSS simple

En lugar de usar estilos en línea, es más común importar hojas de estilo CSS.

Escribir en una hoja de estilos CSS es probablemente el enfoque mas básico de agregar estilos a nuestra aplicacion de React, pero no debe descartarse fácilmente.

Los estilos en CSS plano están mejorando todo el tiempo, debido al aumento de características disponibles en el estándar.

Esto incluye características como variables para guardar valores dinámicos, todo tipo de selectores avanzados para seleccionar elementos con precisión, y nuevas pseudoclasses como :is and :where .

Aquí esta nuestra carta testimonial escrito en CSS plano importado en la parte superior de nuestra aplicación de React:

/* src/estilos.css */

body {
  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  margin: 0;
  font-size: 1rem;
  font-weight: 1.5;
  line-height: 1.5;
  color: #292b2c;
  background-color: #fff;
}
.testimonial {
  margin: 0 auto;
  padding: 0 2em;
}
.testimonial-contenedor {
  text-align: center;
  max-width: 950px;
  margin: 0 auto;
  border: 1px solid #e6e6e6;
  padding: 40px 25px;
  margin-top: 50px;
}
.testimonial-cita p {
  line-height: 1.5;
  font-weight: 300;
  margin-bottom: 25px;
  font-size: 1.375rem;
}
.testimonial-avatar {
  margin: -90px auto 30px;
  width: 100px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: 0;
}
.testimonial-nombre {
  margin-bottom: 0;
  font-weight: 600;
  font-size: 1rem;
}
.testimonial-nombre span {
  font-weight: 400;
}
// src/App.js

import "./estilos.css";

export default function App() {
  return (
    <section className="testimonial">
      <div className="testimonial-contenedor">
        <img
          className="testimonial-avatar"
          src="https://randomuser.me/api/portraits/women/48.jpg"
          alt="Tammy Stevens"
        />
        <div className="testimonial-cita">
          <p>
            ¡Este es uno de los mejores blogs de desarrolladores del planet!
             Lo leo a diario para mejorar mis habilidades.
          </p>
        </div>
        <p className="testimonial-nombre">
          Tammy Stevens<span>· Desarrolladora frontend</span>
        </p>
      </div>
    </section>
  );
}

Para nuestra carta testimonial,  nota que estamos creando clases que son aplicadas a cada elemento individual. Todas estas clases comienzan con el mismo nombre testimonial-.

CSS escrito en una hoja de estilos es una excelente primera opción para su aplicación. A diferencia de los estilos en línea, puede diseñar su aplicación de cualquier forma que necesite.

Un problema menor podría ser su convención de nomenclatura. Una vez que tenga una aplicación grande, se vuelve más dificil pensar en nombres de clase únicos para sus elementos, especialmente cuando tienes 5 divs envueltos uno dentro de otro.

Si no tiene una convención de nomenclatura en la que confíe (por ejemplo: BEM), puede ser más fácil cometer errores, además de crear varias clases con el mismo nombre, lo que genera conflictos.

Adicionalmente, escribir CSS normal puede ser verboso y repetitivo que herramientas más nuevas como SASS/SCSS. Como resultado, esto puede tomar un poco más de tiempo escribir sus estilos en CSS en comparación a estas o una librería de CSS en Javascript.

Además, es importante tener en cuenta que CSS se aplica en cascada a todos los elementos secundarios, si tú aplicas una hoja de estilos CSS a un componente no solo se limita a este.

Si tienes confianza con CSS, es definitivamente una opción viable.

Con eso dicho, existe una serie de librerias de CSS que nos brindan todo el poder de CSS con menos código e incluidas algunas características que CSS nunca tendría por si solo (como limitar los estilos y prefijos CSS del navegador).

? Ventajas:

  • Nos da todas las herramientas modernas de CSS (variables, selectores avanzados, nuevas pseudoclases, etc).
  • Ayuda a mantener limpio nuestros componentes de estilos en línea.

? Desventajas:

  • Necesita configurar los prefijos de navegador para asegurar que las funciones más recientes funcionen para todos los ususarios.
  • Requiere escribir más y a veces código repetitivo que otras librerías de CSS (SASS).
  • Cualquier hoja de estilo en cascada importada a un componente, afecta támbien a sus componentes hijos, no está limitado al componente.
  • Debe usar una convención de nomenclatura confiable para garantizar que los estilos no entren en conflicto.

SASS / SCSS

¿Qué es SASS? SASS es un acrónimo que significa: Syntactically Awesome Style Sheets u Hojas de estilo sintácticamente asombrosas.

SASS nos brinda poderosas herramientas, algunas de las cuales no existen en una hoja de estilos CSS normal. Esto incluye características como variables, estilos extendidos y anidamiento.

Screen-Shot-2021-07-14-at-12.36.47-PM

SASS nos permite escribir estilos en dos tipos diferentes de hoja de estilos, con las extensiones .scss y .sass.

Los estilos SCSS están escritos en una sintaxis similar a CSS normal, sin embargo los estilos de SASS no requieren usar llaves de apertura ( { ) y cierre ( } ) .

Aquí hay un rápido ejemplo de una hoja de estilos SCSS con algunos estilos anidados:

/* estilos.scss */

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

Compara este ejemplo con el mismo codigo escrito en SASS:

/* estilos.sass */

nav
  ul
    margin: 0
    padding: 0
    list-style: none

  li
    display: inline-block

  a
    display: block
    padding: 6px 12px
    text-decoration: none

Dado que esto no es CSS normal, debe compilarse a CSS plano. Para hacer esto en nuestras aplicaciones de React, puedes usar una librería como node-sass.

Si estás usando un proyecto creado con create-react-app, y quieres usar SASS o SCSS, puedes instalar node-sass con npm:

npm install node-sass

Aquí está nuestra carta testimonial hecha con SCSS:

/* src/estilos.scss */

$fuentes: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
$color-texto: #292b2c;

%fuente-basica {
  font-size: 1rem;
}

body {
  @extend %fuente-basica;
  font-family: $fuentes;
  color: $color-texto;
  margin: 0;
  font-size: 1rem;
  font-weight: 1.5;
  line-height: 1.5;
  background-color: #fff;
}

/* reglas sin cambio omitidas */

.testimonial-nombre {
  @extend %fuente-basica;
  margin-bottom: 0;
  font-weight: 600;

  span {
    font-weight: 400;
  }
}

Estos estilos nos dan las siguientes características: variables, estilos extendidos y anidamiento.

Variables: Puedes usar valores dinámicos escribiendo variables, justo como en Javascript, declarándolos con  $  al principio.

Aquí tenemos dos variables que pueden ser usados en múltiples reglas $fuentes, $color-texto.

Extendiendo / Herencia:  Puedes agregar reglas de estilos extendiéndolas. Para hacer esto, tienes que crear tu propio selector el cual puede ser reutilizado como variable. El nombre de las reglas que quieres extender debe comenzar con  %.

La variable %fuente-basica es heredada por las reglas  body  y  .testimonial-nombre.

Anidamiento: En lugar de escribir multiples reglas que comiencen con el mismo selector, puedes anidarlas.

En  .testimonial-nombre, usamos un selector de anidamiento para apuntar al elemento span dentro de él.

Puedes encontrar una versión de una aplicación de React con SCSS aquí

? Ventajas:

  • Incluye muchas características dinámicas de CSS como el poder de extender las reglas, anidamiento, y mixins.
  • Los estilos con SCSS son mucho menos repetitivos que CSS normal.

? Desventajas:

  • Similar a CSS plano, los estilos son globales y no se limitan a un componente.
  • Las hojas de estilos CSS están comenzando a incluir un número de características que SASS tenía exclusivamente, como variables por ejemplo.
  • SASS / SCSS con frecuencia requieren una configuración, como instalar la librería de Node node-sass.

Módulos de CSS

Los módulos de CSS son otra alternativa ligera a algo como CSS o SASS

Lo bueno de los módulos de CSS es que pueden ser usado con CSS normal o SASS. Además, si está usando Create React App puede comenzar usando módulos de CSS sin ninguna configuración.

Aquí está nuestra aplicación escrita con módulos de CSS:

/* src/estilos.module.css */

body {
  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  margin: 0;
  font-size: 1rem;
  font-weight: 1.5;
  line-height: 1.5;
  color: #292b2c;
  background-color: #fff;
}

/* estilos excluidos */

.testimonial-nombre span {
  font-weight: 400;
}
import estilos from './estilos.module.css';

export default function App() {
  return (
    <section className={estilos.testimonial}>
      <div className={estilos['testimonial-contenedor']}>
        <img
          src="https://randomuser.me/api/portraits/women/48.jpg"
          alt="Tammy Stevens"
          className={estilos['testimonial-avatar']}
        />
        <div>
          <p className={estilos['testimonial-cita']}>
            ¡Este es uno de los mejores blogs de desarrolladores del planeta!
             Lo leo a diario para mejorar mis habilidades.
          </p>
        </div>
        <p className={estilos['testimonial-name']}>
          Tammy Stevens
          <span> · Desarrolladora Frontend</span>
        </p>
      </div>
    </section>
  );
}

Nuestro archivo CSS tiene el nombre .module antes de la extensión  .css . Cualquier módulo de CSS debe incluir ".module" en el nombre del archivo y terminar con la extensión apropiada (si estamos usando CSS o SASS/SCSS).

Lo que es interesante notar si miramos el código anterior, es que los módulos de CSS  están escrito como CSS normal, pero son importados y usados como si fueran como objetos (estilos en línea).

El beneficio de los módulos de CSS es que ayuda a evitar problemas con los conflictos de nombres de clases que tiene CSS. Las propiedades que estamos referenciando se convierten en nombres de clase únicas que no pueden entrar en conflicto entre sí.

Nuestros elementos HTML generados se verán así:

<p class="_estilos__testimonial-nombre_309571057">
  Tammy Stevens
</p>

Además, modulos de CSS resuelven el problema del alcance global de CSS. Comparado con nuestra hoja de estilos CSS normal, el CSS usando módulos para componentes individuales no afectará en cascada a los componentes hijos.

Por lo tanto, los módulos de CSS son mejores para usar que CSS normal o SASS para asegurarte de que los nombres de clases no entren en conflicto, y  escribir estilos predecibles que solo sean aplicados a uno u otro componente.

? Ventajas:

  • Los estilos tienen un alcance a uno u otro componente específico (a diferencia de CSS / SASS).
  • Único, genera nombres de clases que aseguran no entrar en conflicto.
  • Pueden ser usados inmediatamanete sin configuración en proyectos CRA.
  • Pueden ser usados con SASS / CSS

? Desventajas:

  • Puede ser complicado hacer referencias a nombres de clases.
  • Puede ser complicado usar estilos CSS como propiedades de objetos.

CSS en Javascript

Similar a como React nos permite escribir HTML con Javascript con JSX, CSS en Js ha hecho algo similar con CSS.

CSS en JS nos permite escribir estilos CSS directamente en los acrhivos (.js) de nuestros componentes.

No solo permite escribir CSS sin tener un solo archivo .css, si no que estos estilos se limitan a componentes individuales.

En otras palabras, puedes agregar, cambiar o remover estilos de CSS sin sorpresas. Cambiar los estilos de un componente no afectará a los estilos del resto de tu aplicación.

CSS en JS cons frecuencia hace uso de un tipo especial de funcion de javascript llamada un literal de plantilla etiquetada. !Lo bueno de esto es que podemos escribir estilos de CSS directamente en nuestro archivo JS¡.

Aquí hay un ejemplo rapido de una librería popular de CSS en JS, Styled Components:

import styled from "styled-components";

const Boton = styled.button`
  color: limegreen;
  border: 2px solid limegreen;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;

  &:hover {
    opacity: 0.9;
  }
`;

export default function App() {
  return (
    <div>
      <Boton>Click me</Boton>
    </div>
  );
}
Screen-Shot-2021-07-14-at-11.18.06-AM

Tenga en cuenta algunas cosas aquí:

  1. Puedes escribir estilos de CSS normal, pero puede incluir anidamiento de estilos y pseudoclases (como :hover).
  2. Puedes asociar estilos a cualquier elemento HTML válido, como el elemento "button" de arriba ( styled.button).
  3. Puedes crear nuevos componentes con estos estilos asociados. Vea como Boton es usado en nuestro componente App.

Ya que es un componente, ¿podemos pasarle parámetros? !Sí ¡ Podemos exportar este componente y usarlo donde sea requerido, además de darle características dinámicas a travéz de parámetros.

Digamos que desea una variante del botón de arriba con un fondo y texto opuestos. No hay problema.

Pasemos el parámetro opuesto a un segundo botón. En el componente Boton puede acceder a todos los parámetros pasados usando ${} con una función interna.

import styled from "styled-components";

const Boton = styled.button`
  background: ${props => props.opuesto ? "limegreen" : "white"};
  color: ${props => props.opuesto ? "white" : "limegreen"};
  border: 2px solid limegreen;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;

  &:hover {
    opacity: 0.9;
  }
`;

export default function App() {
  return (
    <div>
      <Button>Click me</Button>
      <Button opuesto>Click me</Button>
    </div>
  );
}

En el retorno de la función, puedes seleccionar el parámetro opuesto  y usar el operador ternario para determinar el color de fondo y del texto, condicionalmente.

Este es el resultado:

Screen-Shot-2021-07-14-at-11.31.52-AM

Hay muchos más beneficios al usar una libreria de CSS en JS para agregar estilos a tus aplicaciones de React (demasiados para cubrirlos aquí), algunos de los cuales enumeraré a continuación.

Asegúrese de revisar las dos más populares librerias de CSS en JS for React: Emotion y Styled Components.

Un incoveniente de usar librerías de CSS en JS es añadir una librería adicional a tu proyecto. Sin embargo, diría que esto vale la pena pues mejora la experiencia de desarrollo de sus aplicaciones de React en lugar de CSS normal.

? Ventajas:

  • Los estilos se limitan a componentes individuales.
  • Ya que su CSS es ahora JS, puede exportar, reutilizar, e incluso extender sus estilos a travez de parámetros.
  • Librerías de CSS en JS evitan los conflictos generando un nombre de clase único para sus estilos.
  • No necesita enfocarse en usar convenciones de nomenclatura para sus clases !solo en escribir los estilos¡.

? Desventajas:

  • A diferencia de CSS normal, necesitará instalar uno o más librerías de terceros, lo cual añade mayor tamaño a su proyecto.

Conclusión

Tenga en cuenta que no incluí librerías de componentes en los ejemplos. Quería enfocarme principalmente en las diferentes formas en las que puede agregar estilos.

Tenga en cuenta que elegir una librería con componentes y estilos prefabricados como Material UI o Ant Design (por nombrar un par) es una opción totalmente válida para su proyecto.

Espero que esta guía le haya ayudado a comprender mejor como agregar estilos a sus aplicaciones de React, y que enfoque elegir para sus próximos proyectos.

¿Quiere saber más? Únase a El Bootcamp de React

El Bootcamp de React toma todo lo que debería saber sobre el aprendizaje de React y lo agrupa en un paquete completo, incluido videos y bonificaciones especiales.

Obten información privilegiada que cientos de desarrolladores ya han utilizado para dominar React, encontrar el trabajo de sus sueños, y tomar control de su futuro:

The React Bootcamp