Organizar el CSS: reset y BEM
En esta lección
Escribir CSS que funcione es fácil. Escribir CSS que siga funcionando cuando el proyecto tiene veinte páginas, tres personas tocándolo y seis meses de cambios es otra historia. En esta lección verás cómo empezar con un reset moderno, cómo ordenar un archivo CSS, cómo nombrar las clases con la metodología BEM y qué herramientas usan los profesionales para escribir, optimizar y depurar sus estilos.
Por qué hace falta organizar el CSS
CSS no avisa de errores. Si escribes una regla que choca con otra, simplemente gana una de las dos (por la cascada y la especificidad) y la otra se ignora en silencio. Con un archivo pequeño lo controlas; con uno de 3000 líneas empiezan los problemas típicos:
- Cambias el color de un botón y se rompe otro en una página distinta.
- No te atreves a borrar reglas porque no sabes si se usan.
- Acabas escribiendo
!importantpara “forzar” que algo funcione.
Casi todo se evita con tres ideas: un punto de partida común (el reset), un orden fijo y nombres de clase predecibles.
Un reset moderno, regla a regla
Cada navegador aplica sus propios estilos por defecto: márgenes en los párrafos y títulos, box-sizing: content-box, imágenes en línea… Un reset los neutraliza para que partas de una base igual en todos. Hoy no se borra todo como hace años, sino solo lo que molesta. Este es un reset moderno, pequeño y razonable:
/* 1 */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* 2 */
* {
margin: 0;
}
/* 3 */
body {
min-height: 100dvh;
line-height: 1.5;
}
/* 4 */
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
/* 5 */
input,
button,
textarea,
select {
font: inherit;
}
/* 6 */
p,
h1,
h2,
h3 {
overflow-wrap: break-word;
}
/* 7 */
h1,
h2,
h3 {
text-wrap: balance;
}
Qué hace cada regla y por qué:
box-sizing: border-boxen todo, incluidos los pseudoelementos. Elwidthincluye el padding y el borde, así que una caja dewidth: 300pxmide 300px, no 340px. Lo viste en Modelo de caja.margin: 0en todo. Quita los márgenes por defecto de títulos, párrafos, listas ybody. A partir de ahí, tú decides cada margen.bodya toda la altura (100dvhtiene en cuenta la barra del navegador en móvil) y un interlineado de 1.5, más cómodo de leer que el que trae el navegador (en torno a 1.2).- Imágenes y vídeos como bloque y nunca más anchos que su contenedor.
display: blockelimina un pequeño hueco que aparece debajo de las imágenes por ser elementos en línea. - Los controles de formulario heredan la fuente. Por defecto,
inputybuttonusan una fuente del sistema y un tamaño más pequeño que el resto de la página. Confont: inheritse integran. overflow-wrap: break-wordparte las palabras larguísimas (una URL, un correo) en lugar de desbordar la caja en el móvil.text-wrap: balancereparte las palabras de los títulos entre las líneas para que no quede una palabra sola en la última.
Consejo: no uses resets que borran todo (listas sin viñetas,
font-size: 100%en cada etiqueta…). Luego tienes que volver a escribir lo que ya estaba bien.
El orden de un archivo CSS
Un archivo ordenado se lee de lo general a lo particular. Es el mismo orden que sigue la cascada: lo que va después y es más específico sobrescribe a lo anterior. Un esquema muy habitual:
/* ==========================================================
1. VARIABLES
========================================================== */
:root {
--color-primario: #2d6cdf;
--color-fondo: #ffffff;
--fuente-base: system-ui, sans-serif;
--espacio: 1rem;
}
/* ==========================================================
2. RESET Y BASE (etiquetas sin clases)
========================================================== */
/* ...el reset de arriba... */
body { font-family: var(--fuente-base); }
a { color: var(--color-primario); }
/* ==========================================================
3. LAYOUT (el esqueleto de la página)
========================================================== */
.contenedor { width: min(100% - 32px, 1100px); margin-inline: auto; }
.cabecera { display: flex; justify-content: space-between; }
/* ==========================================================
4. COMPONENTES
========================================================== */
.boton { /* ... */ }
.tarjeta { /* ... */ }
/* ==========================================================
5. UTILIDADES
========================================================== */
.oculto { display: none; }
.texto-centrado { text-align: center; }
- Variables: colores, fuentes y espacios en un solo sitio. Cambiar el color de la marca es tocar una línea. Lo tienes en Variables CSS.
- Base: estilos de etiquetas (
body,a,h1) que afectan a toda la web. - Layout: las grandes zonas, normalmente con Flexbox y Grid.
- Componentes: piezas reutilizables (botones, tarjetas, formularios).
- Utilidades: clases pequeñas de una sola tarea. Van al final para que ganen a los componentes.
Dentro de cada componente, pon sus media queries justo debajo (o anidadas, como viste en CSS moderno), no todas juntas al final del archivo: así, lo que afecta a una pieza está en un solo sitio.
BEM: bloque, elemento y modificador
BEM es una convención para nombrar clases. No es una librería ni hay que instalar nada: son unas reglas de nombres. Divide la interfaz en tres tipos de piezas:
| Pieza | Qué es | Forma | Ejemplo |
|---|---|---|---|
| Bloque | Un componente independiente | bloque | .tarjeta |
| Elemento | Una parte del bloque que no tiene sentido fuera de él | bloque__elemento | .tarjeta__titulo |
| Modificador | Una variante o estado | bloque--modificador | .tarjeta--destacada |
Un ejemplo con el menú de una biblioteca:
<nav class="menu">
<ul class="menu__lista">
<li class="menu__item">
<a class="menu__enlace menu__enlace--activo" href="/catalogo">Catálogo</a>
</li>
<li class="menu__item">
<a class="menu__enlace" href="/prestamos">Préstamos</a>
</li>
</ul>
</nav>
.menu { background: #1b2a41; }
.menu__lista { display: flex; gap: 16px; list-style: none; padding: 0; }
.menu__enlace { color: white; text-decoration: none; }
.menu__enlace--activo { border-bottom: 2px solid #ffcc00; }
¿Qué ganas con nombres tan largos?
- Especificidad plana. Todos los selectores son una sola clase, (0,1,0). Nada gana “por sorpresa” y nunca necesitas
!important. - Sin dependencia del HTML.
.menu__enlacefunciona aunque cambies el<a>por un<button>o metas un<div>de por medio. Con.menu ul li ase rompería. - Se entiende sin mirar el CSS. Viendo
tarjeta__botonen el HTML sabes que pertenece a la tarjeta.
Dos reglas prácticas: no encadenes elementos (.menu__lista__item__enlace es excesivo; basta con .menu__enlace) y el modificador se añade a la clase base, no la sustituye: class="boton boton--grande".
Nombres de clases y selectores
Uses BEM o no, estas costumbres te ahorrarán problemas:
- Nombra por lo que es, no por cómo se ve.
.aviso-errormejor que.texto-rojo: si mañana el error es naranja, la clase seguirá teniendo sentido. - Minúsculas y guiones, sin espacios, tildes ni ñ:
.tarjeta-producto,.anio-publicacion. - Estila con clases, no con ids. Un id tiene especificidad (1,0,0) y es casi imposible de sobrescribir sin otro id. Deja los ids para enlaces internos (
#contacto), formularios (for/id) y JavaScript. - Selectores cortos.
.formulario .campo input[type="text"]es frágil y difícil de vencer. Mejor una clase:.campo__entrada.
Evitar !important
!important rompe la cascada: esa declaración gana a todo, y la única forma de ganarle es otro !important. Si lo necesitas, casi siempre es síntoma de selectores demasiado específicos en otro sitio. Lo razonable es reservarlo para utilidades que siempre deben aplicarse (.oculto { display: none !important; }) o para sobrescribir CSS de terceros. Tienes el detalle en Cascada, especificidad y herencia.
Comentarios
CSS solo tiene un tipo de comentario, /* ... */, que puede ocupar varias líneas. Úsalos para:
- Separar secciones (como los bloques con
====de arriba), que se localizan rápido con el buscador del editor. - Explicar el porqué de algo raro:
.cabecera {
/* z-index alto: el menú desplegable debe quedar por encima del mapa */
z-index: 100;
}
No comentes lo evidente (color: red; /* color rojo */): solo añade ruido.
¿Un archivo o varios?
En una web pequeña, un solo archivo estilos.css está bien. Cuando crece, conviene partirlo por secciones: variables.css, base.css, componentes/boton.css…
El problema es cómo juntarlos. Tienes dos opciones:
<!-- Varios <link>: el navegador los descarga en paralelo -->
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/componentes.css">
/* @import dentro de un CSS: funciona, pero el navegador
no descubre el segundo archivo hasta descargar el primero */
@import url("base.css");
Evita encadenar @import en producción porque retrasa la carga. En proyectos reales se usa una herramienta de construcción (como Vite) que junta todos los archivos en uno solo al publicar. Tú trabajas con archivos pequeños y ordenados; el usuario descarga uno.
Minificar
Minificar es quitar al CSS todo lo que el navegador no necesita: espacios, saltos de línea, comentarios y hasta acortar valores (#ffffff pasa a #fff).
/* Antes */
.boton {
background: #ffffff;
padding: 8px 16px;
}
/* Después de minificar */
.boton{background:#fff;padding:8px 16px}
El archivo pesa menos y carga antes. No lo hagas a mano: las herramientas de construcción lo hacen solas al generar la versión final. Tú siempre editas el archivo legible.
Sass y PostCSS en pocas palabras
Sass es un preprocesador: escribes en un lenguaje parecido a CSS (archivos .scss) y una herramienta lo convierte en CSS normal. Durante años aportó cosas que CSS no tenía:
$primario: #2d6cdf; // variables de Sass
.tarjeta {
border: 1px solid $primario;
&__titulo { // genera .tarjeta__titulo
font-size: 1.2rem;
}
}
Hoy CSS ya tiene variables y anidamiento propios, así que Sass es menos imprescindible. Aun así, lo encontrarás en muchos proyectos (Bootstrap está escrito en Sass) y aporta extras como los mixins y la concatenación &__titulo, que el CSS nativo no admite.
PostCSS es otra herramienta que transforma el CSS con plugins. El más conocido es Autoprefixer: añade automáticamente los prefijos de navegador (-webkit-, -moz-) que aún hagan falta según los navegadores que quieras soportar. Tú escribes CSS estándar y él se ocupa de la compatibilidad.
Depurar CSS con DevTools
Cuando algo no se ve como esperas, no cambies valores a ciegas. Abre las herramientas de desarrollo (F12 o clic derecho, Inspeccionar):
- Panel Elementos → Estilos: muestra todas las reglas que afectan al elemento seleccionado, ordenadas por prioridad. Las declaraciones tachadas son las que han perdido contra otra. Ahí tienes la respuesta a “¿por qué no se aplica mi CSS?”.
- Un icono de aviso junto a una declaración indica que no es válida (un valor mal escrito, una propiedad que no existe).
- Puedes editar valores y desactivar declaraciones con su casilla para probar cambios en vivo. Cuando funcione, cópialo a tu archivo.
- Pestaña Calculado (Computed): el valor final de cada propiedad y de qué regla viene. Incluye el dibujo del modelo de caja con margin, border y padding.
:hov: fuerza estados como:hovero:focuspara estilarlos sin tener el ratón encima.- Las etiquetas
flexygridjunto a los elementos dibujan las líneas y los huecos del diseño sobre la página.
Consejo: un truco clásico para encontrar qué elemento se sale de la pantalla es añadir temporalmente
* { outline: 1px solid red; }.outlineno ocupa espacio, así que no altera el diseño.
Errores frecuentes
- Estilar con ids y luego no poder sobrescribirlos.
- Selectores largos que dependen del HTML (
.menu ul li a span). Cualquier cambio en el HTML los rompe. - Usar
!importantpara arreglar un conflicto en lugar de entender por qué pierde la regla. - Nombres visuales (
.azul,.izquierda) que dejan de tener sentido cuando cambia el diseño. - Dejar CSS muerto. Si borras un componente del HTML, borra también sus estilos. Con BEM es fácil: busca el nombre del bloque.
- Editar el CSS minificado o el generado por Sass. Se sobrescribirá en la siguiente construcción.
Resumen
| Práctica | Por qué |
|---|---|
| Reset moderno | Misma base en todos los navegadores |
| Orden: variables, base, layout, componentes, utilidades | De lo general a lo particular, como la cascada |
BEM (bloque__elemento--modificador) | Especificidad plana y nombres predecibles |
| Clases, no ids; selectores cortos | CSS fácil de sobrescribir |
Evitar !important | No romper la cascada |
| Comentarios de sección y del porqué | Encontrar y entender el código |
| Varios archivos, uno al publicar | Orden para ti, rapidez para el usuario |
| Minificar | Archivos más ligeros |
| Sass / PostCSS + Autoprefixer | Extras y compatibilidad automática |
| DevTools | Ver qué regla gana y probar en vivo |
Pruébalo tú
Cambia el código y pulsa Ejecutar (o Ctrl + Enter).
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.