Styled Components: Qué son y cómo se utilizan
Tags: javascript, webdev, programming, react
Published: 2022-07-22 22:39:08

Los Styled Components son una nueva forma de utilizar CSS con tus componentes en las aplicaciones frontend de hoy en día. Se trata del siguiente paso a los módulos CSS, estando el código CSS asociado únicamente al componente al que pertenece, sin afectar al resto de elementos de la página.
Qué son los Styled Components
Styled Components es una librería que te permite escribir código CSS en JavaScript del mismo modo que ocurre con otras librerías como React Style, Radium o jsxstyle.

Hace no demasiado, todo el mundo del desarrollo web se basaba en puro HTML. CSS ni siquiera existía. Y así, con tablas, marcos y poco más fue como creé mi primera web hace muchos años. Lo cierto es que de aquellas todo era muy fácil salvo el tema de la compatibilidad con diferentes navegadores. Años después surgió CSS y no tardaron mucho en aparecer los primeros frameworks como por ejemplo Foundation, Bootstrap o Bulma, para así desarrollar aplicaciones más rápido y de una forma más consistente.

A todo esto le siguieron los preprocesadores como LESS o SASS que permitían utilizar variables en sus documentos para luego compilarlos en hojas de estilos CSS óptimas.

Unos años más tarde, JavaScript se ha convertido en el estándar que se utiliza como base a la hora de desarrollar aplicaciones frontend, por lo que el código CSS debería poder asignarse, de algún modo, a los diferentes componentes de la interfaz, creados con JavaScript o alguna de sus bibliotecas, como React, Vue o Svelte. Y es aquí en donde intervienen tanto los Styled Components como otras tantas librerías ya mencionadas que tiene el mismo objetivo.

El objetivo de los Styled Componentes es el de ser el sucesor de los clásicos módulos CSS. Mediante Styled Components podrás escribir código CSS plano en tus componentes sin preocuparte de variables JavaScript propias de la librería que utilices o de posibles colisiones.

Cómo instalar Styled Components
Podrás instalar Styled Componentes tanto mediante npm como mediante yarn.

Para instalar Styled Componentes mediante npm usa el siguiente comando:
npm install styled-components
Para instalar Styled Componentes mediante yarn usa el siguiente comando:
yarn add styled-components
Una vez hayas instalado Styled Components podrás importar la librería en tu proyecto:

import styled from 'styled-components';
Cómo Utilizar Styled Components
En este apartado vamos a ver los conceptos más básicos de los Styled Componentes, que en general son los que utilizarás casi todo el tiempo. Lo primero, asegúrate de haber importado la librería en tu script. Además, en estos ejemplos utilizaremos los componentes que creemos junto con React.

Creación de un Styled Component
Para crear un Styled Components basta con que uses alguna de las propiedades del objeto styled. En el siguiente ejemplo creamos las propiedades CSS de un botón:

const Boton = styled.button`
  font-size: 1.4em;
  display: inline-block;
  background-color: #e10098;
  color: #fff;
`;
Y con esto ya tenemos un Boton, que será un componente de React en toda regla. Para ello hemos usado la función button del objeto styled, a la que hemos pasado todas las propiedades CSS mediante la misma notación que usamos en las plantillas literales o template literals, que son una forma de declarar cadenas de texto en JavaScript mediante comillas invertidas.

En concreto, hemos usado las template tags de estas plantillas, que permiten pasar el contenido de la cadena de texto a la función que tienen como prefijo. En este ejemplo, la función asociada es la función styled.button(), que recibe como parámetros tanto los elementos textuales de la cadena definida entre comillas invertidas como las posibles variables que se usen en su interior.

No solamente podrás crear botones, ya que también existen elementos input, section, div, a y toda la gama de diferentes etiquetas HTML.

Si quisieras renderizar el componente que hemos creado, bastaría con que utilizases la notación de React de toda la vida:

render(<Boton />);
Lo que usas no es otra cosa que código CSS, por lo que podrías personalizar tu botón con todo tipo de código CSS que sea válido. No existen limitaciones, por lo que si quieres también puedes anidar elementos o usar media queries:

const Boton = styled.button`
  display: block;
  background: blue;
  @media screen and (min-width: 980px) {
    display: inline-block;
  }
  &:not(:first-child) {
    background: orange;
  }
`;
Tampoco te tendrás que preocupar de los prefijos css o vendor prefixes particulares de cada navegador, ya que se agregarán automáticamente cuando compiles el código.

Usando propiedades
También puedes pasar propiedades HTML a un Styled Component. Estas propiedades se verán reflejadas en elemento del DOM en el que se monte el componente. En el siguiente ejemplo vamos a pasar las propiedades placeholder y value a un componente input:

const Input = styled.input`
 // Código
`;

render(
  <Input type="text" placeholder="Escribe algo aquí..." value="Hola, colega" />
);
Las propiedades que hemos definido se representarán como atributos HTML.

Sin embargo también podemos usar las propiedades para personalizar los componentes dependiendo de valor que tengan:

const Boton = styled.button`
  background: ${props => (props.secundario ? 'black' : 'white')};
  color: ${props => (props.secundario ? 'white' : 'black')};
`;

render(
  <div>
    <Boton>Botón con fondo blanco y letra en negro</Boton>
    <Boton secundario>Botón con fondo negro y letra en blanco</Boton>
  </div>
);
En el ejemplo anterior el color del botón cambiará en función de que la propiedad secundario esté presente o no.

Cómo extender componentes
Si has creado un componente y quieres crear otro componente similar, puedes aprovechar el código que ya tienes y extender el componente usando la propiedad extends:

const Boton = styled.button`
  background: black;
`;

const BotonBlanco= Boton.extend`
  background: white;
`;

render(
  <div>
    <Boton>Un botón negro</Boton>
    <BotonBlanco>Un botón blanco</BotonBlanco>
  </div>
);