Saltar a contenido

UT2 — Uso de estilos

Índice

  1. UT2-1 — Estilos en línea basados en etiquetas y en clases
  2. UT2-2 — Crear y vincular hojas de estilo
  3. UT2-3 — Crear y vincular hojas de estilo en cascada externa
  4. UT2-4 — Herramientas y test de verificación
  5. UT2-5 — Tecnologías y frameworks
  6. UT2-6 — Preprocesadores de estilos. Variables, mixins y funciones
  7. Glosario rápido
  8. Repaso: 8-10 preguntas para autoevaluarte
  9. De dónde sale esto (fuentes de la carpeta)

De qué va esta unidad

Imagina que ya sabes escribir HTML: tienes encabezados, párrafos, listas, botones... pero todo se ve con la tipografía por defecto del navegador, en negro sobre blanco, sin ningún orden visual. Eso es exactamente lo que le pasa a cualquier página el día que solo tiene estructura y ningún estilo. En esta unidad aprendes a resolver ese problema con CSS (Cascading Style Sheets, hojas de estilo en cascada): el lenguaje que separa "qué es cada cosa" (lo dice el HTML) de "cómo se ve" (lo dice el CSS).

Vas a recorrer el camino completo: desde la forma más rudimentaria de aplicar un estilo —escribirlo directamente sobre una etiqueta— hasta las formas profesionales que se usan hoy en cualquier empresa de desarrollo web: hojas de estilo externas que se reutilizan en todo un sitio, hojas alternativas para lectores con necesidades distintas, hojas especiales para cuando alguien imprime la página, herramientas que comprueban que tu CSS no tiene errores, frameworks que te dan medio trabajo hecho (Bootstrap, Tailwind CSS) y preprocesadores como Sass, que añaden a CSS superpoderes que el propio CSS no tiene (variables reutilizables, anidamiento, funciones...).

El hilo conductor de las prácticas de este módulo es un cliente ficticio, el Café Central: una cafetería que necesita una web con carta, reservas y una zona de barra para el personal. A lo largo de esta unidad usaremos ese ejemplo varias veces para que veas cómo se aplican los conceptos a un caso real de encargo profesional, no solo a fragmentos de código sueltos.

Dicho con las palabras de la propia programación del ciclo: esta unidad trata sobre la "creación de interfaces web homogéneas mediante hojas de estilo: estilos en línea, internos y externos, hojas alternativas, redefinición de estilos y clases, validación, diseño responsive con tecnologías y frameworks como Bootstrap o Tailwind CSS, y preprocesadores de estilos como SASS (variables, mixins y funciones)". Todo eso, con calma y con ejemplos, es lo que encontrarás a continuación.

Qué deberías saber hacer al terminar (resultados de aprendizaje)

El resultado de aprendizaje de esta unidad es el RA2: Crea interfaces web homogéneos definiendo y aplicando estilos. En cristiano, al acabar la UT2 deberías ser capaz de:

  • Reconocer qué posibilidades tienes para modificar el aspecto de las etiquetas HTML (más allá de lo que traen "de fábrica" los navegadores).
  • Definir estilos de forma directa, es decir, aplicar CSS sobre un elemento concreto sin pasar por una hoja de estilos aparte.
  • Definir y asociar estilos globales usando una hoja de estilos externa, para que todo el sitio comparta la misma apariencia.
  • Crear hojas de estilos alternativas, que ofrezcan versiones distintas de la presentación de una misma página.
  • Redefinir estilos: cambiar el aspecto por defecto de una etiqueta o sobrescribir un estilo anterior cuando hace falta.
  • Identificar las distintas propiedades CSS que se le pueden aplicar a cada tipo de elemento.
  • Crear y usar clases de estilo para agrupar elementos que deben verse igual.
  • Utilizar herramientas de validación de hojas de estilos, para comprobar que tu CSS es correcto antes de publicarlo.
  • Analizar y utilizar tecnologías y frameworks (como Bootstrap o Tailwind CSS) para construir interfaces con diseño responsive.
  • Analizar y utilizar preprocesadores de estilos (como Sass), que traducen un código más cómodo de escribir a CSS estándar, el único que entienden los navegadores.

UT2-1 — Estilos en línea basados en etiquetas y en clases

El atributo style: la forma más directa (y menos recomendable) de dar estilo

La manera más básica de decirle a un navegador "quiero que esto se vea así" es escribir el estilo directamente sobre la etiqueta, usando el atributo style. Su sintaxis general es:

<etiqueta style="declaraciones de estilo">

Por ejemplo:

<p style="color: red; font-weight: bold;">¡Oferta especial esta semana!</p>

Esto se llama estilo en línea (inline). Es válido, pero mézclalo con cuidado: estás metiendo información de presentación dentro del propio contenido HTML, justo lo contrario de lo que CSS pretende conseguir (separar contenido y presentación). Por eso, un estilo en línea "contamina" el documento y debería usarse solo de forma puntual, por ejemplo para ignorar una regla de nivel más alto en un caso muy concreto.

Selectores basados en la etiqueta: redefinir el aspecto por defecto

Antes de pensar en clases o identificadores, la forma más sencilla de aplicar CSS es seleccionar directamente el nombre de la etiqueta (selector de tipo o de elemento). Esto te permite redefinir cómo se ve por defecto un elemento en todo el documento:

p {
  color: #333;
  line-height: 1.5;
}

h1 {
  font-family: "Georgia", serif;
  color: #6b3e26;
}

Con esto, absolutamente todos los párrafos y todos los <h1> del documento cambian de aspecto sin tocar una sola línea de HTML. Aquí es donde se ve el primer gran beneficio de separar contenido y presentación: si mañana el Café Central decide cambiar su color corporativo, cambias una regla CSS y toda la web se actualiza sola.

Selectores contextuales y combinadores

Además de seleccionar por nombre de etiqueta, puedes combinar selectores para ser más concreto. Un selector contextual (o descendente) selecciona un elemento solo cuando está dentro de otro:

nav a {
  text-decoration: none;
}

Esto afecta únicamente a los enlaces <a> que estén dentro de un <nav>, no a todos los enlaces de la página. También existe el selector adyacente, que usa el símbolo + para seleccionar un elemento que va justo después de otro (por ejemplo, el primer párrafo que sigue a un encabezado):

h1 + p {
  font-size: 1.2em;
}

Clases: agrupar elementos que deben comportarse igual

Cuando varios elementos necesitan el mismo tratamiento aunque sean de tipos distintos (un <h1> y un <p>, por ejemplo), usamos el atributo class. Un elemento puede pertenecer a más de una clase a la vez, separando los nombres con espacios:

<h1 class="especial">¡Atención!</h1>
<p class="textocabecera especial">Hoy tenemos grandes rebajas.</p>

Para escribir la regla de estilo de una clase se usa un punto seguido del nombre:

.especial {
  color: green;
}

h1.especial {
  color: red; /* las cabeceras "especial" serán rojas, no verdes */
}

Fíjate en algo importante: h1.especial es más específico que .especial a secas, así que gana la regla más concreta quando hay conflicto. Esto se conoce como especificidad del selector: cuanto más concreto es un selector (por ejemplo, uno que combina etiqueta y clase, o que usa un identificador), más peso tiene frente a otras reglas que también afectan al mismo elemento. Los nombres de clases e identificadores nunca pueden llevar espacios en blanco.

Identificadores (id): un caso único por documento

El atributo id identifica de forma exclusiva a un elemento: solo puede existir un elemento con ese id en todo el documento. Se selecciona con el símbolo #:

<p id="textocabecera">Café Central</p>
#textocabecera {
  font-size: 14px;
}

Como el id es único, basta con #textocabecera para seleccionarlo sin ambigüedad: no hace falta anteponerle la etiqueta.

Pseudoclases y pseudoelementos: estilos "condicionales"

A veces quieres dar estilo a un elemento en función de una situación (si el ratón está encima, si ya se ha visitado un enlace...) o a una parte concreta de un elemento (su primera letra, su primera línea). Para eso existen las pseudoclases y los pseudoelementos, que se escriben con : a continuación del selector.

Las pseudoclases más habituales son las de los enlaces, que además deben escribirse siempre en este orden (regla mnemotécnica: LVHA):

a:link    { color: red; }      /* enlace no visitado */
a:visited { color: blue; }     /* enlace ya visitado */
a:hover   { color: fuchsia; }  /* ratón encima */
a:active  { color: maroon; }   /* mientras se pulsa */

Otras pseudoclases útiles: :focus (el elemento tiene el foco, por ejemplo un campo de formulario), :first-child (el primer hijo de su padre) o :lang() (según el idioma del contenido).

Los pseudoelementos afectan a partes concretas de un elemento, como su primera línea o su primera letra:

p:first-line { letter-spacing: 6pt; }
p.definicion:first-letter { font-size: 300%; color: red; }

Ejemplo actual — por qué el email marketing todavía usa mucho el estilo en línea. Si alguna vez has mirado el código fuente de un boletín de Mailchimp, Amazon o cualquier tienda online, verás que casi todo el CSS está escrito como estilos en línea sobre cada etiqueta. No es que a esos equipos les guste ensuciar el HTML: es que muchos clientes de correo (Outlook clásico, Gmail en algunos contextos) ignoran las hojas de estilo externas o internas por motivos de seguridad, y el único CSS que garantizan que se aplique es el que va pegado directamente en el atributo style. Es la excepción que confirma la regla: se usa estilo en línea a propósito, sabiendo sus limitaciones.

Ideas clave de esta sección

  • El atributo style aplica CSS directamente sobre una etiqueta concreta: es el modo más directo, pero también el que menos separa contenido y presentación.
  • Seleccionar por nombre de etiqueta te permite redefinir el aspecto por defecto de todo un tipo de elemento en el documento.
  • Las clases (.clase) agrupan elementos distintos que deben verse igual; los id (#id) identifican un único elemento por documento.
  • Cuanto más específico es un selector, más peso tiene frente a otras reglas en conflicto (especificidad).
  • Las pseudoclases (:hover, :focus...) y los pseudoelementos (:first-letter, :first-line...) permiten aplicar estilos según un estado o a una parte del elemento.

UT2-2 — Crear y vincular hojas de estilo

Cuando el número de reglas de estilo empieza a crecer, escribirlas todas en línea se vuelve inmanejable. El siguiente paso es reunir esas reglas en una hoja de estilos: un bloque de código CSS separado del contenido, aunque todavía viva dentro del mismo documento HTML.

Hojas de estilo incrustadas (internas)

Se colocan dentro del elemento <style>, en la cabecera (<head>) del documento.

Ejemplo actual — los ejemplos de DIW04.pdf usan el DOCTYPE de XHTML 1.0 Transitional y <style type="text/css">; hoy se escribe con el DOCTYPE de HTML5 y sin el atributo type, que ya no es necesario:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <style>
      body { font-family: Arial, sans-serif; }
      h1   { color: #6b3e26; }
    </style>
    <title>Café Central</title>
  </head>
  <body>
    ...
  </body>
</html>

Este método es cómodo cuando el estilo es específico de una única página y no quieres crear un archivo aparte. El atributo media, que orienta una hoja de estilos a un tipo de dispositivo o salida concreto (por ejemplo screen para pantalla), se usa sobre todo en el elemento <link> (lo verás en el siguiente apartado), aunque también puede combinarse con @media dentro de un bloque <style>.

Comentarios en CSS

Al igual que en HTML, en CSS se pueden (y deben) añadir comentarios para explicar el código. La sintaxis es distinta a la de HTML:

/* Esto es un comentario en CSS */
h2 { margin-bottom: 8px; }

Importar hojas de estilo con @import

Dentro de un bloque <style> (o dentro de otra hoja CSS) se puede importar otra hoja de estilos con la regla @import. Debe colocarse siempre al principio, antes de cualquier otra regla:

<style type="text/css">
  @import url(base.css);
  /* aquí podrían ir otros @import u otras reglas */
</style>

Si se importan varias hojas y hay conflicto entre ellas, prevalece la última que se importa.

Ideas clave de esta sección

  • Una hoja de estilos incrustada se escribe dentro de <style> en la cabecera del documento: mantiene el CSS fuera del cuerpo del HTML, pero sigue viviendo en el mismo archivo.
  • El atributo type="text/css" identifica el lenguaje de la hoja y media indica el tipo de salida al que se dirige.
  • @import permite traer el contenido de otra hoja de estilos dentro de la actual; debe ir siempre al principio del bloque.
  • Los comentarios CSS se escriben entre /* ... */, con una sintaxis distinta a la de HTML (<!-- ... -->).

UT2-3 — Crear y vincular hojas de estilo en cascada externa

Este es el modo más potente y más usado en el desarrollo web profesional: reunir todas las reglas de estilo en un archivo .css independiente y vincularlo desde tantas páginas HTML como haga falta. Así, cambiar un color o una tipografía en un único archivo actualiza el aspecto de todo el sitio a la vez.

Diagrama de varias páginas HTML vinculadas a una única hoja de estilos CSS Figura: varias páginas HTML distintas enlazan a la misma hoja de estilos externa, que concentra todas las reglas de presentación del sitio. Origen: DIW04.pdf.

Para vincular una hoja externa se usa el elemento <link> dentro de <head>:

<head>
  <link rel="stylesheet" href="../estilos/miestilo.css" type="text/css" />
</head>
  • rel="stylesheet" indica la relación del documento vinculado con el actual: es una hoja de estilo.
  • href apunta a la URL (relativa o absoluta) del archivo CSS.

Puedes vincular más de una hoja de estilos en el mismo documento; en ese caso, el orden importa: si dos hojas afectan al mismo elemento, la que se enlaza más abajo en el <head> es la que gana en caso de conflicto (se aplican "de arriba hacia abajo").

La "cascada": cómo decide el navegador qué regla gana

El nombre "hojas de estilo en cascada" viene precisamente de esto: cuando varias reglas afectan al mismo elemento, el navegador las ordena según el origen de la hoja, la especificidad del selector y el orden de la regla, para decidir cuál se aplica.

Respecto al origen, y ordenadas de menor a mayor peso, las hojas de estilo de la persona que ha diseñado la página se organizan así:

  1. Hojas de estilo externas vinculadas (<link>).
  2. Hojas de estilo externas importadas (@import dentro de <style>).
  3. Hojas de estilo incrustadas (<style> en la cabecera).
  4. Estilos en línea (atributo style).
  5. Declaraciones marcadas con !important.

Es decir: cuanto "más cerca" está la regla del elemento, más peso tiene, y !important siempre gana sobre cualquier otra declaración normal para ese mismo elemento:

#principal {
  width: 800px !important;
  width: 1200px;
}
/* El elemento con id="principal" acabará midiendo 800px,
   porque la primera declaración lleva !important */

Usa !important con moderación: es muy útil para depurar un problema puntual, pero abusar de él hace que tu CSS sea difícil de mantener, porque rompe el orden natural de la cascada.

Hojas de estilo alternativas

Además de la hoja "normal" de una página, se pueden ofrecer hojas de estilo alternativas: distintas presentaciones de la misma página entre las que la persona usuaria puede elegir (por ejemplo, un tema "clásico" y uno "moderno", o un modo de alto contraste). Se indican con el atributo rel del <link>:

<link href="reset.css" rel="stylesheet" />
<link href="default.css" rel="stylesheet" title="Default Style" />
<link href="fancy.css" rel="alternate stylesheet" title="Fancy" />
<link href="basic.css" rel="alternate stylesheet" title="Basic" />

Cada hoja cae en una de estas categorías:

Tipo Cómo se declara Comportamiento
Persistente rel="stylesheet", sin title Se aplica siempre, no se puede desactivar.
Preferida rel="stylesheet" con title="..." Se aplica por defecto, pero se puede sustituir.
Alternativa rel="alternate stylesheet" con title="..." Desactivada por defecto; el usuario puede elegirla.

En el ejemplo de arriba, reset.css siempre se aplica (es persistente), default.css es la opción preferida y fancy.css/basic.css son alternativas que la persona usuaria puede activar. En el navegador Firefox, por ejemplo, estas opciones aparecen en el menú Ver > Estilo de la página; el resto de navegadores actuales necesitan una extensión para ofrecer ese menú, porque no tienen soporte nativo para esta función.

En las noticias — el modo oscuro ha sustituido de facto a las hojas alternativas. Aunque las hojas de estilo alternativas siguen siendo parte del estándar HTML, en la práctica casi nadie las usa hoy para ofrecer temas visuales: la tendencia de los últimos años (Windows, macOS, Android, iOS y la mayoría de apps y webs) ha sido resolver el "tema claro / tema oscuro" con la media feature prefers-color-scheme, que detecta la preferencia del sistema operativo automáticamente, sin que la persona usuaria tenga que elegir nada en un menú del navegador.

Hojas de estilo para imprimir

CSS permite dirigir una hoja de estilos a un medio concreto usando el atributo media del <link>. Uno de los casos más útiles es preparar una versión especial para cuando alguien imprime la página (o la exporta a PDF desde el navegador):

<link href="/ruta/print.css" media="print" rel="stylesheet" />

También puedes escribir los estilos de impresión dentro de la misma hoja general, usando la regla @media:

@media print {
  /* Aquí van todos los estilos de impresión */
  #header,
  #footer,
  #nav {
    display: none !important;
  }
}

Algunos motivos habituales para tener una hoja de impresión propia son: ocultar elementos que no aportan nada en papel (menús, cabeceras, publicidad), ajustar el diseño al tamaño y forma del papel, usar imágenes de mayor resolución o incluso mostrar una vista previa especial antes de imprimir. Además de @media, existe la regla @page, que permite ajustar aspectos propios de la página impresa como sus dimensiones, orientación o márgenes.

En cuanto al valor del atributo media, CSS define distintos tipos de medio; los más usados en la práctica actual son all (todos los medios), screen (pantallas) y print (impresoras o vista previa de impresión). Otros valores que se definieron en su momento (handheld para dispositivos de mano, tty, braille, embossed, projection, tv...) casi no se usan hoy: la mayoría de esos casos de uso se resuelven ahora con diseño responsive (que verás en el apartado UT2-5) en lugar de con hojas de estilo separadas por tipo de dispositivo.

Ejemplo propio — el Café Central en papel. Imagina que la carta online del Café Central tiene fotos grandes, un menú de navegación fijo y botones de "añadir al pedido". Nada de eso tiene sentido en una hoja impresa. Con una hoja print.css (o un bloque @media print) podrías ocultar la navegación y los botones, poner el texto en blanco y negro para ahorrar tinta, y asegurarte de que los precios se ven grandes y claros.

Ideas clave de esta sección

  • <link rel="stylesheet" href="../..."> vincula una hoja de estilos externa desde el <head>; es el método más mantenible para sitios con varias páginas.
  • La cascada decide qué regla gana combinando el origen de la hoja (externa vinculada < importada < incrustada < en línea < !important), la especificidad del selector y el orden de la regla.
  • Las hojas alternativas (rel="alternate stylesheet") ofrecen variantes de presentación que la persona usuaria puede elegir, aunque hoy están en desuso frente a soluciones como prefers-color-scheme.
  • El atributo media="print" o la regla @media print permiten preparar una versión de la página pensada para imprimir.

UT2-4 — Herramientas y test de verificación

Escribir CSS a mano es fácil equivocarse: una propiedad mal escrita, una llave que falta, una unidad olvidada... Por eso conviene validar el CSS antes de darlo por bueno, igual que se valida el HTML. La herramienta de referencia es el Servicio de Validación de CSS del W3C, cuyo manual de usuario documenta la URI base http://jigsaw.w3.org/css-validator/.

Este validador ofrece tres formas de comprobar tu CSS:

Pestaña "Validar mediante URI" del validador CSS del W3C Figura: validación introduciendo la URL pública de un documento HTML o CSS. Origen: WEB - W3C - Validador CSS (manual).pdf.

  • Validación mediante URI: introduces la dirección web del documento (HTML o CSS) y el validador la analiza directamente.

Pestaña "Validar mediante Carga de Archivo" del validador CSS del W3C Figura: validación subiendo un archivo CSS local desde tu propio ordenador. Origen: WEB - W3C - Validador CSS (manual).pdf.

  • Validación mediante carga de archivo: subes un archivo local desde tu equipo. Ojo: con este método solo se admiten archivos CSS (no HTML), y hay que tener cuidado con las reglas @import, porque solo se seguirán si apuntan a una URL pública (no a rutas relativas de tu disco).

Pestaña "Validar mediante entrada directa" del validador CSS del W3C, con una hoja CSS de ejemplo Figura: se puede pegar directamente un fragmento de CSS en un área de texto para validarlo. Origen: WEB - W3C - Validador CSS (manual).pdf.

  • Validación mediante entrada directa: pegas el código CSS en un área de texto. Es el modo más cómodo para probar fragmentos sueltos o para pedir ayuda a la comunidad, porque puedes enlazar la URL con el resultado como caso de prueba.

Errores y advertencias

El validador distingue entre dos tipos de mensajes:

  • Errores: el CSS no respeta la especificación técnica de CSS. Hay que corregirlos.
  • Advertencias: no incumplen la especificación, pero avisan de algo que podría dar problemas en ciertos navegadores. Un caso típico: si defines font-family sin un tipo de letra genérico al final (sans-serif, serif...), el validador te avisará de que, si ninguna de las fuentes que pediste está disponible, el navegador podría mostrar un tipo de letra inesperado.

Opciones avanzadas

La interfaz básica del validador comprueba el cumplimiento con CSS 2.1, usando all como medio por defecto. Si necesitas algo más fino, la interfaz avanzada permite ajustar tres parámetros:

Parámetro Para qué sirve
warnings Nivel de detalle de los avisos: sin avisos, nivel bajo o nivel alto.
profile Perfil de CSS a comprobar: css1, css2, css21, css3, svg, mobile, tv...
medium Medio de destino equivalente a la regla @media (screen, print, braille...).

El validador también ofrece una API de servicio web para llamarlo de forma programada (por ejemplo, desde un script que valide automáticamente todos los CSS de un proyecto), a través de parámetros como uri, text, output o lang. Eso sí: si automatizas llamadas al servicio público del W3C, el propio manual pide dejar al menos un segundo de espera entre peticiones, porque es un servicio gratuito y compartido por toda la comunidad web.

Ejemplo actual — validar CSS como parte del flujo de trabajo. En un equipo de desarrollo profesional no se suele validar "a mano" cada archivo con el formulario del W3C: se integran herramientas equivalentes (como stylelint) directamente en el editor de código o en el proceso de integración continua (CI), de forma que el propio sistema avisa si alguien sube CSS con errores antes de que llegue a producción. El validador del W3C sigue siendo, sin embargo, el punto de referencia oficial para comprobar que un CSS cumple realmente el estándar.

Ideas clave de esta sección

  • El Servicio de Validación de CSS del W3C admite tres modos: por URI, por carga de archivo, o por entrada directa de texto.
  • Diferencia entre errores (incumplen la especificación) y advertencias (avisos de buenas prácticas).
  • La validación básica comprueba CSS 2.1 por defecto; la avanzada permite elegir perfil (profile), medio (medium) y nivel de avisos (warnings).

UT2-5 — Tecnologías y frameworks

Diseño responsive: por qué ya no se diseña "para una pantalla"

Durante mucho tiempo, una web se diseñaba pensando en un único tamaño de pantalla. Cuando llegaron los móviles, muchas empresas optaron por crear una web aparte solo para ellos (con URLs como m.ejemplo.com), lo que suponía mantener dos sitios en paralelo. El concepto que resolvió este problema, acuñado por Ethan Marcotte en 2010, es el diseño web responsivo (responsive web design, RWD): un conjunto de técnicas que permite que una misma página adapte su diseño y apariencia a diferentes anchos de pantalla y resoluciones. Combina tres ideas:

  1. Rejillas fluidas (fluid grids): en vez de anchos fijos en píxeles, se usan porcentajes, de modo que el diseño se reparte proporcionalmente al espacio disponible.
  2. Imágenes fluidas: aplicando max-width: 100% a las imágenes, estas se reducen si su contenedor se estrecha, pero nunca se salen de la columna.
  3. Consultas a los medios (media queries): permiten aplicar un CSS u otro según características del dispositivo, sobre todo el ancho de la ventana.
@media screen and (min-width: 800px) {
  .container {
    margin: 1em 2em;
  }
}

Los puntos donde una media query cambia el diseño se llaman puntos de interrupción (breakpoints). Un enfoque muy habitual es el mobile-first: diseñar primero la versión de una sola columna para pantallas estrechas y luego ir añadiendo columnas a medida que hay más ancho disponible.

Hoy en día, además de las media queries, se usan técnicas de maquetación que son responsivas "de fábrica": multicol (column-count, column-width), Flexbox (display: flex) y CSS Grid (display: grid), que reparten el espacio disponible entre los elementos sin que tengas que calcular porcentajes a mano.

Por último, casi toda página responsiva necesita esta línea en su <head>:

<meta name="viewport" content="width=device-width, initial-scale=1" />

Sin esta metaetiqueta, muchos navegadores móviles simulan una pantalla de 960 píxeles de ancho y luego reducen el resultado, dando una versión en miniatura del diseño de escritorio. Con width=device-width le decimos al navegador que use el ancho real del dispositivo, para que las media queries funcionen como se espera. Se recomienda no usar user-scalable=no ni limitar demasiado el zoom con minimum-scale/maximum-scale, porque eso perjudica la accesibilidad de personas que necesitan ampliar el contenido.

Bootstrap 5: framework basado en componentes

Bootstrap es uno de los frameworks CSS más usados del mundo. Se instala fácilmente vía CDN, sin necesidad de proceso de compilación:

<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Café Central</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
  </head>
  <body>
    <h1>Hola, Café Central</h1>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
  </body>
</html>

(La versión en el momento de escribir esta documentación es la 5.3.8; Bootstrap cambia de versión con cierta frecuencia, así que conviene revisar siempre la última disponible).

Bootstrap está desarrollado con enfoque mobile-first y aplica de serie unos estilos globales (llamados Reboot) para uniformar cómo se ven las etiquetas HTML en los distintos navegadores; entre otras cosas, cambia el box-sizing de todos los elementos a border-box, para que el padding no aumente el ancho final calculado de una caja.

El sistema de rejilla (grid) es su pieza más usada. Se basa en contenedores, filas y columnas, construido con Flexbox, con 12 columnas por fila y seis niveles de punto de interrupción (breakpoints):

Breakpoint Prefijo de clase Ancho mínimo Ancho máximo del contenedor
Extra pequeño (xs) .col- (ninguno) auto
Pequeño (sm) .col-sm- ≥576px 540px
Mediano (md) .col-md- ≥768px 720px
Grande (lg) .col-lg- ≥992px 960px
Extra grande (xl) .col-xl- ≥1200px 1140px
Extra extra grande (xxl) .col-xxl- ≥1400px 1320px

Cada columna indica cuántas de esas 12 columnas ocupa (por ejemplo, col-4 ocupa un tercio del ancho). El ejemplo más simple, tres columnas de igual ancho:

Ejemplo de tres columnas iguales con las clases de rejilla de Bootstrap 5 Figura: resultado visual de una fila .row con tres .col de igual ancho. Origen: WEB - Bootstrap 5 - Rejilla (grid).pdf.

<div class="container text-center">
  <div class="row">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
  </div>
</div>

Y así es como el mismo bloque de tarjetas puede pasar de tres columnas por fila en pantallas grandes, a dos en pantallas medianas y a una sola en móvil, cambiando únicamente las clases de la rejilla:

Comparativa de la misma cuadrícula de tarjetas en tamaños grande, mediano y pequeño Figura: la misma colección de tarjetas se reorganiza automáticamente según el tamaño de pantalla gracias a las clases responsivas de la rejilla. Origen: TE11UD1 Ejercicio Bootstrap Grids ENUNCIADO.pdf.

Bootstrap incluye, además de la rejilla, un catálogo grande de componentes ya maquetados (barras de navegación, modales, acordeones, carruseles, toasts...), algunos de los cuales necesitan también su JavaScript (y, en varios casos, la librería Popper para posicionar menús desplegables o tooltips).

Tailwind CSS: framework basado en utilidades

Tailwind CSS (en el momento de esta documentación, versión 4.3) sigue una filosofía muy distinta: en vez de darte componentes ya diseñados, te da un catálogo enorme de clases de utilidad, cada una con un único propósito, que combinas directamente en el HTML:

<div class="mx-auto flex max-w-sm items-center gap-x-4 rounded-xl bg-white p-6 shadow-lg">
  <img class="size-12 shrink-0" src="/img/logo.svg" alt="Logo ChitChat" />
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-gray-500">Tienes un mensaje nuevo</p>
  </div>
</div>

Ejemplo de tarjeta construida con clases de utilidad de Tailwind CSS y su código HTML Figura: cada clase (flex, rounded-xl, shadow-lg, text-xl...) aporta una única propiedad CSS; combinándolas se construye el componente completo sin salir del HTML. Origen: WEB - Tailwind CSS - Clases de utilidad.pdf.

Según la propia documentación de Tailwind, trabajar así tiene ventajas frente a escribir CSS tradicional (clases propias con nombre semántico) y frente a usar estilos en línea:

  • Es más rápido: no hay que inventar nombres de clases ni ir cambiando de archivo.
  • Es más seguro tocar algo: una clase de utilidad solo afecta al elemento donde la pones, así que no rompes sin querer otra parte de la página que comparte esa misma clase CSS.
  • El CSS final no crece sin parar: como las utilidades se reutilizan muchísimo, el tamaño del CSS no aumenta al mismo ritmo que el número de páginas o componentes.

Tailwind también resuelve el diseño responsive con prefijos de punto de interrupción: cualquier utilidad puede aplicarse solo a partir de un tamaño de pantalla anteponiendo el nombre del breakpoint y dos puntos:

<img class="w-16 md:w-32 lg:w-48" src="foto.jpg" alt="" />
<!-- ancho 16 por defecto, 32 en pantallas medianas, 48 en pantallas grandes -->
Prefijo Ancho mínimo Equivalente CSS
sm: 40rem (640px) @media (width >= 40rem)
md: 48rem (768px) @media (width >= 48rem)
lg: 64rem (1024px) @media (width >= 64rem)
xl: 80rem (1280px) @media (width >= 80rem)
2xl: 96rem (1536px) @media (width >= 96rem)

Con el mismo mecanismo de prefijos se pueden aplicar utilidades solo en estados como hover: o focus:, o combinarlos entre sí (por ejemplo lg:hover:bg-indigo-600). Tailwind también admite valores arbitrarios entre corchetes cuando ninguna utilidad predefinida encaja exactamente, por ejemplo bg-[#316ff6].

Bootstrap frente a Tailwind: ¿cuál elegir?

Bootstrap Tailwind CSS
Enfoque Componentes ya diseñados (botones, tarjetas, navbars...) Utilidades de un único propósito que tú combinas
Punto de partida Rápido para maquetar algo estándar sin diseñar desde cero Rápido para construir un diseño propio y diferenciado
Personalización Sobrescribir sus clases o sus variables Sass Configurar el propio Tailwind; el diseño nace "a medida"
Peso del HTML Clases pocas, con nombre semántico (.btn, .card) Muchas clases por elemento, muy descriptivas
JavaScript incluido Sí, para varios componentes (modales, dropdowns...) No; Tailwind es solo CSS

No hay una respuesta única: para un prototipo rápido o un panel interno donde no importa tanto que "se note" qué framework usas, Bootstrap suele ahorrar tiempo. Para un producto con una identidad visual propia y muy cuidada, Tailwind da más control fino sin tener que pelear contra los estilos por defecto de los componentes de otro framework.

Ejemplo actual — Tailwind en el ecosistema Laravel. El framework de backend PHP Laravel incluye Tailwind CSS de serie en sus kits de arranque oficiales (como Jetstream o Breeze) desde hace varias versiones, lo que ha ayudado a que Tailwind se haya convertido en una opción habitual para equipos que arrancan un proyecto nuevo desde cero.

En las noticias — Tailwind CSS v4. Según se informó por parte del propio equipo de Tailwind, la versión 4 del framework (publicada en 2025) reescribió su motor interno para ser notablemente más rápido a la hora de compilar el CSS, y cambió la forma de personalizarlo: en vez de un archivo de configuración en JavaScript, ahora se configura directamente con CSS. Es un buen ejemplo de cómo los frameworks CSS siguen evolucionando rápido, así que conviene revisar siempre la documentación oficial antes de dar una versión por sentada.

Ideas clave de esta sección

  • El diseño responsive combina rejillas fluidas, imágenes fluidas y media queries, y hoy se apoya también en Flexbox, Grid y multicol.
  • La metaetiqueta <meta name="viewport" content="width=device-width, initial-scale=1"> es imprescindible para que el diseño responsive funcione en móviles.
  • Bootstrap ofrece componentes prediseñados y una rejilla de 12 columnas con 6 breakpoints.
  • Tailwind CSS ofrece clases de utilidad de un único propósito, con sus propios prefijos de breakpoint (sm:, md:, lg:, xl:, 2xl:) para el diseño responsive.
  • Elegir framework depende del proyecto: velocidad y componentes ya hechos (Bootstrap) o control fino y diseño a medida (Tailwind).

UT2-6 — Preprocesadores de estilos. Variables, mixins y funciones

CSS, tal cual lo escribe el navegador, no tiene variables reutilizables "de verdad" (más allá de las propiedades personalizadas --nombre), ni funciones propias, ni una forma cómoda de organizar el código en varios archivos pequeños. Un preprocesador de estilos añade todo eso: escribes en un lenguaje algo más potente que CSS y luego lo compilas (lo traduces) a CSS estándar, que es el único que entienden los navegadores. El preprocesador más usado hoy es Sass.

Sass tiene dos sintaxis: SCSS (.scss), que es un superconjunto de CSS —todo CSS válido es también SCSS válido— y la sintaxis indentada (.sass), que usa sangrado en vez de llaves y saltos de línea en vez de punto y coma. En la práctica profesional se usa casi siempre SCSS, así que es la que veremos aquí. Para compilar un archivo se usa el comando sass:

sass input.scss output.css
sass --watch input.scss output.css   # recompila automáticamente al guardar

Variables

Guardan un valor (un color, una fuente, una medida...) para reutilizarlo en toda la hoja de estilos. Se declaran con el símbolo $:

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

Esto es especialmente útil para mantener consistentes los colores de marca: si el Café Central decide cambiar su color corporativo, basta con tocar el valor de la variable una sola vez.

Anidamiento (nesting)

El HTML tiene una jerarquía visual clara (una lista dentro de un <nav>, un enlace dentro de esa lista...), pero el CSS plano no refleja esa jerarquía de forma natural. Sass permite anidar selectores siguiendo la misma estructura que el HTML:

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  li { display: inline-block; }
  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

Que se traduce a CSS estándar como nav ul { ... }, nav li { ... } y nav a { ... }. Ojo: anidar demasiados niveles genera selectores muy "sobre-específicos" y difíciles de mantener; hay que usarlo con cabeza.

Parciales y módulos

Un parcial es un archivo Sass pensado para ser incluido en otro, no para generar un CSS por sí solo. Se nombra con un guion bajo delante (por ejemplo _base.scss); ese guion bajo le dice a Sass que no debe compilarlo como archivo independiente. Los parciales se combinan con la regla @use, que carga otro archivo Sass como módulo, dándole acceso a sus variables, mixins y funciones a través de un espacio de nombres basado en el nombre del archivo:

// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

// styles.scss
@use 'base';

.inverse {
  background-color: base.$primary-color;
  color: white;
}

Así, en un proyecto real como la web del Café Central, podrías tener _variables.scss (los colores y tipografías de la marca), _carta.scss (estilos de la página de la carta), _reservas.scss... y un styles.scss principal que los une todos con @use.

Mixins: agrupar declaraciones reutilizables

Un mixin agrupa un conjunto de declaraciones CSS que quieres repetir en varios sitios, y admite parámetros (incluso con valores por defecto) para hacerlo flexible:

@mixin theme($theme: DarkGray) {
  background: $theme;
  box-shadow: 0 0 1px rgba($theme, 0.25);
  color: #fff;
}

.info    { @include theme; }
.alert   { @include theme($theme: DarkRed); }
.success { @include theme($theme: DarkGreen); }

Cada @include inserta las declaraciones del mixin en ese selector, sustituyendo $theme por el valor que le pases (o por DarkGray si no le pasas ninguno).

Herencia con @extend

@extend permite que un selector "herede" las propiedades de otro. Se suele combinar con los selectores marcador (placeholder selectors, que empiezan por %), que solo generan CSS si alguien los extiende:

%message-shared {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.error   { @extend %message-shared; border-color: red; }
.warning { @extend %message-shared; border-color: yellow; }

Operadores y funciones

Sass permite hacer operaciones matemáticas directamente en el CSS (+, -, *, % y math.div() para dividir), algo muy práctico para calcular anchos porcentuales de una rejilla fluida:

@use "sass:math";

article[role="main"] {
  width: math.div(600px, 960px) * 100%; // 62.5%
}

Y además de las funciones ya incluidas en Sass, puedes definir las tuyas propias con @function, que siempre debe terminar con @return:

@function invert($color, $amount: 100%) {
  $inverse: change-color($color, $hue: hue($color) + 180);
  @return mix($inverse, $color, $amount);
}

$primary-color: #036;
.header {
  background-color: invert($primary-color, 80%);
}

Los argumentos de una función pueden tener valores por defecto (como $amount: 100% en el ejemplo), lo que permite llamarla de forma sencilla o más detallada según haga falta.

Ejemplo actual — Bootstrap está escrito en Sass por dentro. La propia documentación de la rejilla de Bootstrap explica que sus clases predefinidas se generan a partir de variables, maps y mixins de Sass; si no te sirven las clases ya hechas, puedes usar directamente ese Sass "fuente" para construir tu propia rejilla con nombres de clase más semánticos. Es un buen ejemplo real de cómo un framework y un preprocesador se combinan en la práctica profesional.

En las noticias — ¿sigue haciendo falta Sass? En los últimos años, CSS ha ido incorporando de forma nativa funciones que antes solo existían en Sass, como el anidamiento de selectores o las propiedades personalizadas (--variable), ya soportadas en los navegadores modernos. Esto ha abierto un debate habitual en el sector sobre si un preprocesador sigue siendo necesario en proyectos nuevos. En la práctica, según se suele comentar en la comunidad, Sass sigue aportando cosas que el CSS nativo todavía no tiene de serie (como los mixins con parámetros, las funciones propias o los parciales/módulos), así que sigue siendo muy usado, especialmente en proyectos grandes.

Ideas clave de esta sección

  • Un preprocesador como Sass se compila a CSS estándar; se puede escribir en sintaxis SCSS (la más usada) o en sintaxis indentada.
  • Las variables ($nombre) guardan valores reutilizables; el anidamiento refleja la jerarquía HTML en el propio CSS.
  • Los parciales (_archivo.scss) se combinan con @use para organizar el proyecto en varios archivos.
  • Los mixins (@mixin / @include) agrupan declaraciones reutilizables y admiten parámetros con valores por defecto.
  • Las funciones propias (@function / @return) permiten calcular valores; Sass también trae operadores matemáticos y funciones ya incluidas.

Glosario rápido

Término En una frase
CSS Lenguaje de hojas de estilo en cascada que define la presentación de un documento web.
Cascada Mecanismo por el que el navegador decide qué regla aplica cuando varias afectan al mismo elemento.
Especificidad El "peso" de un selector: cuanto más concreto, más prioridad tiene.
Selector de clase / id .clase selecciona un grupo de elementos; #id selecciona uno único por documento.
Pseudoclase / pseudoelemento Estilo según un estado (:hover) o una parte de un elemento (::first-letter).
@import Regla CSS que incorpora el contenido de otra hoja de estilos.
Hoja alternativa rel="alternate stylesheet": variante de presentación que el usuario puede elegir.
@media / media="print" Aplican un bloque de CSS solo a un tipo de salida concreto (pantalla, impresión...).
Validador CSS del W3C Herramienta oficial que comprueba que un CSS cumple la especificación.
Viewport Metaetiqueta que indica al navegador móvil que use el ancho real del dispositivo.
Breakpoint Ancho de pantalla a partir del cual una media query cambia el diseño.
Mobile-first Estrategia de diseñar primero para pantallas pequeñas y ampliar después.
Bootstrap Framework CSS basado en componentes prediseñados y una rejilla de 12 columnas.
Tailwind CSS Framework CSS basado en clases de utilidad de un único propósito.
Sass / SCSS Preprocesador de CSS que añade variables, anidamiento, mixins y funciones.
Mixin Bloque de declaraciones CSS reutilizable en Sass, con parámetros opcionales.
Parcial (_archivo.scss) Archivo Sass pensado para incluirse en otro con @use, no para compilarse solo.

Repaso: 8-10 preguntas para autoevaluarte

  1. ¿Qué diferencia hay entre un estilo en línea, una hoja incrustada y una hoja externa vinculada? ¿Cuál de las tres pesa más en la cascada?
  2. Si tienes .especial { color: green; } y h1.especial { color: red; }, ¿de qué color se verá un <h1 class="especial">? ¿Por qué?
  3. ¿Para qué sirve !important y qué riesgo tiene abusar de él?
  4. ¿Qué diferencia hay entre una hoja de estilos "persistente", una "preferida" y una "alternativa" en el atributo rel de <link>?
  5. ¿Qué línea de HTML necesitas casi siempre en el <head> para que el diseño responsive funcione correctamente en un móvil, y qué pasa si no la pones?
  6. Nombra los tres modos que ofrece el validador CSS del W3C para comprobar una hoja de estilos.
  7. ¿Cuántas columnas tiene la rejilla de Bootstrap y cuántos breakpoints por defecto?
  8. ¿Qué diferencia fundamental hay entre el enfoque de Bootstrap y el de Tailwind CSS a la hora de maquetar una interfaz?
  9. ¿Qué es un parcial en Sass y con qué regla se incluye en otro archivo?
  10. Escribe un mixin en Sass que reciba un color de fondo con un valor por defecto y lo aplique junto con un texto en blanco.
Ver respuestas (indicando la sección donde se explican)
  1. Estilo en línea (style="...", UT2-1) < hoja incrustada (<style>, UT2-2) < hoja externa vinculada (<link>, UT2-3) en cuanto a "dónde vive", pero en la cascada pesa más el estilo en línea que la hoja externa vinculada (UT2-3).
  2. Rojo: h1.especial es más específico que .especial (UT2-1).
  3. Da prioridad absoluta a una declaración; abusar de él rompe el orden natural de la cascada y dificulta el mantenimiento (UT2-3).
  4. Persistente se aplica siempre; preferida se aplica por defecto pero se puede sustituir; alternativa está desactivada hasta que el usuario la elige (UT2-3).
  5. <meta name="viewport" content="width=device-width, initial-scale=1">; sin ella, el navegador móvil simula una pantalla ancha y reduce el resultado (UT2-5).
  6. Por URI, por carga de archivo y por entrada directa de texto (UT2-4).
  7. 12 columnas y 6 breakpoints (xs, sm, md, lg, xl, xxl) (UT2-5).
  8. Bootstrap da componentes prediseñados; Tailwind da clases de utilidad de un único propósito que tú combinas (UT2-5).
  9. Un archivo Sass nombrado con guion bajo (_archivo.scss) pensado para incluirse en otro; se incluye con @use (UT2-6).
  10. Ejemplo: @mixin fondo($color: gray) { background: $color; color: white; } y se usa con @include fondo($color: DarkRed); (UT2-6).

De dónde sale esto (fuentes de la carpeta)

  • WEB - MDN - Hojas de estilo alternativas.pdf — hojas de estilo alternativas, tipos (persistente/preferida/alternativa) y soporte actual en navegadores.
  • WEB - MDN - CSS para imprimir.pdf — hoja de estilos para impresión, @media print, @page, eventos de impresión.
  • WEB - MDN - Diseño adaptable (responsive).pdf — historia y fundamentos del diseño responsive, media queries, rejillas fluidas, imágenes fluidas, metaetiqueta viewport.
  • WEB - W3C - Validador CSS (manual).pdf — manual del Servicio de Validación de CSS del W3C: modos de validación, errores/advertencias, parámetros avanzados y API.
  • WEB - Bootstrap 5 - Introducción.pdf — instalación vía CDN, doctype HTML5, viewport, box-sizing, Reboot, componentes que requieren JavaScript.
  • WEB - Bootstrap 5 - Rejilla (grid).pdf — sistema de rejilla de 12 columnas, breakpoints, contenedores, columnas automáticas.
  • WEB - Tailwind CSS - Clases de utilidad.pdf — filosofía utility-first, ejemplo de tarjeta con clases de utilidad, variantes de estado.
  • WEB - Tailwind CSS - Diseño responsive.pdf — prefijos de breakpoint, tabla de breakpoints por defecto, ejemplo responsivo completo.
  • WEB - Sass - Guía básica.pdf — variables, anidamiento, parciales, módulos (@use), mixins, @extend/herencia, operadores.
  • WEB - Sass - Funciones.pdf — declaración de funciones (@function/@return), argumentos opcionales, ejemplo invert().
  • DIW04.pdf — fuente histórica (hacia 2012, centrada en CSS2/CSS2.1): estilos en línea, incrustados y externos, cascada, especificidad, selectores, pseudoclases/pseudoelementos y el diagrama de hojas externas vinculadas. Se ha usado como base de UT2-1 a UT2-3 porque esos fundamentos de CSS no han cambiado, contrastando los datos de versión con las fuentes «WEB -» más recientes.
  • TE11UD1 Ejercicio Bootstrap Grids ENUNCIADO.pdf — enunciado de práctica con la rejilla de Bootstrap; se ha aprovechado su imagen comparativa de la rejilla en distintos tamaños.
  • Django y SASS.pdf — guía de instalación de Sass en un entorno Django/Windows; es un tutorial de puesta en marcha de un proyecto concreto, no aporta contenido de temario sobre variables, mixins o funciones de Sass, así que no se ha usado como fuente de conceptos.