Saltar al contenido
organizar-css.css · devschool

Organizar el CSS: reset y BEM

Lección 21 de 25 · 11 min de lectura · Actualizado el

En esta lección
  1. Por qué hace falta organizar el CSS
  2. Un reset moderno, regla a regla
  3. El orden de un archivo CSS
  4. BEM: bloque, elemento y modificador
  5. Nombres de clases y selectores
  6. Comentarios
  7. ¿Un archivo o varios?
  8. Minificar
  9. Sass y PostCSS en pocas palabras
  10. Depurar CSS con DevTools
  11. Errores frecuentes
  12. Resumen

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 !important para “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é:

  1. box-sizing: border-box en todo, incluidos los pseudoelementos. El width incluye el padding y el borde, así que una caja de width: 300px mide 300px, no 340px. Lo viste en Modelo de caja.
  2. margin: 0 en todo. Quita los márgenes por defecto de títulos, párrafos, listas y body. A partir de ahí, tú decides cada margen.
  3. body a toda la altura (100dvh tiene 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).
  4. Imágenes y vídeos como bloque y nunca más anchos que su contenedor. display: block elimina un pequeño hueco que aparece debajo de las imágenes por ser elementos en línea.
  5. Los controles de formulario heredan la fuente. Por defecto, input y button usan una fuente del sistema y un tamaño más pequeño que el resto de la página. Con font: inherit se integran.
  6. overflow-wrap: break-word parte las palabras larguísimas (una URL, un correo) en lugar de desbordar la caja en el móvil.
  7. text-wrap: balance reparte 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:

PiezaQué esFormaEjemplo
BloqueUn componente independientebloque.tarjeta
ElementoUna parte del bloque que no tiene sentido fuera de élbloque__elemento.tarjeta__titulo
ModificadorUna variante o estadobloque--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__enlace funciona aunque cambies el <a> por un <button> o metas un <div> de por medio. Con .menu ul li a se rompería.
  • Se entiende sin mirar el CSS. Viendo tarjeta__boton en 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-error mejor 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 :hover o :focus para estilarlos sin tener el ratón encima.
  • Las etiquetas flex y grid junto 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; }. outline no 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 !important para 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ácticaPor qué
Reset modernoMisma base en todos los navegadores
Orden: variables, base, layout, componentes, utilidadesDe lo general a lo particular, como la cascada
BEM (bloque__elemento--modificador)Especificidad plana y nombres predecibles
Clases, no ids; selectores cortosCSS fácil de sobrescribir
Evitar !importantNo romper la cascada
Comentarios de sección y del porquéEncontrar y entender el código
Varios archivos, uno al publicarOrden para ti, rapidez para el usuario
MinificarArchivos más ligeros
Sass / PostCSS + AutoprefixerExtras y compatibilidad automática
DevToolsVer qué regla gana y probar en vivo

Pruébalo tú

Cambia el código y pulsa Ejecutar (o Ctrl + Enter).

organizar-css.html
Resultado

Pon a prueba lo que has aprendido

[CSS] Siguiendo BEM, ¿cuál es el nombre correcto para el botón de una tarjeta en su versión grande?

[CSS] ¿Para qué sirve esta regla de un reset moderno?
input, button, textarea, select {
  font: inherit;
}

[CSS] En las DevTools, una declaración aparece tachada en el panel de estilos. ¿Qué significa?

[CSS] ¿Por qué se recomienda estilar con clases en lugar de con ids?

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.