Introducción
Styled-components te permite escribir CSS real dentro de tus archivos JavaScript, con alcance restringido a un componente específico. Los estilos viajan junto con el componente, por lo que no hay colisiones de nombres de clase ni necesidad de buscar un archivo CSS separado cuando algo no se ve bien. Si has perdido tiempo depurando qué hoja de estilos global está sobreescribiendo a cuál, el atractivo es inmediato.
¿Por Qué Usar Styled-Components?
Estilización con Alcance
Los estilos se limitan automáticamente al componente al que pertenecen. Sin convenciones de nomenclatura BEM, sin preocupaciones por el orden de cascada entre archivos.
Estilización Dinámica
Puedes ramificar basándote en props directamente dentro del template literal. Alternar una variante ya no requiere mantener clases CSS paralelas y lógica JavaScript por separado.
Mantenibilidad Mejorada
Los estilos y el marcado viven en el mismo archivo. Cuando se elimina un componente, sus estilos se van con él. No descubres CSS huérfano un año después.
Prefijado de Vendor Automático
Styled-components aplica los prefijos de vendor automáticamente, de modo que escribes propiedades CSS estándar y él se encarga de la compatibilidad entre navegadores.
Primeros Pasos con Styled-Components
Instalación
npm install styled-components
o
yarn add styled-components
Uso Básico
Así es como se crea un componente de botón estilizado:
import React from 'react';
import styled from 'styled-components';
const Button = styled.button`
background-color: #6200ee;
color: white;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: #3700b3;
}
`;
const App = () => (
<Button>Click Me</Button>
);
export default App;
styled.button devuelve un componente React con el CSS aplicado. Lo usas como cualquier otro componente.
Estilización con Props
Styled-components te permite pasar props a los elementos estilizados para aplicar estilos de forma condicional.
const Button = styled.button`
background-color: ${props => props.primary ? '#6200ee' : '#white'};
color: ${props => props.primary ? 'white' : '#6200ee'};
padding: 10px 15px;
border: ${props => props.primary ? 'none' : '2px solid #6200ee'};
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: ${props => props.primary ? '#3700b3' : '#f2e7fe'};
}
`;
const App = () => (
<>
<Button primary>Primary Button</Button>
<Button>Secondary Button</Button>
</>
);
export default App;
Al pasar la prop primary, podemos alternar los estilos del botón de forma dinámica.
Extendiendo Styled Components
Puedes crear nuevos styled components extendiendo los existentes:
const OutlineButton = styled(Button)`
background-color: transparent;
color: #6200ee;
border: 2px solid #6200ee;
&:hover {
background-color: #f2e7fe;
}
`;
OutlineButton hereda todo de Button y añade sus propias sobreescrituras.
Temas con Styled-Components
Para design tokens consistentes en un árbol de componentes grande, usa ThemeProvider.
import { ThemeProvider } from 'styled-components';
const theme = {
primary: '#6200ee',
secondary: '#03dac6',
};
const Button = styled.button`
background-color: ${props => props.theme.primary};
color: white;
padding: 10px 15px;
`;
const App = () => (
<ThemeProvider theme={theme}>
<Button>Themed Button</Button>
</ThemeProvider>
);
Actualiza el objeto de tema en un solo lugar y todos los componentes que usan props.theme recogen el cambio.
Creando una Aplicación de Ejemplo Completa
Aquí hay una aplicación básica de tareas que demuestra cómo encajan estas piezas.
Configurando el Proyecto
npx create-react-app styled-components-todo
cd styled-components-todo
npm install styled-components
Estructurando el App
Tres componentes:
App: el componente principal y contenedor de estado.TodoList: renderiza la lista de tareas.TodoForm: formulario para agregar nuevas tareas.
Componente App
// src/App.js
import React, { useState } from 'react';
import styled from 'styled-components';
import TodoForm from './TodoForm';
import TodoList from './TodoList';
const Container = styled.div`
max-width: 500px;
margin: 50px auto;
padding: 20px;
background-color: #f2e7fe;
border-radius: 10px;
`;
const Title = styled.h1`
text-align: center;
color: #6200ee;
`;
const App = () => {
const [todos, setTodos] = useState([]);
const addTodo = text => {
const newTodos = [...todos, { text }];
setTodos(newTodos);
};
return (
<Container>
<Title>Styled Components To-Do App</Title>
<TodoForm addTodo={addTodo} />
<TodoList todos={todos} />
</Container>
);
};
export default App;
Componente TodoForm
// src/TodoForm.js
import React, { useState } from 'react';
import styled from 'styled-components';
const Form = styled.form`
display: flex;
margin-bottom: 20px;
`;
const Input = styled.input`
flex: 1;
padding: 10px;
border: 2px solid #6200ee;
border-radius: 5px;
margin-right: 10px;
font-size: 16px;
`;
const Button = styled.button`
background-color: #6200ee;
color: white;
padding: 0 20px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
&:hover {
background-color: #3700b3;
}
`;
const TodoForm = ({ addTodo }) => {
const [value, setValue] = useState('');
const handleSubmit = event => {
event.preventDefault();
if (!value) return;
addTodo(value);
setValue('');
};
return (
<Form onSubmit={handleSubmit}>
<Input
type="text"
placeholder="Add a new task"
value={value}
onChange={e => setValue(e.target.value)}
/>
<Button type="submit">Add</Button>
</Form>
);
};
export default TodoForm;
Componente TodoList
// src/TodoList.js
import React from 'react';
import styled from 'styled-components';
const List = styled.ul`
list-style: none;
padding-left: 0;
`;
const ListItem = styled.li`
background-color: white;
padding: 15px 20px;
border-bottom: 1px solid #ddd;
&:nth-child(even) {
background-color: #fafafa;
}
`;
const TodoList = ({ todos }) => (
<List>
{todos.map((todo, index) => (
<ListItem key={index}>{todo.text}</ListItem>
))}
</List>
);
export default TodoList;
Ejecutando la Aplicación
npm start
Navega a http://localhost:3000 para interactuar con tu app de tareas estilizada.
Conclusión
Styled-components es una opción práctica cuando quieres que los estilos y los componentes permanezcan sincronizados. El CSS con alcance restringido significa que no hay sobreescrituras inesperadas, la estilización basada en props reemplaza la lógica de clases condicionales, y los temas mantienen los design tokens consistentes sin variables CSS dispersas por múltiples archivos.
La contrapartida es el tamaño del bundle y el costo de runtime adicional para generar nombres de clase. Para la mayoría de las aplicaciones React esa compensación vale la pena, pero conviene hacer benchmarks si trabajas en un contexto sensible al rendimiento.
Consejos Adicionales
- Usa
createGlobalStylepara resets de base e importaciones de fuentes que deben aplicarse a todo el documento. - Al añadir styled-components a un proyecto existente, migra un componente a la vez en lugar de hacer una reescritura completa.
- El plugin Babel de styled-components mejora la legibilidad de los nombres de clase en DevTools y vale la pena añadirlo a cualquier proyecto no trivial.
Lectura Adicional
- Documentación Oficial de Styled-Components
- Temas con Styled-Components
- CSS-in-JS vs. CSS Tradicional