Diseño de interfaces web
cover

Interfaces de usuario

1 Introducción

Una interfaz (en plural: interfaces) se utiliza en informática para nombrar a la conexión funcional entre dos sistemas, programas, dispositivos o componentes de cualquier tipo, que proporciona una comunicación de distintos niveles, permitiendo el intercambio de información.

Ejemplos:

  • Interfaces de usuario: cuando un usuario final hace uso de un programa.
  • Dispositivo de interfaz humana: de las siglas en inglés HID (human interface device), cuando hacemos referencia al interfaz hardware que utilizamos los humanos para interactuar con el ordenador
  • Interfaz física: un componente que se conecta a otro (puerto USB o puerto SATA).

2 Interfaces de usuario

Una interfaz de usuario (User Interface o UI) es el conjunto de elementos visuales e interactivos que permiten a una persona comunicarse con una aplicación o un sistema informático. Gracias a ellas podemos realizar acciones como pulsar un botón, seleccionar una opción de un menú, o navegar entre distintas páginas.

Normalmente suelen ser fáciles de entender y fáciles de utilizar, aunque en el ámbito de la informática es preferible referirse a que suelen ser “usables, amigables e intuitivas”.

Actualmente, las interfaces continúan evolucionando y ya no se limitan únicamente a pantallas con botones. Existen interfaces táctiles, asistentes por voz, realidad aumentada, realidad virtual e incluso sistemas capaces de interpretar gestos.

2.1 La interfaz como medio de comunicación

Puede resultar útil imaginar la interfaz como un traductor entre el usuario y el ordenador (o aplicación). El usuario expresa lo que desea hacer mediante acciones sencillas que el programa transforma en instrucciones que él mismo puede comprender y ejecutar, para después devolver información al usuario. Por tanto, la comunicación es bidireccional.

2.2 Características de una buena interfaz

Una buena interfaz debe permitir que el usuario consiga sus objetivos con el menor esfuerzo posible. Entre sus principales características destacan:

  • Simplicidad: Una interfaz sencilla contiene únicamente los elementos necesarios. Sobrecargar la pantalla con botones, colores o información que no son necesarios para la acción a realizar suele provocar confusión.
  • Claridad: Los elementos deben indicar claramente su función. El usuario no debería tener que adivinar qué hace cada elemento. Ejemplo:
    • “Guardar” es más claro que “Aceptar”.
    • Un icono de una papelera suele representar la acción de eliminar.
    • Un icono de una lupa suele representar una búsqueda.
  • Consistencia: Todos los elementos similares deben comportarse de forma similar. La consistencia permite que el usuario aprenda rápidamente cómo funciona la aplicación.
  • Rapidez: La interfaz debe responder inmediatamente a las acciones del usuario. En caso de que una operación tarde varios segundos en completarse, la aplicación debe mostrar algún tipo de respuesta:
    • Un indicador de carga.
    • Una barra de progreso.
    • Un mensaje informativo.
  • Accesibilidad: Todas las personas deberían poder utilizar la aplicación independientemente de sus capacidades.
  • Adaptabilidad: La interfaz debe adaptarse correctamente a cualquier tamaño de pantalla.

2.3 La importancia de la primera impresión

Diversos estudios sobre experiencia de usuario muestran que una persona suele formarse una opinión inicial sobre una página web en apenas unos segundos. Durante ese breve tiempo el usuario decide si:

  • La página parece profesional.
  • Encuentra fácilmente la información.
  • Confía en el sitio.
  • Continúa navegando o abandona la página.

Por este motivo, el diseño visual tiene un impacto directo sobre la percepción de calidad de una aplicación. Pero es importante recordar que una interfaz bonita no tiene por qué ser una buena interfaz.

Una interfaz bonita no tiene por qué ser una buena interfaz

3 Evolución de las interfaces de usuario

Hoy en día podemos diferenciar entre 3 tipos:

  • Interfaz de línea de comandos (Command-Line Interface, CLI): Interfaces alfanuméricas (intérpretes de comandos) que solo presentan texto o interfaces simples generadas con texto y caracteres especiales.
  • Interfaz gráfica de usuario (Graphic User Interface, GUI): Permiten comunicarse con la computadora de forma rápida e intuitiva representando gráficamente los elementos de control y medida.
  • Interfaz natural de usuario (Natural User Interface, NUI): Pueden ser táctiles, representando gráficamente un “panel de control” en una pantalla sensible al tacto que permite interactuar con el dedo de forma similar a si se accionara un control físico; pueden funcionar mediante reconocimiento del habla, como por ejemplo Siri; o mediante movimientos corporales (como es el caso del antiguo Kinect o las actuales Vision Pro de Apple).

En la Wikipedia está la historia de las interfaces gráficas de las que aquí se va a hacer un resumen.

3.1 Interfaz de línea de comandos

La interfaz de línea de comandos o interfaz de línea de órdenes (en inglés: command-line interface, CLI) es un tipo de interfaz de usuario de ordenador que permite a los usuarios dar instrucciones a algún programa informático o al sistema operativo por medio de una línea de texto simple.

Las CLI pueden emplearse interactivamente, escribiendo instrucciones en alguna especie de entrada de texto, o pueden utilizarse de una forma mucho más automatizada (archivo batch), leyendo órdenes desde un archivo de scripts.

Esta interfaz existe casi desde los comienzos de la computación, superada en antigüedad solo por las tarjetas perforadas y mecanismos similares. Los ordenadores tenían conectadas “terminales tontas” que permitían enviar comandos al ordenador.

Terminal VT100. Fuente: Wikipedia

Hoy en día la línea de comandos se utiliza a través de programas denominados “emulador de terminales” que ejecutan un intérprete de comandos (llamado “shell”). Estos intérpretes, dependiendo del sistema operativo se pueden elegir, por ejemplo:

  • En Windows se puede hacer uso del antiguo cmd o el más nuevo y mejorado PowerShell. También se puede utilizar otros, pero no vienen de serie instalados (como bash)
  • En sistemas GNU/Linux el intérprete más utilizado y que está instalado en la gran mayoría de distribuciones es bash. En los últimos años ha ganado mucho mercado zsh gracias al framework Oh-my-zsh.
  • En sistemas MacOS el intérprete por defecto es zsh.
Interfaz BASH. Fuente: Wikipedia

Los conceptos de CLI, shell y emulador de terminal no son lo mismo ya que CLI se refiere al paradigma, mientras que un shell o un emulador de terminal son programas informáticos específicos, que usualmente en conjunto implementan la CLI. Sin embargo, los tres suelen utilizarse como sinónimos.

Ventajas Inconvenientes
● Muy rápida para usuarios expertos. ● Requiere memorizar comandos.
● Gran capacidad de automatización. ● Poco intuitiva para principiantes.

3.2 Interfaz gráfica de usuario

La interfaz gráfica de usuario, conocida también como GUI (del inglés graphical user interface), es un programa informático que actúa de interfaz de usuario, en la que hoy en día utilizando un conjunto de imágenes y objetos gráficos para representar la información y acciones disponibles en la interfaz.

Su función principal es proporcionar un entorno visual sencillo para permitir la comunicación con el sistema operativo de un ordenador.

3.2.1 Interfaz en modo texto

Las interfaces gráficas no nacen con los escritorios, si no que ya en pasos anteriores existen librerías que simulan ventanas o entornos haciendo uso de caracteres de texto y colores.

FreeDos Edit. Fuente: Wikipedia
Midnight Commander. Fuente: Wikipedia

Hay que tener en cuenta que estos interfaces se solían utilizar en máquinas con muy pocos recursos y con sistemas operativos en los que no existía un interfaz gráfica.

3.2.2 Primeras investigaciones y desarrollos

El proyecto de “Aumento del Intelecto Humano” de Doug Engelbart en el Stanford Research Institute (en Menlo Park, EE. UU.) en la década de los 60 desarrolló el oN-Line System, que incorporaba un cursor manejado con un ratón y múltiples ventanas usadas para trabajar con hipertexto.

Mucha de la investigación inicial estuvo basada en como los niños pequeños aprenden. Por lo que el diseño se basó en las primitivas infantiles de coordinación mano-ojo, en lugar de usar lenguajes de comandos.

El primer prototipo de un ratón. Fuente: Wikipedia

El GUI fue inicialmente desarrollado en Xerox PARC (Palo Alto Research Center) por Alan Kay, Larry Tesler, Dan Ingalls y algunos investigadores más. Usaba ventanas, iconos y menús, incluyendo el primer menú desplegable fijo, para dar soporte a comandos como abrir ficheros, borrar y mover ficheros, etc.

En 1981 Xerox presentó un producto innovador, el Star, incorporando muchas de las innovaciones de PARC. Aunque no fue un éxito comercial, el Star influenció de manera importante los futuros desarrollos, por ejemplo en Apple, Microsoft y Sun Microsystems.

En 1979, el equipo encabezado por Steve Wozniak, Steve Jobs y Jef Raskin (junto con antiguos trabajadores de Xerox) continuaron con las ideas vistas en Xerox PARC para lanzar en 1983 el ordenador “Apple Lisa”, el primer ordenador con interfaz gráfico. No fue un éxito en ventas, pero inició la era de lo que se podrían denominar “los sistemas operativos con escritorio”.

El interfaz gráfico de LisaOS 1.0. Fuente: GUI Gallery

En 1984 Apple lanzó el Macintosh, el cual presentó una evolución del sistema operativo de Lisa, llamado “System”, en el que se puede apreciar partes que apenas han cambiado desde entonces.

El interfaz gráfico del Macintosh. Fuente: GUI Gallery

Al año siguiente Microsoft sacaría Windows 1.0, que era un GUI para su sistema operativo MS-DOS, pero no sería hasta la versión de Windows 3.0 de 1990 en la que su popularidad explotó.

El interfaz gráfico de Windows 3.0. Fuente: GUI Gallery

3.3 Uso masivo del escritorio

Con la llegada de la década de 1990, en la que los ordenadores personales (PC, del inglés personal computer) se popularizan y empiezan a llegar a las casas y negocios, hizo que se creara un mercado de usuarios sin conocimientos avanzados que requerían de facilidades de uso.

El “boom” comenzó con el Windows 3.11, pero sobre todo con Windows 95, que consiguió ocultar el núcleo del sistema operativo subyacente (MS-DOS) para mostrar directamente el interfaz gráfico desde el inicio.

El interfaz gráfico de Windows 95 en el primer arranque. Fuente: GUI Gallery

Apple compra a NeXT (empresa fundada por Steve Jobs) y utiliza su sistema operativo como los cimientos de Mac OS 8. Posteriormente cambiarían la arquitectura del sistema operativo para ser de estilo UNIX y así presentar Mac OS X en 2001.

Mac OS X 10.1 en 2001. Fuente: GUI Gallery

Durante estos años y principios de los 2000, los interfaces de usuario van evolucionando a medida que evoluciona la potencia de los ordenadores, pero siguiendo la misma tónica de simular un escritorio real en el ordenador.

Se anuncian entornos de escritorio libres como Gnome y KDE, que evolucionan en paralelo dentro de mundo de GNU/Linux llegando a crearse casi una guerra entre ellos y entre los usuarios (Enlace 1, Enlace 2).

Cada sistema operativo y cada sistema de escritorio realizaba sus propias evoluciones que si tenían calado eran “copiadas” en los otros, generando también ciertas “modas” en colores, iconos o efectos de ventanas.

Evolución de KDE en 1998, 2000 y 2005. Fuente: Wikipedia

3.4 Interfaces web

Entre finales de los 90 y principios de los 2000, el auge de internet en todo el mundo hace que los portales web también sufran una gran evolución en sus interfaces.

Evolución de la web de Amazon. Fuente: VersionMuseum

También hay que tener en cuenta que las versiones HTML y CSS de la época no era tan avanzado como lo son hoy, y que las posibilidades de ejecución de javascript tampoco era tan potente como lo es hoy en día. Las interfaces pueden verse limitadas por la propia tecnología

Las interfaces pueden verse limitadas por las tecnologías del momento

Por otro lado, es habitual que la imagen de la compañía cambie, ya sea por cambios de logotipo, colores corporativos, moda en el tono de los colores... y todo eso también hace que los interfaces sufran modificaciones.

Evolución del logotipo de Twitter/X.

3.5 Interfaces móviles

En el caso de los teléfonos móviles, debido a que no existía un sistema estándar de visualización, cada fabricante iba creando su propio interfaz a medida que las pantallas iban creciendo en tamaño, resolución, colores...

Los primeros móviles carecían de pantalla, posteriormente comenzaron a tener pequeñas pantallas LCD monocromas, en algunos casos con una única línea de texto.

Ericsson T10 y Nokia 3310

Posteriormente comenzaron a tener pantallas a color y cada compañía crea su propio sistema operativo. Existe un intento de crear un sistema operativo entre varias compañías llamado Symbian, pero al final es Nokia la desarrolladora y la que más uso le da.

Durante los primeros años de la década de los 2000 también se ponen de moda las PDA (personal digital assistant, asistente digital personal u ordenadores de bolsillo), que normalmente hacían uso de un lapiz para hacer funcionar la pantalla táctil (resistiva) que tenían.

Palm

Todo cambió con la llegada del iPhone en el 2007 y los primeros smartphones, donde las pantallas táctiles capacitativas (se manejan con el dedo) cobran protagonismo. Estas pantallas aparte de ser táctiles también permiten gestos con varios dedos, dando lugar a nuevos efectos de interactuar con el interfaz.

iPhone 1ª generación y HTC Desire.

Apple se decanta por un único botón mientras que los sistemas operativos Android (como el HTC Desire del 2009) tienen al menos cuatro para manejar ciertas tareas del sistema y de la aplicación que se está usando en el momento.

Con estos cambios, los sistemas operativos y las interfaces sufren un cambio radical, donde buscan la facilidad del usuario y aparecen los “gestos” como nueva manera de interactuar con el interfaz:

  • Tap: tocar la pantalla (similar al “click” con el ratón)
  • Double tap: doble toque, que dependiendo de la aplicación puede hacer un zoom específico.
  • Scroll: presionando con el dedo y subiendo para arriba o para abajo se hace scroll sobre el interfaz.
  • Flick: si se hace un gesto rápido hacía arriba o hacia abajo se hace scroll, mientras que si es a izquierda o derecha el movimiento dependerá de si hay más pantalla.
  • Pinch in: hacer zoom acercando lo que se quiere ver.
  • Pinch out: hacer zoom alejando el objeto.

Con todo ello, surge un nuevo “problema” que hasta este momento no se había planteado en los interfaces, que es la rotación del dispositivo. Esta rotación debe hacer que la aplicación que se está ejecutando se adapte a la nueva posición del terminal, pasando de vertical a horizontal o viceversa.

Vista vertical y horizontal de la app Music de iOS

Como evolución de estos dispositivos surgen las tablets en donde se sigue la misma filosofía de gestos, pero las pantallas táctiles de mayor tamaño permiten tener más espacio para información. En lugar de usar los interfaces de escritorio, evolucionan los interfaces de los móviles.

Al tener más espacio, no se utilizan las aplicaciones de móviles y se “escalan”, si no que surgen nuevas posibilidades para que los interfaces dispongan de nuevos menús o lugares donde añadir más información.

Vista de la app Music de iOS en iPhone e iPad. Fuente: 9to5mac

Al diseñar un interfaz tenemos que tener en cuenta el dispositivo, las dimensiones y el uso que se le va a dar para mejorar la experiencia de usuario.

3.6 Realidad virtual y realidad aumentada

El siguiente paso en el desarrollo de interfaces se encuentra en la conocida como realidad aumentada y en la realidad virtual. Aunque puedan parecer términos que están ahora de moda, su estudio y evolución lleva décadas fraguándose.

Los primeros pasos que se dieron en este sentido son los denominados “head-up display”, que son pantallas transparentes que presentan información al usuario dejando ver lo que está en la parte trasera de la pantalla. De esta manera, el usuario no tiene que girar la cabeza para obtener la información.

Ejemplo de interfaz head-up en un avión. Fuente:Wikipedia

En algunos casos esta pantalla puede estar entre el usuario y el salpicadero, integrada en el salpicadero o también como una pantalla puesta en el casco del piloto y cerca del ojo.

Por otro lado, tenemos la realidad virtual, que es un entorno simulado que da una sensación de inmersión al usuario ofreciéndole la posibilidad de moverse en él, y en algunos casos interactuar con elementos del entorno.

Para ello, suele ser habitual contar con unas gafas que nos mostrarán el entorno virtual, y también dispondremos de unos mandos para poder interactuar con el entorno.

Casco y mandos del HTC Vive

Para poder movernos por el entorno, algunos de estos sistemas hacen uso de trackers, de esta manera nos podremos desplazar por el entorno virtual sin tener que usar los mandos.

El siguiente paso es la conocida como realidad aumentada, en el que se trata de integrar elementos virtuales en la vida real. No es algo nuevo, ya que lleva años existiendo en juegos y aplicaciones.

Ejemplos de realidad aumentada con el móvil

Cn la idea de que la realidad aumentada sea de uso cotidiano han empezado a evolucionar los sistemas para que poco a poco esto vaya fraguando, aunque el coste todavía sigue siendo elevado. A día de hoy, tampoco está claro cuál será el beneficio y el rendimiento que tendrá.

En el caso de las Apple Vision Pro prometen una experiencia de realidad aumentada utilizando únicamente gestos de las manos para moverse a través de su interfaz.

Apple Vision Pro

3.7 Interfaces por voz

La primera herramienta que permitió ejecutar reconocimiento digital de voz fue presentado en 1962. Aunque hubo distintas aplicaciones y asistentes virtuales antes, no fue hasta la aparición de Siri en 2010 cuando su uso pasó al gran público.

Los interfaces por voz hoy en día están asociados al teléfono móvil y a los asistentes virtuales que son capaces de reconocer lenguaje natural y ejecutar las acciones que se les pide. Los asistentes más conocidos son Siri, Alexa y Google Assistant.

4 Curiosidades, prototipos y ciencia ficción

En este apartado se van a añadir algunos ejemplos de interfaces que son reales, pero que no dejan de ser meras curiosidades, ejemplos de prototipos de interfaces que de momento no han llegado a nada, y la visión en algunos casos que nos da las películas de ciencia ficción.

  • Demonstración de 1982 de posibles usos de tecnología táctil en pantallas. Realmente la pantalla no es táctil, tiene sensores alrededor de ella. Vídeo.

  • En Jurassic Park aparece un interfaz para navegar un sistema de ficheros en 3D. It’s UNIX!.

  • La película Minority Report del 2002 muestra un interfaz que se utiliza con las manos. Vídeo.

  • En 2003 Microsoft muestra un vídeo de lo que será su próximo Windows, llamado Longhorn. Este interfaz nunca llegó a la versión final, aunque sí que hubo versiones de demonstración que se parecían un poco, pero la versión final que se llamó Vista nunca llegó a ser como los primeros conceptos.

  • En 2006, con la aceleración de OpenGL por hardware en las tarjetas gráficas, en las distribuciones GNU/Linux nacen los gestores de ventanas con diseños 3D real. Hubo varias alternativas, ya que surgieron varios “forks” de distintos proyectos, pero los más conocidos fueron Compiz y Beryl. Vídeo.

  • En 2006 en una charla TED Jefferson Han realiza una demonstración de pantalla multitáctil con muchos gestos que posteriormente se volverían el día a día con los smartphones. Charla TED y Vídeo de demonstración.

  • En 2009 Microsoft presenta un vídeo con el concepto de una tablet plegable llamada Courier. Vídeo 1, Vídeo 2. El iPad todavía no se había presentado.

    • Microsoft tiene varias páginas con conceptos de interfaces para tablets plegables en su web. Enlace 1, Enlace 2.
  • Las películas de Iron Man han ofrecido muchas escenas donde aparecen interfaces muy espectaculares, a nivel holográfico y de realidad aumentada. Vídeo.

  • Película Her en la que se ve la relación entre un humano y su asistente virtual.

Evolución del diseño web

5 Introducción

Cuando navegamos por Internet es fácil pensar que las páginas web siempre han tenido un aspecto similar al actual. Sin embargo, el diseño web ha evolucionado enormemente desde la creación de la World Wide Web a principios de los años noventa.

Las primeras páginas eran muy sencillas y estaban formadas casi exclusivamente por texto. Con el paso de los años aparecieron nuevas tecnologías que permitieron incorporar imágenes, estilos, animaciones e interfaces mucho más elaboradas.

Conocer esta evolución permite comprender por qué existen determinadas tecnologías, cómo han surgido los estándares actuales y cuáles son las buenas prácticas que deben seguirse en el desarrollo de interfaces web.

6 Historia del diseño web

6.1 Los primeros años: páginas web estáticas

En 1991 Tim Berners-Lee comienza el desarrollo de HTML en el CERN. No sólo creó el lenguaje HTML si no que creó el protocolo HTTP (HyperText Transfer Protocol) y el primer servidor web.

Primer servidor Web

Las primeras páginas web estaban escritas en HTML y tenían una estructura extremadamente simple. No existía ninguna separación entre contenido y presentación. El propio HTML indicaba tanto la estructura como la apariencia del documento.

Durante estos primeros años aparecieron navegadores como:

6.2 La guerra de los navegadores (1995-2000)

A mediados de los años noventa Internet comenzó a crecer rápidamente. Microsoft lanzó Internet Explorer, mientras que Netscape seguía dominando el mercado. Ambas empresas comenzaron una intensa competencia por incorporar nuevas características antes que su rival.

Este periodo se conoce como la guerra de navegadores debido a que cada navegador implementaba nuevas etiquetas HTML propias. Como consecuencia:

  • Una página podía funcionar correctamente en un navegador y presentar errores en otro.
  • Los desarrolladores debían crear versiones específicas para distintos navegadores.
  • El mantenimiento de los sitios web resultaba complicado.

Era habitual que las webs tuviesen mensajes como “Sitio optimizado para Internet Explorer” o “Compatible con Netscape Navigator” debido a esta problemática.

6.2.1 Tablas para maquetar el contenido

Como todavía no existía CSS con un soporte amplio, muchos desarrolladores utilizaban las tablas HTML para organizar el contenido.

Tabla para maquetar

<table>
    <tr>
        <td>Menú</td>
        <td>Contenido</td>
    </tr>
</table>

Las tablas habían sido diseñadas para mostrar datos tabulares, no para crear diseños completos, pero durante años fueron la herramienta principal para construir páginas web. Hoy en día esta práctica está totalmente desaconsejada.

6.3 La aparición de CSS

En 1996 apareció CSS (Cascading Style Sheets), cuyo objetivo fue resolver uno de los principales problemas del desarrollo web: separar el contenido de la presentación.

HTML

<h1>Título</h1>

CSS

h1{
    color: blue;
    text-align:center;
}

Desde ese momento:

  • HTML describía la estructura.
  • CSS controlaba el aspecto visual.

Esta separación ofrecía numerosas ventajas:

  • Código más limpio.
  • Mayor facilidad de mantenimiento.
  • Reutilización de estilos.
  • Mejor accesibilidad.
  • Diseño uniforme en todo el sitio web.

Aunque CSS apareció en 1996, pasaron varios años hasta que los navegadores comenzaron a implementarlo correctamente.

6.4 La Web 2.0

A comienzos de los años 2000 Internet cambió profundamente. Los usuarios dejaron de ser simples lectores para convertirse también en creadores de contenido. A este periodo se le conoce como Web 2.0.

Las páginas web comenzaron a incorporar:

  • Blogs.
  • Redes sociales.
  • Wikis.
  • Comentarios.
  • Foros.
  • Comercio electrónico.

El diseño también evolucionó considerablemente. Se hicieron populares:

  • Grandes botones.
  • Sombras.
  • Degradados.
  • Bordes redondeados.
  • Iconos coloridos.
  • Menús más elaborados.

6.5 HTML5 y CSS3

En torno a 2010 comenzaron a consolidarse dos grandes estándares: HTML5 y CSS3, que transformaron completamente el desarrollo web. Entre las novedades más importantes encontramos:

HTML5 CSS3
● Etiquetas semánticas.
● Vídeo nativo.
● Audio nativo.
● Canvas.
● SVG.
● Formularios más completos.
● Bordes redondeados.
● Sombras.
● Gradientes.
● Animaciones.
● Transformaciones.
● Media Queries.

6.6 El auge de los dispositivos móviles

En 2007 apareció el primer iPhone, y aunque ya había dispositivos móviles que permitían navegar por Internet, ninguno llegaba a la calidad de renderizado de este, ya que era un navegador real. Poco después comenzaron a popularizarse los teléfonos inteligentes, lo que hizo que cambiase completamente la forma de navegar por Internet.

Los diseñadores ya no podían crear páginas únicamente para monitores de escritorio, ya que ahora era necesario pensar en:

  • Pantallas pequeñas.
  • Pantallas táctiles.
  • Distintas resoluciones.
  • Diferentes orientaciones.

6.6.1 Responsive Web Design

En 2010 Ethan Marcotte popularizó el término Responsive Web Design. Su propuesta consistía en crear páginas capaces de adaptarse automáticamente al tamaño de cualquier pantalla.

Para ello comenzaron a utilizarse:

  • Diseños fluidos.
  • Media Queries.
  • Imágenes adaptables.
  • Unidades relativas.

Actualmente el diseño responsive es un requisito imprescindible en prácticamente cualquier sitio web.

Fuente: Wikipedia y Stéphanie Walter

6.7 La llegada de Flexbox y CSS Grid

Durante muchos años crear diseños complejos mediante CSS resultaba complicado. Se utilizaban técnicas como float, tablas y posicionamientos absolutos.

Estas soluciones eran poco flexibles y difíciles de mantener. Esto cambió con la llegada de flexbox y CSS Grid, que permitió un salto de calidad y mantenimiento en la maquetación. Hoy en día ambos sistemas constituyen la base del diseño moderno.

6.8 Evolución en el diseño

Durante muchos años las interfaces intentaban imitar objetos reales. Esta filosofía recibe el nombre de skeuomorfismo:

  • Los botones parecían botones físicos.
  • Las carpetas parecían carpetas reales.
  • Los calendarios imitaban calendarios de papel.
Ejemplo skeuomorfismo en iOS 6. Fuente: AppleInsider

A partir de 2012 comenzó a imponerse una tendencia completamente distinta denominada Flat Design. Sus características principales son:

  • Colores sólidos.
  • Pocos efectos visuales.
  • Ausencia de texturas.
  • Sombras mínimas.
  • Diseño limpio.
  • Iconos sencillos.

Microsoft fue uno de los primeros grandes impulsores de este estilo con Windows Phone. Posteriormente Apple y Google adoptaron diseños similares. En 2014 Google presentó Material Design, que no se trataba únicamente de un conjunto de estilos visuales, sino de un completo sistema de diseño. Material Design define:

  • Colores.
  • Tipografías.
  • Animaciones.
  • Iconografía.
  • Espaciados.
  • Componentes reutilizables.

Su objetivo era ofrecer una experiencia consistente en todas las aplicaciones de Google. Hoy continúa evolucionando y es uno de los sistemas de diseño más influyentes del desarrollo web.

6.9 Mirando hacia el futuro

El diseño web continúa evolucionando constantemente. Algunas tendencias actuales son:

  • Modo oscuro (Dark Mode).
  • Aplicaciones web progresivas (PWA).
  • Microanimaciones y animaciones discretas.
  • Diseño basado en componentes.
  • Sistemas de diseño compartidos.
  • Accesibilidad desde las primeras fases del desarrollo.
  • Alto rendimiento.

Aunque las herramientas cambian con rapidez, los principios fundamentales de un buen diseño permanecen prácticamente inalterables.

Una página web desarrollada hace más de veinte años sigue pudiendo visualizarse en un navegador moderno. Esta compatibilidad hacia atrás ha sido una de las claves del enorme éxito de la Web.

Introducción a CSS

7 Historia de CSS

En los primeros años de la World Wide Web, las páginas web eran muy diferentes a las actuales. Su objetivo principal era compartir información y documentos entre investigadores, por lo que el aspecto visual tenía una importancia secundaria.

7.1 El problema de HTML

HTML nació como un lenguaje para describir la estructura de un documento, no su apariencia, por lo que se podía definir el contenido mediante títulos, párrafos, listas y enlaces, pero apenas ofrecía opciones para controlar la presentación del documento. Esto provocaba que la mayoría de las páginas tuvieran un aspecto muy similar: fondo gris, texto negro, enlaces azules y una distribución muy sencilla.

A medida que Internet comenzó a popularizarse, empresas y organizaciones quisieron crear páginas con un aspecto más atractivo y diferenciado. Sin embargo, HTML no había sido diseñado para ello. No existía ningún mecanismo para definir aspectos como:

  • Colores.
  • Márgenes.
  • Tipografías.
  • Espaciados.
  • Posición de los elementos.

7.2 La llegada de etiquetas de presentación

Como los diseñadores querían controlar el aspecto de las páginas, los navegadores comenzaron a incorporar etiquetas HTML relacionadas con la presentación como por ejemplo: <font>, <center>, <big>

Estas etiquetas solucionaban parcialmente el problema, pero generaban otros nuevos, como que si queríamos añadir el tipo de fuente se lo teníamos que especificar a todos los textos. Aparte, se mezclaba el contenido con la presentación, el mantenimiento era costoso y cada navegador interpretaba algunas etiquetas de forma distinta, o no las interpretaba directamente.

7.3 El nacimiento de CSS

Para solucionar estos problemas, en 1994 el informático noruego Håkon Wium Lie propuso un nuevo lenguaje denominado Cascading Style Sheets, más conocido por sus siglas CSS. Su propuesta consistía en separar completamente dos aspectos diferentes:

  • HTML describiría el contenido y la estructura.
  • CSS definiría únicamente la apariencia.

La idea fue muy bien recibida y, junto con otros colaboradores como Bert Bos, evolucionó hasta convertirse en un estándar del W3C, y en diciembre de 1996 se publicó la primera recomendación oficial: CSS Level 1 (CSS1). Permitía modificar aspectos como:

  • Colores.
  • Tipografías.
  • Márgenes.
  • Sangrías.
  • Alineación del texto.
  • Fondos.

7.4 CSS2

En 1998 apareció CSS2, incorporando numerosas mejoras. Entre ellas destacaban:

  • Posicionamiento absoluto.
  • Posicionamiento relativo.
  • Tipos de medios (pantalla, impresión…).
  • Capas.
  • Nuevos selectores.
  • Tablas más completas.

Gracias a CSS2 comenzaron a desarrollarse diseños mucho más complejos. Sin embargo, los navegadores todavía presentaban importantes diferencias en su implementación. Durante muchos años era habitual que una página funcionara correctamente en un navegador y mostrara errores en otro.

7.5 CSS3: una nueva forma de evolucionar

En lugar de crear una única especificación enorme, el W3C decidió dividir CSS en pequeños módulos independientes. Aunque popularmente hablamos de CSS3, en realidad no existe un documento oficial llamado “CSS3”. Actualmente CSS está formado por numerosos módulos, cada uno con su propio ritmo de desarrollo. Algunos ejemplos son:

  • Selectores.
  • Fondos y bordes.
  • Animaciones.
  • Transiciones.
  • Flexbox.
  • Grid Layout.
  • Variables CSS.
  • Media Queries.

Este sistema permite incorporar nuevas funcionalidades sin esperar años para publicar una nueva versión completa.

7.6 El nacimiento de los preprocesadores CSS

Para resolver estas limitaciones aparecieron los llamados preprocesadores CSS. Un preprocesador permite escribir en un lenguaje más potente y cómodo que posteriormente se transforma automáticamente en CSS estándar. Los dos preprocesadores más conocidos son:

  • SASS: nace en 2006 y permite crear variables, anidamiento, sistema de mixins (podría definirse como funciones) para no tener que repetir código, herencia, bucles …
  • LESS: nace en 2009 inspirado por SASS y la ventaja es que mediante JavaScript permite ejecutarse en el navegador sin tener que preprocesarse previamente.

Hasta hace unos años prácticamente todos los grandes proyectos utilizaban SASS o LESS internamente, ya que permitían:

  • Reducir la repetición de código.
  • Organizar grandes proyectos.
  • Reutilizar componentes.
  • Facilitar el mantenimiento.
  • Trabajar en equipo.
  • Automatizar tareas.

En aquella época CSS todavía no disponía de muchas de estas características.

Con el paso del tiempo CSS ha ido incorporando muchas funciones como variables, nuevos selectores, algunas funciones matemáticas, … Como consecuencia, muchos proyectos pequeños y medianos ya pueden desarrollarse utilizando únicamente CSS.

Sin embargo, SASS sigue siendo muy utilizado en proyectos grandes porque continúa ofreciendo ventajas relacionadas con la organización del código y la reutilización de estilos.

7.7 CSS en la actualidad

Hoy en día CSS es un lenguaje extremadamente potente y en continua evolución en el que participan distintas empresas para proponer nuevas características para ser añadidas.

8 Añadir CSS en una página HTML

Para que una página HTML pueda utilizar una hoja de estilos, es necesario indicar al navegador dónde se encuentra el archivo CSS. La forma más habitual consiste en utilizar el elemento <link> dentro de la sección <head> del documento HTML.

Añadir CSS en un HTML

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Mi primera página con CSS</title>
    <link rel="stylesheet" href="css/estilos.css">
</head>
<body>
    <h1>Hola mundo</h1>
</body>
</html>

En este ejemplo el navegador carga el archivo estilos.css situado dentro de la carpeta css, antes de mostrar la página. El atributo rel="stylesheet" indica que el archivo enlazado es una hoja de estilos, mientras que href especifica la ruta del archivo CSS.

8.1 Incorporar varias hojas de estilo

En proyectos reales es muy habitual dividir el código CSS en varios archivos para facilitar su mantenimiento. En ese caso el navegador descargará y aplicará todas las hojas de estilo en el orden en el que aparecen. Cuando varias hojas de estilo modifican la misma propiedad de un mismo elemento, el orden en el que se cargan puede afectar al resultado final.

Añadir varios CSS en un HTML

<head>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/estilos.css">
    <link rel="stylesheet" href="css/titulos.css">
</head>

Siguiendo con el ejemplo anterior, supongamos que contienen el siguiente código:

estilos.css

h1 {
    color: blue;
}

titulos.css

h1 {
    color: red;
}

El color final del título será rojo, ya que la segunda hoja de estilos sobrescribe la primera. Este comportamiento forma parte del mecanismo conocido como cascada (cascade), que estudiaremos con detalle más adelante.

El orden de carga de los ficheros es importante.

No existe un número fijo de archivos CSS que deba tener un proyecto. En aplicaciones pequeñas suele ser suficiente con una única hoja de estilos, pero a medida que el proyecto crece, resulta habitual dividir el código en varios archivos según su función.

01

Carga dos ficheros CSS y comprueba la importancia del orden tal como aparece en el ejercicio anterior.

8.2 CSS interno

Se puede escribir estilos CSS dentro de una página HTML directamente usando las etiquetas <style> y tiene que estar dentro de la cabecera <head>.

HTML+CSS inline

<html>
  <head>
    <style>
      body {
        background-color: linen;
      }  
      h1 {
        color: maroon;
        margin-left: 40px;
      }
    </style>
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

No se recomienda usar CSS interno dentro de un HTML.

Existen sistemas para generar HTML unificado (para generar HTML auto-contenidos) para generar webs estáticas, pero durante el desarrollo no se debe usar CSS dentro del HTML.

8.3 Estilos CSS inline

Se puede utilizar estilos CSS dentro del código HTML, lo que se denominan estilos inline. Esta técnica era muy utilizada al inicio de la web, pero no es recomendable usarla ya que va en contra de la reutilización de los estilos CSS.

También va en contra de la separación entre maquetación y estilos, lo que puede dificultar la reutilización de componentes en distintos apartados de una misma aplicación. En el siguiente ejemplo se ve un ejemplo de estilo inline y cómo sería con HTML y CSS separado:

HTML+CSS inline

<p style="
 color: red;
 font-style: italic;
">
    Texto
</p>

HTML

<p class="special">
    Texto
</p>

CSS

.scpecial {
  color: red;
  font-style: italic;
}

En el primer ejemplo, si quisiésemos otro p con el mismo estilo, habría que volver a escribir dicho estilo, mientras que con la separación sólo sería necesario poner la clase. Si en el primer ejemplo queremos añadir un nuevo estilo, habría que modificarlo en varios sitios, mientras que con la separación sólo sería necesario hacerlo en la hoja CSS.

No se recomienda usar estilos inline.

8.4 Ejemplos de la importancia de CSS

Las hojas de estilo CSS nos permiten hacer que una página web se vea completamente diferente cambiando dicha hoja de estilo. Imaginemos una empresa que tiene un producto de tienda online para varios clientes.

  • Los estilos CSS están inline, modificar los estilos para cada cliente supondría:
    • Copiar todo el código fuente.
    • Modificar los estilos inline.
    • Si queremos añadir una nueva feature, habría que modificarlo en cada cliente.
    • Volver a modificar los estilos inline.
  • Los estilos CSS están separados de HTML:
    • Se hace una copia del CSS para cada cliente y se modifica con estilos propios.
    • Si queremos añadir una nueva feature, se actualiza sólo el HTML en cada cliente.

A continuación un ejemplo del mismo código HTML con distintas hojas de estilo CSS. Ejemplos obtenidos de W3Schools.

Sin estilo
Ejemplo 1
Ejemplo 2
Ejemplo 3

9 Sintaxis de CSS

CSS posee una sintaxis sencilla y relativamente fácil de aprender. A diferencia de otros lenguajes de programación, CSS no contiene estructuras de control como bucles o condicionales (aunque sí dispone de funciones y reglas avanzadas que estudiaremos más adelante). Su función principal consiste en indicar cómo deben mostrarse los elementos HTML.

9.1 Regla CSS

Una hoja de estilos está formada por un conjunto de reglas CSS. Cada regla indica:

  • Qué elementos deben modificarse.
  • Qué propiedades deben cambiar.
  • Qué valor debe asignarse a cada propiedad.

La estructura general es la siguiente:

Definiciones

selector {
    propiedad: valor;
}

Ejemplo real

h1 {
    color: red;
}

Esta regla indica que todos los elementos <h1> deben mostrarse en color rojo.

9.1.1 El selector

El selector indica qué elementos HTML se verán afectados por la regla. En la siguiente sólo aparecen unos pocos ejemplos, pero en el anexo aparecen todas las etiquetas HTML que se pueden usar como selectores.

Selector Función
h1 Encabezados 1
h2 Encabezados 2
p Párrafos
ul Lista desordenada

9.1.2 Las propiedades

Las propiedades indican qué aspecto queremos modificar. Existen cientos de propiedades distintas. Algunas de las más utilizadas son:

Propiedad Función
color Color del texto
background-color Color de fondo
font-size Tamaño del texto
font-family Tipografía
width Anchura
height Altura
margin Margen exterior
padding Espacio interior
border Borde
text-align Alineación del texto

Cada propiedad únicamente acepta determinados valores, aprenderemos los más importantes.

9.1.3 Los valores

Cada propiedad necesita un valor. Dependiendo de la propiedad, ese valor puede ser:

Valor Ejemplo
Un color color:red;
Un número font-size: 20px;
Una longitud font-size: 2rem;
Un porcentaje width: 80%;
Una palabra clave display: flex;
Una función width: calc(100% - 50px);

9.2 Declaraciones

Cada pareja formada por una propiedad y un valor recibe el nombre de declaración. Una misma regla puede contener varias declaraciones. En el siguiente ejemplo hay tres:

Ejemplo real

h1 {
    color: blue;
    font-size: 40px;
    text-align: center;
}

El conjunto de declaraciones comprendido entre las llaves recibe el nombre de bloque de declaraciones.

9.3 Comentarios

Los comentarios permiten añadir información al código sin que el navegador la interprete. Pueden ser de una única línea o varias:

Comentario

/* Estilos generales */
body {
    margin: 0;
}

Comentario multilínea

/*
  Curso: DAW
  Fecha: Septiembre de 2026
*/

9.4 Sensibilidad a mayúsculas y minúsculas

Tanto los nombre de propiedades como las palabras clave deben escribirse en minúsculas. Aunque algunos navegadores aceptan determinadas variantes, es recomendable seguir siempre las convenciones del lenguaje.

9.5 Espacios en blanco

CSS ignora los espacios en blanco innecesarios. Las siguientes reglas son equivalentes.

Ignora espacios

h1 {
color:red;
}

Ignora espacios

h1 {
  color:red;
}

Ignora espacios

h1 {   color:red;     }

Todas producen exactamente el mismo resultado, pero únicamente la segunda resulta fácil de leer.

9.6 Sangrado (indentation)

El sangrado consiste en desplazar ligeramente el código hacia la derecha para mostrar su estructura. Aunque CSS funciona correctamente sin sangrado, utilizar una indentación uniforme mejora enormemente la legibilidad. La mayoría de editores realizan esta tarea automáticamente. Podemos elegir si queremos que sea dos espacios o cuatro.

9.7 El punto y coma

Cada declaración finaliza mediante un punto y coma ;. Cuando una regla contiene varias declaraciones, el punto y coma resulta obligatorio.

9.8 ¿Qué ocurre cuando existe un error?

Una característica muy importante de CSS es que los navegadores intentan seguir interpretando la hoja de estilos aunque encuentren errores.

Error

h1 {
    color: blue;
    colr: red;
    font-size: 40px;
}

En este caso:

  • color: blue; se aplicará correctamente.
  • colr: red; será ignorado.
  • font-size: 40px; volverá a aplicarse normalmente.

Este comportamiento hace que pequeños errores no impidan visualizar la página.

9.9 Orden de las propiedades

CSS no obliga a escribir las propiedades siguiendo un orden determinado. Los siguientes producen el mismo resultado:

Orden

h1 {
    color: blue;
    margin: 20px;
    font-size: 30px;
}

Orden

h1 {
    font-size: 30px;
    margin: 20px;
    color: blue;
}

No obstante, en proyectos profesionales suele seguirse un orden para facilitar la lectura.

  1. Posicionamiento.
  2. Modelo de cajas.
  3. Tipografía.
  4. Colores.
  5. Animaciones.

Mantener siempre el mismo criterio mejora el mantenimiento del código.

En un equipo de desarrollo se debería seguir el mismo formateo, orden e indentación.

10 Selectores CSS

Una regla CSS necesita indicar sobre qué elementos HTML debe aplicarse. Para ello se utilizan los selectores. El selector es la parte de una regla CSS que permite identificar los elementos que queremos modificar.

Los selectores son una de las partes fundamentales de CSS, ya que permiten aplicar diferentes estilos a diferentes elementos de un documento HTML, y se pueden diferenciar en distintos apartados.

10.1 Selector de tipo

El selector de tipo permite seleccionar todos los elementos HTML de un determinado tipo.

HTML

<p>Primer párrafo.</p>
<p>Segundo párrafo.</p>
<p>Tercer párrafo.</p>

CSS

p {
    color: blue;
}

Teniendo en cuenta el ejemplo anterior, el CSS selecciona todos los elementos de tipo <p> (párrafo) añadiéndoles el color azul al texto.

Los selectores de tipo son sencillos, pero pueden resultar demasiado generales cuando necesitamos aplicar diferentes estilos a elementos del mismo tipo.

10.2 Selector universal

El selector universal se representa mediante un asterisco (*) y selecciona todos los elementos del documento.

CSS

* {
    margin: 0;
    box-sizing: border-box;
}

El selector universal se utiliza frecuentemente para realizar pequeños ajustes generales. Aunque el selector universal es útil, no conviene utilizarlo indiscriminadamente para aplicar muchas propiedades a todos los elementos, ya que puede generar reglas innecesarias y dificultar el mantenimiento.

02a

Crea un HTML con elementos h1 y p y genera un CSS con un selector universal que quite el margen y añada borde a todos los elementos.

10.3 Selector de clase

Los selectores de clase permiten aplicar estilos a determinados elementos sin afectar a todos los elementos del mismo tipo. En HTML se utiliza el atributo class.

HTML

<h1 class="importante grande">
  Título importante
</h1>

<p class="importante">
  Este texto es importante.
</p>

<p class="grande">
  Este texto es grande.
</p>

CSS

.importante {
  color: red;
}

.grande {
  font-size: 50px;
}

En CSS, una clase se selecciona utilizando un punto (.) seguido del nombre de la clase. Una clase puede ser utilizada varias veces y en distintos elementos, por lo que debemos tener eso en cuenta, pero más adelante hablaremos de ello.

Por otro lado, el atributo class puede contener varias clases separadas mediante espacios, por lo que recibirá los estilos de ambas clases. De esta manera podemos reutilizar y combinar estilos dependiendo de nuestras necesidades.

02b

Crea un HTML con elementos que tengan clases y combinaciones y genera un CSS con clases reutilizables y un selector universal.

10.4 Selector de identificador

HTML también dispone del atributo id que sólo debe ser utilizado una única vez en cada documento HTML. Para seleccionar un elemento mediante su identificador utilizamos el carácter #:

HTML

<h1 id="titulo-principal">
    Mi página web
</h1>

CSS

#titulo-principal {
    color: blue;
}

El selector se aplicará al elemento cuyo id sea titulo-principal.

02c

Crea un HTML con elementos que tengan identificadores y crea CSS propios.

10.5 Selector por atributo

CSS permite seleccionar elementos que poseen determinados atributos HTML. Por ejemplo, podemos seleccionar todos los elementos que tengan el atributo type:

HTML

<input type="text">

<input type="email">

<input type="password">

CSS

input[type] {
    border: 1px solid black;
}
input[type="email"] {
    background-color: lightblue;
}

También podemos seleccionar un valor concreto del atributo, en el ejemplo type="email". En este caso, únicamente el campo de correo electrónico tendrá el fondo azul claro.

Los selectores de atributo son especialmente útiles cuando necesitamos aplicar estilos dependiendo de las características de un elemento HTML.

Otro ejemplo para enlaces con atributo target.

HTML

<a href="http://google.com"
    target="_self">
    link
</a>
<a href="http://google.com" 
    target="_blank">
    link
</a>

CSS

a[target] {
    font-weight: bold;
}
a[target="_blank"] {
    color: red;
}

02d

Crea un HTML con elementos que tengan atributos y crea CSS propios.

10.6 Agrupar selectores

Podemos aplicar las mismas reglas a varios selectores separándolos mediante comas. La agrupación evita repetir código.

Agrupar selectores

h1,
h2,
h3 {
    font-family: sans-serif;
}

Agrupar selectores

h1, h2, h3 {
    font-family: sans-serif;
}

10.7 Selectores descendientes

CSS permite seleccionar elementos que se encuentran dentro de otros elementos. Podemos seleccionar únicamente los párrafos que están dentro de <article>.

HTML

<article>
    <p>Primer párrafo.</p>
    <p>Segundo párrafo.</p>
</article>

<article>
    <div>
        <p>
            Texto.
        </p>
    </div>
</article>

<p>Párrafo exterior.</p>

CSS

article p {
    color: blue;
}

El espacio entre article y p indica que estamos seleccionando los elementos<p> que son descendientes de <article>.

El resultado será:

  • Primer párrafo → azul.
  • Segundo párrafo → azul.
  • Párrafo exterior → sin este estilo.
  • Texto → azul.

El selector descendiente no se limita a los hijos directos, si no a toda la descendencia.

El selector descendiente no se limita a los hijos directos, si no a toda la descendencia.

10.8 Selector de hijo directo

En ocasiones no queremos seleccionar cualquier descendiente, sino únicamente los hijos directos. Para ello utilizamos el símbolo >.

HTML

<article>
  <p>Párrafo directo.</p>
  <div>
    <p>Dentro de un div.</p>
  </div>
</article>

CSS

article > p {
    color: blue;
}

De esta manera sólo se selecciona únicamente el primer párrafo, porque el segundo párrafo no es hijo directo de <article>.

02f

Crea un HTML con un CSS que diferencie entre descendientes e hijos directos.

10.9 Selector de hermano adyacente

CSS permite seleccionar elementos que aparecen inmediatamente después de otro. Para ello se utiliza el símbolo +.

HTML

<h2>Título</h2>
<p>Primer párrafo.</p>
<p>Segundo párrafo.</p>

CSS

h2 + p {
    color: blue;
}

Con la regla anterior sólo se selecciona el primer párrafo, pero el segundo no.

10.10 Selector de hermanos posteriores

Para seleccionar todos los hermanos que aparecen después de un elemento se usa ~.

HTML

<h2>Título</h2>
<p>Primer párrafo.</p>
<p>Segundo párrafo.</p>
<div>Otro elemento.</div>
<p>Tercer párrafo.</p>

CSS

h2 ~ p {
    color: blue;
}

Con la regla anterior selecciona todos los elementos <p> que sean hermanos posteriores de <h2>. Por tanto, los tres párrafos serán seleccionados.

02g

Crea un HTML con un CSS que diferencie entre hermanos adyacentes y todos los posteriores.

10.11 Pseudoclases

Las pseudoclases permiten seleccionar elementos en función de un estado o una condición, y se representan mediante dos puntos (:). Unos ejemplos son:

  • :hover: Cuando el usuario sitúa el puntero del ratón sobre el elemento.
  • :focus: Cuando un elemento tiene el foco.
  • :active: Representa el momento en el que un elemento está siendo activado
  • :visited: Enlaces que el usuario ya ha visitado

02h

Crea un HTML con un CSS que use estas pseudoclases.

10.12 Pseudoelementos

Los pseudoelementos permiten seleccionar determinadas partes de un elemento o generar contenido asociado a él. Se representan normalmente mediante dos puntos (::).

HTML

<p class="aviso">
    Este campo es obligatorio.
</p>

CSS

p::first-letter {
    font-size: 50px;
}
p::first-line {
    font-weight: bold;
}
.aviso::before {
    content: "⚠ ";
}
.enlace::after {
    content: " →";
}

Las reglas creadas hacen:

  • Modifica la primera letra de cada párrafo.
  • Permite modificar la primera línea de un texto.
  • Permite insertar contenido antes del contenido del elemento.
  • ::after funciona de forma similar, pero inserta el contenido después.

El contenido generado mediante ::before y ::after forma parte de la representación visual del documento, pero no sustituye al contenido HTML que necesita el usuario. No debemos utilizarlos para introducir información esencial que deba estar disponible para todas las personas o tecnologías de asistencia.

02i

Crea el ejemplo anterior e interioriza los pseudoelementos.

10.13 Combinación de selectores

Los selectores pueden combinarse para crear reglas mucho más específicas. Por ejemplo:

HTML

<article class="destacado">
  <p>Este párrafo será azul.</p>
</article>

CSS

article.destacado p {
    color: blue;
}

Esta regla selecciona los párrafos que se encuentran dentro de un elemento que:

  • Es un <article>.
  • Tiene la clase destacado.

También podemos combinar clases:

HTML

<button class="boton">
    Aceptar
</button>

<button class="boton importante">
    Eliminar
</button>

CSS

.boton.importante {
    background-color: red;
}

La regla selecciona únicamente los elementos que tienen las dos clases:

10.14 Resumen de selectores

Selector Ejemplo Selecciona
Universal * Todos los elementos
Tipo p Todos los
Clase .aviso Elementos con la clase aviso
ID #menu Elemento con id="menu"
Atributo input[type="email"] Inputs de tipo email
Descendiente article p <p> dentro de <article>
Hijo directo article > p <p> hijos directos
Hermano adyacente h2 + p <p> inmediatamente posterior
Hermanos posteriores h2 ~ p <p> posteriores que sean hermanos
Pseudoclase a:hover Enlaces bajo el cursor
Pseudoelemento p::first-letter Primera letra de un párrafo

10.15 Buenas prácticas

Al escribir selectores CSS conviene seguir algunas recomendaciones.

  • Utilizar clases para los estilos reutilizables.
  • Evitar selectores excesivamente complejos, ya que dificultan el mantenimiento posterior.
  • Utilizar nombres descriptivos con las clases e identificadores únicos.

11 Especificidad

En el apartado anterior hemos visto que CSS permite utilizar diferentes tipos de selectores para seleccionar elementos HTML. En ocasiones, varias reglas CSS pueden afectar al mismo elemento y modificar la misma propiedad. Por ejemplo:

HTML

<p id="mensaje" class="importante">
    Hola mundo
</p>

css

p {
    color: blue;
}
.importante {
    color: green;
}
#mensaje {
    color: red;
}

Las tres reglas anteriores afectan al mismo elemento y las tres intentan establecer el valor de la propiedad color. Ante estos casos, cuando hay varias reglas, la especificidad es el mecanismo que utiliza CSS para determinar qué regla tiene prioridad cuando varias reglas pueden aplicarse al mismo elemento. El texto será rojo, porque el selector #mensaje tiene una especificidad mayor que los otros dos selectores.

11.1 Tipos de selectores y especificidad

La especificidad de un selector depende principalmente del tipo de selector utilizado. Podemos establecer, de mayor a menor prioridad, la siguiente clasificación:

  1. Estilos inline.
  2. Identificadores (#id).
  3. Clases, atributos y pseudoclases.
  4. Elementos y pseudoelementos.

Para comprender la especificidad podemos representar un selector mediante cuatro valores A B C D que podemos imaginar como una puntuación. Imaginemos los siguientes ejemplos:

CSS

p {
    color: blue;
}

CSS

.mensaje {
    color: green;
}

CSS

#mensaje {
    color: red;
}

Las puntuaciones quedarían:

  • 0 0 0 1: porque contiene un selector de tipo elemento.
  • 0 0 1 0: por ser una clase.
  • 0 1 0 0: por ser identificador.

Es importante comprender que los valores de especificidad no se suman como una puntuación normal. Se comparan de izquierda a derecha. Por ejemplo 0 1 0 0 > 0 0 20 0, el primero es más específico aunque el segundo selector tenga 20 clases, ya que el selector de identificador es más prioritario que las clases. Existe calculadoras para calcular el valor y comparar entre distintas reglas y saber cuál es más específica que otra.

03a

Crea un HTML con tres p y añade estilos por especificidad.

11.2 Combinación de selectores

La especificidad también se acumula cuando combinamos selectores. Si seguimos la regla explicada previamente, analicemos los siguientes ejemplos:

CSS

article p {
    color: blue;
}

CSS

article .mensaje {
    color: green;
}

Las puntuaciones quedarían:

  • 0 0 0 2: porque contiene dos selector de tipo.
  • 0 0 1 1: por tener un selector de tipo y otro de clase. Por lo tanto, tiene mayor especifidad que la anterior

11.3 Varias clases

Si un selector contiene varias clases, todas ellas cuentan para la especificidad.

CSS

.mensaje.importante {
    color: red;
}

CSS

.mensaje {
    color: blue;
}

La primera regla es más especifica que la segunda.

11.4 Selectores de atributos

Los selectores de atributos tienen la misma importancia que las clases.

CSS

input[type="email"] {
    border-color: blue;
}

Tiene puntuación de 0 0 1 1 por:

  • Un selector de tipo: input
  • Un selector de atributo: [type="email"]

11.5 Pseudoclases

Las pseudoclases también cuentan como una clase a efectos de especificidad.

CSS

a:hover {
    color: red;
}

Tiene puntuación de 0 0 1 1 por:

  • Un selector de tipo: a
  • Un selector de atributo: :hover

11.6 Pseudoelementos

Los pseudoelementos cuentan como selectores de tipo.

CSS

p::first-letter {
    font-size: 30px;
}

Tiene puntuación de 0 0 0 2 por:

  • Un selector de tipo: p
  • Un pseudoelemento: ::first-letter

11.7 El selector universal

El selector universal no aporta especificidad. Lo mismo pasa con > + ~. Estos elementos sirven para establecer relaciones entre selectores, pero no aumentan la especificidad.

11.8 Especificidad frente a orden

La especificidad no es el único criterio que utiliza CSS. Cuando dos reglas tienen la misma especificidad, el orden de aparición puede determinar cuál se aplica. En el siguiente ejemplo ambos selectores tienen la misma puntuación y afectan al mismo tipo de elemento:

CSS

p {
    color: blue;
}
p {
    color: red;
}

A pesar de tener la misma puntuación, la regla que se aplica es la segunda, ya que aparece después y por tanto el texto será rojo.

11.9 Forzar declaración con !important

CSS proporciona una herramienta especial denominada !important que adquiere una prioridad especial dentro del mecanismo de la cascada. Puede utilizarse para forzar que una determinada declaración tenga prioridad sobre otras declaraciones normales.

Teniendo en cuenta el ejemplo anterior, al añadir !important a la primera regla se vuelve prioritaria y deja sin validez a la segunda:

CSS

p {
    color: blue !important;
}
p {
    color: red;
}

Cuando existen numerosos !important, se vuelve complicado saber qué regla terminará aplicándose, y por tanto no se recomienda utilizar como solución habitual a los problemas de estilos.

Utilizar !important es considerado una mala práctica.

11.10 Herramientas del navegador

Las herramientas para desarrolladores de los navegadores permiten comprobar fácilmente qué reglas CSS se están aplicando. Por ejemplo, en Chrome o Firefox podemos seleccionar un elemento mediante el inspector y el navegador mostrará:

  • Las reglas que afectan al elemento.
  • Las propiedades aplicadas.
  • Las propiedades sobrescritas.
  • El archivo CSS donde se encuentra cada regla.
  • La línea donde está definida.
  • En algunos casos, información relacionada con la especificidad.

Si aparece una propiedad tachada significa que existe otra declaración para la misma propiedad que tiene prioridad. Aprender a identificar el orden y utilizar esta herramienta resulta fundamental para solucionar problemas de CSS.

03b

Teniendo en cuenta el siguiente código HTML y CSS, analiza el código y determina qué color va a tener texto (apúntalo en un papel). Copia el texto en ficheros y comprueba si has acertado. Analiza con las herramientas del desarrollador las reglas que se aplican y cuáles se tachan por tener menor especificidad.

HTML

<h1 id="titulo">Especificidad de CSS</h1>

<h2 class="azul">Primer ejemplo</h2>
<p class="base">Párrafo 1</p>

<h3 class="verde">Segundo ejemplo</h3>
<p id="importante" class="destacado">Segundo párrafo</p>

<h2 class="gris">Tercer ejemplo</h2>
<p class="base resaltado">Tercer párrafo</p>

<p class="importante">Cuarto párrafo</p>

CSS

p { color: black;}
h1 { color: darkgray;}
h2 { color: purple;}
h3 { color: brown;}
#titulo { color: red;}
.base { color: green;}
h2.azul { color: blue;}
p.destacado { color: orange;}
h3.verde { color: olive;}
p.resaltado { color: teal;}
p.importante { color: fuchsia !important;}
#importante { color: darkblue !important;}
h2.gris { color: gray;}

12 Herencia

La herencia es uno de los mecanismos fundamentales de CSS. Permite que determinadas propiedades CSS definidas en un elemento se transmitan en herencia automáticamente a sus elementos descendientes. Gracias a la herencia, no es necesario establecer algunas propiedades individualmente en todos los elementos de una página.

HTML

<body>
    <h1>Título</h1>
    <p>Primer párrafo.</p>
    <div>
        <p>Segundo párrafo.</p>
    </div>
</body>

CSS

body {
    color: blue;
}
div {
    color: red;
}

Con el ejemplo anterior, los textos de los elementos descendientes heredarán el color especificado en el padre. Por otro lado, tal como se puede ver, un elemento puede tener su propio valor para una propiedad heredable e incluso comenzar su propia herencia tal como sucede con la regla div.

La herencia permite reducir la cantidad de código CSS necesario y facilita la creación de estilos generales para una página.

12.1 No todas las propiedades se heredan

Es importante tener en cuenta que no todas las propiedades CSS son heredables. Por ejemplo, color se hereda normalmente, pero propiedades relacionadas con el modelo de caja, como margin, no se heredan normalmente.

Por tanto, debemos distinguir entre

  • Propiedades heredables: por defecto se establecen al valor calculado del elemento padre. Son propiedades relacionadas al texto, como color, font-family, font-size, font-style, line-height, text-align y visibility.
  • Propiedades NO heredables: por defecto se establecen al valor inicial de la propiedad. Son propiedades relacionadas con el modelo de caja o el layout, como border, background, margin, padding, width y height.

Para saber qué propiedad es heredable, dentro de la documentación de MDN o W3C podemos ver la definición de Inherited, que si es True se hereda.

12.2 Forzar herencia con inherit

CSS proporciona la palabra clave inherit para indicar explícitamente que una propiedad debe utilizar el valor heredado del elemento padre.

Usando esta palabra también vamos a poder heredar atributos que no se heredarían.

HTML

<div>
    <p>Primer párrafo.</p>
    <p>Segundo párrafo</p>
</div>

CSS

div {
  border: 2px solid red;
}
p {
    border: inherit;
}

03d

Genera un HTML con propiedades que se hereden automáticamente y otras por herencia forzada.

12.3 initial como reset

Podríamos definir initial como si fuese un reset, ya que establece el valor inicial definido para la propiedad según CSS.

Supongamos el siguiente ejemplo:

HTML

<div>
    <h1>Título</h1>>
    <p>primer párrafo</p>
</div>

CSS

div {
  color:red
}
h1 {
    color: initial;
}

Establecemos en div un color que por herencia deberían tener todos los elementos bajo él, pero en la regla de h1 hacemos que el color vuelva al valor por defecto.

03e

Genera un HTML con propiedades heredadas pero que no se establezcan por el uso de initial.

12.4 La palabra clave unset

La palabra clave unset combina dos comportamientos.

  • Si la propiedad es heredable, unset se comporta como: inherit
  • Si la propiedad no es heredable, se comporta como initial

CSS

p {
    color: unset;
    margin: unset;
}

En el anterior ejemplo tenemos las dos maneras de comportarse:

  • Como color es una propiedad heredable, unset hará que se utilice el valor heredado.
  • Para margin se utilizará el valor por defecto.

12.5 La palabra clave revert

La palabra clave revert permite volver al valor que habría tenido la propiedad utilizando las reglas de origen anteriores, en lugar de continuar aplicando la declaración actual.

Su funcionamiento está relacionado con la cascada y con los diferentes orígenes de las reglas CSS.

Aunque puede resultar útil en determinados casos, de momento no la usaremos, aunque es conveniente ver un ejemplo en MDN.

13 Cascada

El nombre de CSS procede de Cascading Style Sheets, que en español significa hojas de estilo en cascada. La palabra cascada hace referencia al mecanismo que utiliza CSS para determinar qué estilos deben aplicarse cuando existen varias reglas que afectan a un mismo elemento.

En una página web es habitual que diferentes reglas puedan establecer valores para una misma propiedad.

CSS

p {
    color: blue;
}
p {
    color: red;
}

Las dos reglas afectan a los elementos <p> y las dos establecen un valor para la propiedad color. CSS necesita decidir cuál de los dos valores utilizará. La cascada es el conjunto de reglas que permite resolver estas situaciones.

13.1 La cascada no significa “gana la última regla”

El orden de aparición es solamente uno de los criterios utilizados por la cascada, por lo que hay que tener cuidado y no creer que la última regla siempre va a ser la correcta.

Hay que recordar que la regla que se aplica es la que mayor especificidad tenga.

13.2 Las tres ideas fundamentales

Para comprender la cascada es necesario distinguir los conceptos que hemos visto previamente:

  • Especificidad: Determina qué selector tiene mayor prioridad cuando varias reglas coinciden con un elemento.
  • Herencia: Permite que determinadas propiedades pasen de los elementos padres a sus descendientes.
  • Cascada: Determina qué declaración termina utilizándose cuando existen varias declaraciones posibles.

13.3 Origen de las hojas de estilo

Las reglas CSS pueden proceder de diferentes lugares. De forma simplificada, podemos distinguir:

  • Hojas de estilo del navegador.
  • Hojas de estilo proporcionadas por el usuario.
  • Hojas de estilo del autor de la página.

En el desarrollo habitual de páginas web trabajaremos principalmente con los estilos del autor, es decir, los CSS que escribimos nosotros.

13.3.1 Estilos del navegador

Los navegadores incluyen una hoja de estilos predeterminada conocida habitualmente como user-agent stylesheet. Cuando creamos nuestro HTML, al añadir algún elemento ya tiene un estilo propio de tamaño, color, tipo de letra, grosor, márgenes…

Estos estilos no los hemos escrito nosotros, proceden de las reglas predeterminadas del navegador, que suelen proporcionar estilos predeterminados para las siguientes etiquetas: <h1>, <p>, <a>, <ul>, <button>, <input>, entre muchos otros elementos.

Por este motivo, una página HTML puede tener un aspecto visual incluso cuando no hemos escrito ninguna hoja de estilos.

Mismo HTML sin estilos en Chrome, Firefox y Safari en MacOS

Tal como se puede ver, existen diferencias claras en el botón, pero también en dónde se dibuja el bullet de la lista, separación entre elementos, y más sutilmente el subrayado del enlace.

Esto siempre ha sido un problema, y más antiguamente cuando algunos navegadores no gestionaba bien el estándar, sobre todo en la gestión de los parámetros de cajas. Por eso existen ficheros reset.css para resetear los estilos predeterminados. Los frameworks CSS como Bootstrap o TailWind también hacen esta operación antes de aplicar sus estilos.

13.4 Controlar el sistema de cascada

CSS ha evolucionado y actualmente existen mecanismos adicionales para controlar la cascada. Uno de ellos son las capas de cascada, mediante @layer.

Las capas permiten organizar las reglas CSS en diferentes niveles de prioridad y posteriormente colocar las reglas dentro de cada capa. Esto resulta especialmente útil en proyectos grandes, donde diferentes partes del CSS pueden proceder de distintas bibliotecas o módulos.

CSS

@layer main {
    p {
        color: blue;
    }
}

@layer componentes {
    p {
        color: red;
    }
}

En el ejemplo anterior la capa “componentes” es más prioritaria que “main” por estar declarada después, por lo tanto el color del texto será rojo. También podemos especificar el orden de las capas sin importar después el orden de la declaración.

Orden de capas

@layer componentes, main;

Orden de capas

@layer componentes;
@layer main;

Ahora la capa “main” es más prioritaria (por añadirlo después en la declaración), y por tanto sus estilos son los que se aplican a misma especificidad.

03f

Crea un CSS con capas y modifica el orden de la declaración para aplicar sus estilos.

13.5 Especificidad frente a orden

Teniendo en cuenta todo lo visto hasta ahora, las reglas que más prioridad tienen es por la especificidad, pero a misma especificidad quien gana es la regla que se declara última, siempre y cuando no haya de por medio una especificación de layers, que puede alterar el orden.

13.6 Diferencia entre herencia y cascada

La herencia y la cascada son conceptos relacionados, pero no son lo mismo. La herencia permite que determinadas propiedades pasen de un elemento padre a sus descendientes.

La cascada, en cambio, determina qué declaración CSS tiene prioridad cuando existen varias declaraciones que pueden aplicarse, y por tanto habrá que medir con la especificidad cuál gana.

Podemos resumirlo de esta manera:

Concepto Función
Herencia Transmite determinadas propiedades desde los padres a los descendientes
Cascada Decide qué declaración tiene prioridad
Especificidad Ayuda a determinar qué selector tiene prioridad cuando varias reglas coinciden

14 Unidades de medida

Las propiedades CSS que controlan tamaños, distancias y dimensiones necesitan utilizar unidades de medida.

Indicando tamaño

p {
    font-size: 20px;
}

En este caso:

  • font-size indica el tamaño de la fuente.
  • 20 es el valor numérico.
  • px es la unidad de medida.

Las unidades permiten indicar al navegador cuánto debe medir un elemento, cuánto espacio debe ocupar o qué distancia debe existir entre diferentes elementos.

Las unidades CSS pueden clasificarse principalmente en:

  • Unidades absolutas: representan una medida que no depende directamente del tamaño de otro elemento.
  • Unidades relativas: dependen de alguna característica del documento, del elemento padre, del tamaño de la fuente o del tamaño de la ventana del navegador. Las unidades relativas son especialmente importantes para crear interfaces adaptables a diferentes tamaños de pantalla.

14.1 Unidades absolutas

Las principales unidades absolutas son:

Unidad Significado
px Píxel CSS
cm Centímetro
mm Milímetro
in Pulgada
pt Punto
pc Pica
Q 1/40th of 1cm

En el desarrollo web habitual, px es con diferencia la unidad absoluta más utilizada.

14.1.1 El píxel CSS

La unidad px representa un píxel CSS. Es importante no confundir necesariamente un píxel CSS con un píxel físico de la pantalla, ya que los dispositivos modernos pueden tener una densidad de píxeles muy elevada.

Por tanto, px debe entenderse como una unidad de CSS y no simplemente como “un punto físico de la pantalla”. Suele resultar muy útiles cuando queremos controlar con precisión determinados tamaños, y su uso habitual es en:

  • Bordes.
  • Iconos.
  • Sombras.
  • Pequeños espacios.
  • Tamaños que necesitan un control concreto.

14.1.2 Unidades físicas

CSS también proporciona unidades físicas como cm, mm, in o pt. Estas unidades pueden resultar especialmente interesantes cuando se trabaja con impresión.

Indicando tamaño

@media print {
    .pagina { /* A4 */
        width: 21cm;
        min-height: 29.7cm;
    }
}

Usar unidades físicas en pantallas no tiene sentido.

14.2 Unidades relativas

Las unidades de longitud relativas especifican una longitud en relación con otra propiedad de longitud. Las unidades de longitud relativas se adaptan mejor a diferentes medios de renderizado.

Unidad Significado
em Relativo al tamaño de fuente del elemento (2em significa 2 veces el tamaño de la fuente actual)
rem Relativo al tamaño de fuente del elemento raíz
ex Relativo a la altura-x de la fuente actual (poco usado)
ch Relativo al ancho del “0” (cero) de la fuente actual
vw Relativo al 1% del ancho de la ventana de visualización
vh Relativo al 1% de la altura de la ventana de visualización
% Relativo al elemento padre

Las medidas vw, vh, vmin y vmax tienen en cuenta la ventana del navegador. Si la ventana fuese 50cm de ancho entonces 1vw = 0.5cm.

14.2.1 Unidad relativa em

La unidad em es una unidad relativa relacionada con el tamaño de la fuente. Los navegadores tienen un tamaño predefinido de 16px, que el usuario puede cambiar (por ejemplo, por problemas de visión).

Por ejemplo, si utilizamos:

Indicando tamaño

p {
    font-size: 20px;
    margin: 2em;
}

El valor de 2em está relacionado con el tamaño indicado, y por tanto será 40px. Pero si no se indica la primera regla, por defecto se coge el valor del navegador, y por tanto serán 32px.

03g

Comprueba el valor relativo de em:

  • Indicando un tamaño de fuente en el CSS.
  • Usando el valor por defecto del navegador.
  • Busca la configuración del navegador y cambialo a 32px y comprueba los cambios.

Si indicamos el tamaño de la fuente en el body, después podemos utilizar em para hacer relativo el resto de tamaños.

Indicando tamaño

body {
    font-size: 16px;
}
h1 {
    font-size: 2em;
}

14.2.1.1 El problema de la acumulación de em

Una característica importante de em es que puede acumularse cuando existen elementos anidados. Analiza el siguiente ejemplo:

HTML

<div>
    Texto
    <div>
        Texto interior
    </div>
</div>

CSS

body {
    font-size: 16px;
}
div {
    font-size: 1.5em;
}

¿Qué tamaño tendrá el “texto interior”?

El segundo <div> utiliza como referencia el tamaño de fuente de su padre, que es otro <div>, que a su vez tiene una fuente relativa partiendo de 16px. El resultado sería:

  • Tamaño original: 16px
  • Primer <div>: 16x1.5 = 24px
  • Segundo <div>: 24x1.5 = 36px

Esto puede ser útil en determinados casos, pero también puede complicar el control de los tamaños.

La unidad em es relativa y acumulativa, lo que puede llevar a problemas.

03h

Realiza el ejemplo anterior y analiza el resultado.

14.2.2 Unidad relativa rem

La unidad rem también es relativa al tamaño de la fuente, pero toma como referencia el elemento raíz del documento. La unidad rem viene de root em, y la raíz del documento HTML es normalmente <html>.

HTML

<h1>Título 1</h1>
<div>
    <h1>Título 2</h1>
</div>

CSS

html {
    font-size: 16px;
}
div {
    font-size: 2rem;
}
h1 {
    font-size: 2rem;
}

¿Qué tamaño tendrán los h1?

03i

Realiza el ejemplo anterior y analiza el resultado.

La ventaja de rem respecto a em es que permite crear una escala de tamaños de manera sencilla y clara.

CSS

html  { font-size: 16px; }
h1    { font-size: 2rem; }
h2    { font-size: 1.5rem; }
p     { font-size: 1rem; }
small { font-size: 0.875rem; }

La relación entre los tamaños se mantiene respecto a una única referencia, lo que facilita modificar posteriormente la escala general.

14.2.3 Unidad relativa ch

La unidad ch está relacionada con el ancho del carácter 0 de la fuente utilizada. Por ejemplo:

CSS

p {
    max-width: 60ch;
}

Esto permite limitar aproximadamente la anchura de una línea de texto. Es especialmente útil para mejorar la legibilidad de textos largos. De esta forma evitamos que los párrafos ocupen líneas excesivamente largas y nos aseguramos el tamaño que va a tener.

14.2.4 Unidad relativa ex

La unidad ex está relacionada con la altura de la letra x de la fuente actual. Por ejemplo:

CSS

.elemento {
    height: 5ex;
}

Su uso es mucho menos frecuente que em, rem, o ch.

Para los desarrollos habituales podemos conocer su existencia sin necesidad de utilizarla habitualmente.

14.2.5 Porcentajes

El símbolo % representa una unidad relativa y su valor depende del contexto en el que se utilice. En muchas propiedades, el porcentaje se calcula utilizando como referencia el elemento contenedor.

HTML

<div class="contenedor">
    <div class="caja"></div>
</div>

CSS

.contenedor {
    width: 800px;
}

.caja {
    width: 50%;
}

El elemento “contenedor” tiene un tamaño fijado de 800px y la caja dentro de él una anchura del 50% del tamaño de referencia correspondiente, es decir, la mitad.

Los porcentajes son muy útiles para crear diseños adaptables.

El significado exacto de un porcentaje depende de la propiedad donde se utilice.

CSS

.caja {
    padding: 10%;
}

No se interpreta exactamente igual la propiedad anterior, por lo que conviene leer la documentación.

El uso del porcentaje depende de la propiedad concreta y del contexto.

14.2.6 Unidades relacionadas con el viewport

CSS también proporciona unidades relativas al tamaño de la ventana del navegador. El viewport es, de forma simplificada, el área visible de la página. Las unidades tradicionales relacionadas con él son:

  • vw: significa viewport width y representa el 1% del ancho del viewport, por lo que 100vh es el 100% de la anchura del viewport.
  • vh: significa viewport height y representa el 1% de la altura del viewport, por lo que 100vh es el 100% de la altura del viewport.

CSS

.elemento {
    width: 100vw;
    height: 100vh;
}

Sin embargo, en aplicaciones reales no siempre es necesario utilizar 100vw para el ancho, ya que puede producir problemas cuando aparecen barras de desplazamiento.

Existen otras unidades explicadas en la documentación

Unit Relative to
dvh 1% of the dynamic viewport’s height.
dvw 1% of the dynamic viewport’s width.
lvh 1% of the large viewport’s height.
lvw 1% of the large viewport’s width.
svh 1% of the small viewport’s height.
svw 1% of the small viewport’s width.
vb 1% of viewport’s size in the root element’s block axis.
vh 1% of viewport’s height.
vw 1% of viewport’s width.
vi 1% of viewport’s size in the root element’s inline axis.
vmax 1% of viewport’s larger dimension.
vmin 1% of viewport’s smaller dimension.

Más adelante veremos en profundidad qué es y cómo funciona el Viewport.

14.3 Unidades para ángulos

CSS también utiliza unidades para representar ángulos. Las principales son:

  • deg: grados.
  • rad: radianes.
  • grad: grados centesimales.
  • turn: vueltas.

Rotación

.elemento {
    transform: rotate(45deg);
}

Rotación

.elemento {
    transform: rotate(0.5turn);
}

En la siguiente tabla se ven varios ejemplos y sus equivalencias de la documentación de MDN.

Rotación Equivalencias
90deg = 100grad = 0.25turn ≈ 1.5708rad
180deg = 200grad = 0.5turn ≈ 3.1416rad
-90deg = -100grad = -0.25turn ≈ -1.5708rad

03j

Crea dos elementos con una anchura de 200px y usa la rotación con distintas unidades.

14.4 Unidades de tiempo

Algunas propiedades CSS utilizan unidades de tiempo. Estas unidades se utilizarán especialmente cuando estudiemos transiciones y animaciones CSS. Las principales son:

  • s: segundos.
  • ms: milisegundos.

Transiciones

.boton {
  transition: background-color 0.3s;
}

Transiciones

.boton {
  transition: background-color 300ms;
}

Ambos valores representan la misma duración.

14.5 Valores sin unidad

Algunas propiedades CSS aceptan números sin unidad.

Opacidad

.elemento {
    opacity: 0.5;
}

altura

.elemento {
    line-height: 1.5;
}

En estos ejemplos no es necesario poner unidad ya que:

  • opacity: utiliza un número comprendido normalmente entre 0 y 1.
  • line-height: es una propiedad que puede aceptar no tener unidad.

14.6 El valor 0

En muchas propiedades CSS, cuando el valor es cero, la unidad puede omitirse.

0 sin usar unidad

.elemento {
    margin: 0;
    padding: 0;
    border-width: 0;
}

En estos casos no hace falta poner ninguna unidad por haber puesto cero, mientras que si fuese otra cantidad sí habría que poner px, em o cualquier otra.

14.7 Medidas calculadas automáticamente

En CSS moderno, por la aparición de móviles y tablets hizo que el diseño responsive se haya vuelto imprescindible, y por tanto el hacer uso de medidas relativas es imprescindible. A eso se le suma el poder realizar cálculos automáticos de medidas.

14.7.1 Calc()

CSS permite realizar cálculos utilizando diferentes unidades mediante la función calc().

Calcular anchura automáticamente

.caja {
    width: calc(100% - 40px);
}

Con esta regla estamos indicando que el ancho va a ser “ancho disponible menos 40px”, y de esta manera no tenemos que forzar la anchura, ya que es relativa y calculada.

La función calc() admite las cuatro operaciones básicas: sumar (+), restar (-), multiplicar (*) y dividir (/).

14.7.2 min() y max()

CSS moderno también proporciona dos funciones para calcular el tamaño:

  • min(): utiliza el menor de los valores proporcionados.
  • max(): utiliza el mayor de los valores proporcionados.

Ambas funciones permiten uno o más parámetros separados por comas.

min()

.caja {
    width: min(90%, 1000px);
}

max()

.caja {
    width: max(300px, 50%);
}

El primer ejemplo permite utilizar el menor de los valores proporcionados. Por tanto:

  • En pantallas pequeñas puede utilizar el 90%.
  • En pantallas grandes no superará los 1000px.

En el segundo ejemplo, con max(), utilizará el mayor de los dos valores.

14.7.3 clamp()

Una función especialmente útil para diseños adaptables es clamp(). Su sintaxis acepta tres parámetros, clamp(min, val, max):

  • min: Si el valor preferido es menor que este valor, se utilizará el valor mínimo.
  • val: El valor preferido es la expresión cuyo valor se utilizará siempre que el resultado esté entre los valores mínimo y máximo. Suele ser un valor relativo.
  • max: El valor máximo es el valor de expresión más grande (más positivo) al que se asignará el valor de la propiedad si el valor preferido es mayor que este límite superior.

max()

h1 {
    font-size: clamp(2rem, 5vw, 4rem);
}

El tamaño de este ejemplo:

  • Nunca será inferior a 2rem.
  • Intentará utilizar 5vw.
  • Nunca será superior a 4rem.

Esto permite crear tamaños que se adapten progresivamente al espacio disponible.

15 Colores

Los colores son una parte fundamental del diseño de una interfaz web. CSS permite definir el color del texto, los fondos, los bordes y muchos otros elementos visuales. A través de los colores podemos establecer una identidad visual, diferenciar elementos, llamar la atención del usuario y mejorar la legibilidad del contenido.

CSS ofrece diferentes formas de especificar colores y numerosas propiedades para controlar tanto el color del texto como el fondo de los elementos.

Ya hemos visto previamente cómo modificar el color del texto en ejemplos anteriores, y también sabemos que es una propiedad que normalmente se hereda.

CSS

p { color: blue; }

15.1 Cómo especificar colores

A la hora de asignar colores podemos elegir de distintas maneras cómo indicar el color:

15.1.1 Nombre de colores

Existen numerosos nombres de colores, en inglés, reconocidos por CSS. Hemos visto varios ejemplos como red o blue, pero hay muchos más.

Existen los siguientes colores estándar: aqua, black,blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, yellow.

Hay ciertos nombres que son alias de otros como:

  • aqua / cyan
  • fuchsia / magenta
  • darkgray / darkgrey
  • darkslategray / darkslategrey
  • dimgray / dimgrey
  • lightgray / lightgrey
  • lightslategray / lightslategrey
  • gray / grey
  • slategray / slategrey

Y hay que tener en cuenta las siguientes notas también:

  • Darkgray es más claro que Gray.
  • Lightpink es más oscuro que Pink.

Aunque para hacer pruebas básicas está bien usar estos nombres, utilizarlos resulta bastante limitado.

15.1.2 Colores mediante valores hexadecimales

Una de las formas más utilizadas para definir colores en CSS es mediante valores hexadecimales. Un color hexadecimal comienza con el símbolo # y normalmente está formado por seis caracteres:

Color en hexadecimal

p { color: #ff0000; }

Los seis caracteres representan los componentes:

  • Rojo (R).
  • Verde (G).
  • Azul (B).

Por este motivo, este sistema recibe el nombre RGB hexadecimal, y se representa como #RRGGBB. Cada componente puede tener un valor entre 00 y FF. Las letras hexadecimales también se pueden escribir en minúsculas.

Fuente: Wikipedia

Con este sistema tenemos una “profundidad” de 24 bits de colores (8 bits por canal), lo que da una variedad de 16.777.216 colores.

De esta manera, a modo de ejemplos sencillos tenemos:

  • #000000: negro, por ausencia de color.
  • #FF0000: rojo
  • #00FF00: verde
  • #0000FF: azul
  • #FFFFFF: blanco, todos los colores juntos

Cuando los pares de cada componente están formados por dos caracteres iguales, podemos utilizar una forma abreviada de tres caracteres. Por lo tanto, los siguientes ejemplos son equivalentes:

  • #FF0000 es igual a #F00
  • #112233 es igual a #123
  • #00FFAA es igual a #0FA

15.1.3 Colores con rgb()

Otra posibilidad consiste en utilizar la función rgb() para representar de nuevo el sistema RGB. Con esta función cada componente se pude representar de dos maneras:

  • Valor entre 0 y 255.
  • Como porcentaje entre 0% y 100%.

Color en hexadecimal

p {
    color: rgb(255 0 0);
    background-color: rgb(30% 20% 50% );
}

La siguiente tabla es equivalente:

Hexadecimal RGB RGB
#FF0000 rgb(255 0 0) rgb(100% 0% 0%)
#00FF00 rgb(0 255 0) rgb(0% 100% 0%)
#0000FF rgb(0 0 255) rgb(0% 0% 100%)
#FFFFFF rgb(255 255 255) rgb(100% 100% 100%)
#000000 rgb(0 0 0) rgb(0% 0% 0%)

Antiguamente los valores en rgb() iba separado por comas, pero ya no es necesario.

15.1.4 Colores con HSL

CSS también permite definir colores utilizando el modelo HSL. HSL significa:

  • Hue: tono/matiz.
  • Saturation: saturación.
  • Lightness: luminosidad.

CSS permite utilizarlo mediante la función hsl(). En el siguiente ejemplo se muestra el color rojo:

Fuente: Wikipedia

Color en hexadecimal

p { color: hsl(0 100% 50%); }

HSL representa los valores como un cilindro. El primer valor representa el tono y se expresa mediante un ángulo. Por ejemplo:

  • 0°: rojo
  • 60º: amarillo
  • 120°: verde
  • 180º: cyan
  • 240°: azul
  • 300º: magenta
  • 360º: rojo de nuevo, por dar la vuelta completa al círculo.

La saturación y la luminosidad se expresan mediante porcentaje.

Fuente: techterms

Cuando la saturación tiene un valor del 100% es más intenso que cuando el mismo tiene 50%. Cuando la luminosidad es menor, obtenemos un color más oscuro, y si ponemos 0% será negro.

HSL puede resultar especialmente cómodo cuando necesitamos crear variaciones de un mismo color. En el siguiente ejemplo, jugando con la luminosidad obtendremos 3 variaciones del mismo color:

Variación de luminosidad con HSL

.color-base {
    color: hsl(210 80% 50%);
}
.color-claro {
    color: hsl(210 80% 70%);
}
.color-oscuro {
    color: hsl(210 80% 30%);
}

15.1.5 El canal alfa

El canal alfa (en inglés alpha) permite controlar la transparencia u opacidad de un color. Se puede utilizar tanto en rgb() como en hsl() añadiendo a ambas funciones un cuarto parámetro tras el carácter /.

Añadida transparencia a un color

h1{
    background-color: rgb(0 0 255 / 50%);
}
h2{
    background-color: hsl(240 100% 50% / 0.5);
}
h3{
    background-color: #FF00007F;
}

El canal alfa se puede indicar en modo porcentaje o un valor entre 0 y 1. En ambos ejemplos se está indicando que el color indicado tiene una opacidad del 50%, ya que funciona de la siguiente manera:

  • 0%: completamente transparente.
  • 50%: semitransparente.
  • 100%: completamente opaco.

En el sistema hexadecimal hay que añadir una nueva pareja al final para añadir el nivel de transparencia.

Existen otras maneras de especificar el canal alfa, usando las funciones rgba(), hsla(), pero en CSS moderno son aliases a las funciones vistas previamente.

15.1.6 La palabra clave transparent

Si queremos hacer que algo sea completamente transparente se puede utilizar la palabra clave transparent, que tal como aparece en la documentación es un alias/shortcut a rgb(0 0 0 / 0%).

Esto se suele utilizar para especificar el fondo de un elemento, para así dejar visible el posible fondo que haya.

Fondo transparente

h1{
    background-color: transparent;
}

15.2 Qué sistema utilizar

Aunque pueda parecer una respuesta ambigua, depende del proyecto y de la tecnología final que estemos utilizando, ya que esto también afecta.

Cuando usamos el sistema hexadecimal o la función rgb() estamos trabajando bajo el espacio de color denominado sRGB. Este sistema, tal como se ha dicho previamente, hace uso de 24bits (8 por canal), que hace un total de 16.777.216 colores.

En cambio, al usar hsl() no se limita a esos 8 bits por canal, y si nuestro navegador/sistema/pantalla hace uso de otra profundidad de color, podríamos estar usándola.

A medida que avanza la tecnología necesitamos nuevas maneras de representar colores, ya que el espacio de colores se amplía, como 10 bit de color por canal, HDR, …

Comparación entre sRGB y BT2020

15.3 Colores y diseño de interfaces

En una interfaz normalmente no utilizaremos colores de manera aislada, ya que lo habitual definir una pequeña paleta. Por ejemplo:

  • Color principal
  • Color secundario
  • Color de fondo
  • Color de texto
  • Color de texto secundario
  • Color de éxito
  • Color de error
  • Color de advertencia

Posteriormente, cuando estudiemos las variables CSS, podremos centralizar estos valores.

16 Fondos

CSS permite controlar el fondo de los elementos mediante diferentes propiedades. Podemos utilizar colores, imágenes, degradados y controlar aspectos como su tamaño, posición o repetición.

Las propiedades relacionadas con los fondos son especialmente importantes en el diseño de interfaces, ya que permiten crear tarjetas, cabeceras, botones, secciones destacadas y otros componentes visuales.

16.1 Color de fondo

La propiedad background-color permite establecer el color de fondo de un elemento. Podemos utilizar cualquiera de los formatos de color estudiados anteriormente:

Añadir color de fondo

body {background-color: #d0d0d0}
.div1 { background-color: #2563eb }
.div2 { background-color: rgb(37, 235, 212) }
.div3 { background-color: hsl(262 83% 53% / 0.5) }

Esta propiedad se la podemos asignar a cualquier elemento, incluso al fondo del documento en body tal como se ve en el ejemplo.

04a

Crea distintos elementos añadiendo color al fondo usando los distintos sistemas vistos previamente.

16.2 Imágenes de fondo

La propiedad background-image permite utilizar una imagen como fondo.

Añadir fondo de imagen

div { background-image: url("fondo.jpg"); }

La función url() indica la dirección de la imagen. La ruta puede ser relativa al archivo CSS o absoluta, dependiendo de cómo esté organizada la aplicación. Si queremos que sea ruta relativa, imaginando la siguiente estructura de ficheros:

Estructura de ficheros

proyecto/
├── css/
│   └── estilos.css
└── img/
    └── fondo.jpg

Para cargar la imagen desde estilos.css usaremos la siguiente ruta: url("../img/fondo.jpg").

Podemos hacer uso de background-image junto con background-color, pero el color sólo funcionará en caso de que la imagen no esté disponible.

04b

Crea elementos añadiendo imágenes como fondo. Comprueba qué pasa si se añade un background-color y si la imagen no existe.

16.2.1 background-repeat

Una imagen de fondo puede repetirse para cubrir todo el espacio disponible. Podemos controlar este comportamiento mediante background-repeat, cuyos valores principales, entre otros, son:

  • repeat: permite repetir la imagen tanto horizontal como verticalmente. Este es el comportamiento predeterminado de una imagen de fondo. Es especialmente útil cuando utilizamos imágenes pequeñas que forman patrones.
  • repeat-x: la imagen se repite horizontalmente.
  • repeat-y: la imagen se repite verticalmente.
  • no-repeat: para que la imagen no se repita, lo ideal para cuando queremos añadir sólo una fotografía de fondo.
  • space: se repite la imagen sin hacer cortes. Se pone la primera imagen al principio del elemento, y al final, y en medio se van añadiendo repeticiones, dejando huecos libres.

Las siguientes imágenes son del ejemplo de MDN.

repeat
repeat-x
no-repeat

04c

Comprueba la diferencia de los distintos parámetros de background-repeat.

16.2.2 Varias imágenes de fondo

CSS permite utilizar varias imágenes de fondo simultáneamente, lo que nos permite combinar imágenes creando efectos sin tener que pre-procesarlas previamente.

Al poner varias imágenes funciona añadiendo capas una encima de la otra: la primera que se ponga estará por encima de la segunda, y esta encima de la tercera y así sucesivamente.

En el siguiente ejemplo de la documentación de W3C se ha añadidos dos imágenes a un elemento:

HTML

<div id="example1">
  <h1>Lorem Ipsum</h1>
  <p>Lorem ipsum  ...</p>
</div>

CSS

#example1 {
  background-image: url(img_flwr.gif), url(paper.gif);
  background-position: right bottom, left top;
  background-repeat: no-repeat, repeat;
  padding: 15px;
}
#example1 p {
    width:60%;
}

Tal como se puede ver, se pueden añadir varios parámetros url() a background-image, y lo mismo para la posición y si queremos que la imagen se repita.

Importante recordar que las imágenes van por capas, de más “arriba” hacia abajo.

16.3 Otras propiedades de fondo

Existen otras propiedades que tienen que ver con el fondo, por lo que es recomendable ver la documentación para cada una de ellas para conocer sus opciones.

  • background-position: permite controlar la posición de una imagen de fondo, usando los siguientes valores:
    • Palabras clave, pudiendo combinarlos: left, center, right, top, o bottom.
    • Porcentajes con dos posiciones, posición desde la izquierda y desde arriba.
    • También se pueden usar posiciones como px y em.
  • background-size: permite controlar el tamaño de la imagen de fondo.
    • Si ponemos una única dimensión será el ancho y mantendrá la proporción. Si añadimos una segunda será la altura.
    • Si ponemos la palabra reservada cover cubrirá todo el elemento, pero si la proporción no coincide, parte de la imagen puede quedar fuera de la zona visible.
    • Si ponemos la palabra reservada contain la imagen se escala para que pueda verse completamente dentro del elemento, pero dejará espacio libre.
  • background-attachment: permite controlar el comportamiento del fondo cuando hacemos scroll. Permite los siguientes valores:
    • scroll, el comportamiento normal
    • fixed: En este caso, el fondo puede permanecer fijo mientras desplazamos el contenido.
  • background-origin: permite determinar desde qué zona de la caja se posiciona la imagen de fondo. Los valores son border-box, padding-box o content-box.

Ejemplos de sólo ciertas propiedades

.a {background-position: top left;}
.b {background-position: 10% 50%;}
.c {background-position: 10em 50px;}
.d {background-size: 300px;}
.e {background-size: cover;}
.f {background-size: contain;}

16.4 Degradados

CSS permite crear degradados sin necesidad de utilizar una imagen externa. Los degradados son generados por el navegador, lo que permite crear fondos visualmente complejos sin necesidad de descargar una imagen.

Existen distintas formas a la hora de crear degradados:

  • linear-gradient(): crea un degradado lineal. Se puede indicar la dirección como primer parámetro:
    • to right: el degradado va de izquierda a derecha.
    • to bottom: de arriba hacia abajo.
    • Se puede indicar más de dos colores, y el navegador hará transiciones entre ellos. Aparte de indicar la posición de cada uno de ellos.
  • radial-gradient(): crea un degradado que parte desde un punto central y se extiende hacia fuera.
  • conic-gradient: genera un degradado alrededor de un punto central en forma cónica

Degradado

.a { background: linear-gradient(red, orange); }
.b { background: linear-gradient(to right, red, orange, yellow); }
.c { background: linear-gradient(45deg, red 25%, yellow 50%, blue 100% ); }
.d { background: linear-gradient( to right, red 0%, yellow 50%, blue 100% ); }
.e { background: radial-gradient(circle, white, blue); }
.f { background: conic-gradient(red, orange, yellow, green, blue, purple, red); }

04d

Crea distintos degradados con las opciones vistas y que aparecen en la documentación.

16.4.1 Degradado sobre imagen

Al igual que hemos visto que se pueden poner imágenes una encima de otra, también podemos crear un degradado para poner encima de una imagen.

Degradado

.a {
    background-image:
        linear-gradient(
            rgb(0 0 0 / 50%),
            rgb(0 0 0 / 50%)
        ),
        url("paisaje.jpg");
}

El resultado es una fotografía oscurecida mediante una capa negra semitransparente, sobre la que podemos colocar texto.

16.5 La propiedad abreviada background

Hemos visto cómo crear o añadir fondos con propiedades específicas, pero a la propiedad background se le pueden añadir todos los atributos vistos previamente en el siguiente orden:

CSS

.caja {
    background:
        #222
        url("imagen.jpg")
        no-repeat
        center
        / cover;
}

Con esta única propiedad hemos establecido el color de fondo, una imagen, la repetición, la posición y el tamaño. La propiedad abreviada puede resultar muy útil, pero al principio puede ser más sencillo utilizar las propiedades individuales.

Box Model y dimensiones

17 Box Model

Para comprender realmente cómo se comporta una página web es necesario conocer el modelo de cajas (Box Model), uno de los conceptos más importantes de CSS.

El navegador no interpreta los elementos HTML como texto o imágenes aisladas, sino como cajas rectangulares. Cada párrafo, botón, imagen, encabezado o formulario ocupa una caja con unas dimensiones y un espacio determinado respecto a los demás elementos.

Comprender el modelo de cajas permitirá responder preguntas como:

  • ¿Por qué dos elementos están separados?
  • ¿Por qué una caja ocupa más espacio del esperado?
  • ¿Cuál es la diferencia entre padding y margin?
  • ¿Por qué un borde modifica el tamaño visible de un elemento?

17.1 Áreas de una caja

Tal como se ha dicho, cada elemento en HTML es interpretada como una caja rectangular, que a su vez cuenta con cuatro áreas distintas:

  1. Contenido (content): Contenido del elemento.
  2. Relleno (padding): Espacio interior.
  3. Borde (border): Borde visible.
  4. Margen (margin): Espacio exterior para separar esta caja de otras vecinas.

El tamaño de la caja es calculado por el navegador teniendo en cuenta el espacio de todas ellas. En las siguientes imágenes se pueden apreciar mejor:

Modelo caja en MDN
Modelo caja Chrome
Modelo caja Firefox

Desde las herramientas del desarrollador de nuestro navegador podemos ver el box model y el tamaño que ocupa cada elemento de una página.

Este modelo constituye la base del diseño en CSS y es imprescindible entenderlo antes de ver apartados más complejos.

17.2 Tamaño de la caja y box-sizing

Supongamos que tenemos la siguiente caja:

Máxima altura

.caja {
    width: 300px;
    height: 200px;
    padding: 20px;
    border: 5px solid black;
    margin: 10px;
}

Aunque todavía no hayamos visto las propiedades en profundidad, pero teniendo en cuenta el modelo de caja visto anteriormente:

¿Cuál crees que es la anchura total de la caja? ¿Y la altura?

En el ejemplo anterior la anchura de la caja es de 300+20+20+5+5=350px, ya que hay que sumar la anchura establecida, más el padding a cada lado y la anchura del borde, también a cada lado. El margen no entra en el cómputo del tamaño, al ser separación entre elementos. Este comportamiento puede resultar extraño al principio.

La propiedad box-sizing permite modificar cómo se calculan las dimensiones. Existen dos valores principales:

  • content-box: es el comportamiento tradicional. La anchura corresponde al contenido. Este es el comportamiento por defecto.
  • border-box: el ancho incluye el padding y el borde. Este comportamiento resulta más intuitivo.

En las siguientes imágenes se puede apreciar mejor la diferencia en el cálculo de la dimensión real de la caja:

Comparación
Content-box
Border-box

Tal como se puede ver, cuando la opción es content-box el tamaño es el establecido en width, y después se añade los tamaños restantes. En cambio, cuando es border-box, las herramientas del desarrollador muestran cómo al tamaño del contenido se le ha restado el tamaño del padding y el border para que coincida con el total de width

04i

Comprueba el uso de box-sizing y la diferencia entre configurarlo como content-box o border-box. Interioriza la diferencia y piensa cuál usarías en un proyecto real.

17.2.1 Modificar a box-sizing:border-box en toda la página

Si queremos hacer uso de box-sizing: border-box en nuestra página web, y aplicarlo a todo sin tener que ir elemento a elemento, podemos usar la siguiente regla al comienzo de nuestro CSS:

Aplicar border-box a todo

*,
*::before,
*::after {
    box-sizing: border-box;
}

De esta forma, todos los elementos utilizan el mismo modelo de caja. Actualmente es una práctica muy recomendada porque facilita enormemente el cálculo de dimensiones.

Hoy en día se recomienda box-sizing: border-box como decisión de diseño inicial.

Es importante conocer el comportamiento por defecto, ya que si se decide cambiar después, supondría tener que volver a redimensionar todos los componentes que hayamos hecho.

17.3 Elementos de bloque y elementos en línea

El modelo de caja afecta a todos los elementos, aunque no todos se comportan igual. Los elementos pueden ser de bloque o elementos en línea, pero nunca los dos a la vez.

17.3.1 Elementos de bloque

Los elementos de bloque tienen las siguientes características:

  • Ocupan todo el ancho disponible.
  • Comienzan en una línea nueva.
  • Admiten anchura y altura.

En la siguiente tabla están todos los elementos de tipo bloque (fuente: w3schools):

<address> <article> <aside> <blockquote> <canvas> <dd>
<div> <dl> <dt> <fieldset> <figcaption> <figure>
<footer> <form> <h1> -<h6> <header> <hr>
<main> <nav> <noscript> <ol> <p> <pre>
<section> <table> <tfoot> <ul> <video>

17.3.2 Elementos en línea

Los elementos en línea tienen las siguientes características:

  • Ocupan únicamente el espacio de su contenido.
  • No comienzan una línea nueva.
  • Su comportamiento respecto a anchura y altura es diferente.

En la siguiente tabla están todos los elementos de tipo bloque (fuente: w3schools):

<a> <abbr> <b> <bdo> <br> <button>
<cite> <code> <dfn> <em> <i> <img>
<input> <kbd> <label> <map> <object> <output>
<q> <samp> <script> <select> <small> <span>
<strong> <sub> <sup> <textarea> <time> <var>

Más adelante estudiaremos la propiedad display, que permite modificar este comportamiento.

18 Dimensiones

Las dimensiones permiten controlar el tamaño de los elementos HTML. CSS proporciona propiedades para definir el ancho, la altura, así como límites mínimos y máximos que hacen posible crear interfaces adaptables a diferentes dispositivos.

Las siguientes propiedades forman parte del modelo de caja y son fundamentales para construir cualquier diseño web:

  • width: ancho del área de elemento.
  • min-width: ancho mínimo del elemento.
  • max-width: ancho máximo del elemento.
  • height: altura del elemento.
  • min-height: altura mínima del elemento.
  • max-height: altura máxima del elemento.
  • box-sizing: qué tipo de “modelo de caja” usar para el cálculo de dimensiones.

18.1 Dimensiones por zona

A continuación vamos a ver distintas propiedades para modificar las dimensiones de las cajas del box model de HTML. Las propiedades se pueden diferenciar entre:

  • Propiedad general: el nombre no indica a qué zona afecta, y por tanto modificará todas las áreas.
  • Propiedad específica: indica qué zona va a modificar, y sólo afectará a esa zona.

18.1.1 Propiedad general: todas las zonas

Son las propiedades que afectan a todas las áreas del box model: arriba, derecha, abajo e izquierda. Por lo tanto, si tenemos el siguiente ejemplo:

Padding

.caja {
    padding: 30px;
}

Indica que nuestra caja tiene 30px de padding en cada área: arriba, derecha, abajo e izquierda. Podemos utilizar las propiedades generales para especificar que sólo queremos afectar a ciertas áreas, y eso depende de cuántos parámetros pasemos:

¿a qué área afecta?

.a { padding: 2px; }
.b { padding: 2px 4px; }
.c { padding: 2px 4px 6px; }
.d { padding: 1px 2px 3px 4px;}
  • 1 valor: indicamos todas las áreas.
  • 2 valores: primer valor es top y bottom, el segundo para right y left.
  • 3 valores: top, right y left, último valor es bottom.
  • 4 valores: top, right, bottom y down

Esto afecta a propiedades como padding, border-width y margin.

Es importante conocer este orden ya que se repite en varias propiedades generales que veremos a continuación.

18.1.2 Propiedad específica: sólo afecta a una zona

Para muchas propiedades que veremos a continuación existen propiedades específicas que sólo afectan al área correspondiente. Por ejemplo:

  • padding-top: sólo añade padding a la parte superior.
  • border-right: para configurar sólo el borde del lado derecho.
  • margin-bottom: sólo añade margen en la parte inferior.

De esta manera, con el nombre de la propiedad ya se especifica claramente a qué zona afecta.

18.2 La propiedad width

La propiedad width establece el ancho del área de contenido de un elemento.

Anchura

.caja {
    width: 300px;
}

El contenido tendrá un ancho de 300px. Es importante recordar que, por defecto, el padding y el border no están incluidos dentro de ese ancho. Este comportamiento se estudiará más adelante con box-sizing.

18.2.1 Ancho relativo

Los porcentajes permiten crear elementos adaptables.

Padding con anchura relativa

.contenedor { width: 80%; }

El ancho dependerá del tamaño del elemento contenedor. Si el contenedor mide 1000px, el elemento ocupará aproximadamente 800px. Si posteriormente mide 600px, el ancho pasará a ser aproximadamente 480px.

18.3 Propiedad min-width

La propiedad min-width establece el ancho mínimo que puede tener un elemento.

Anchura y asegurar ancho mínimo

.caja {
    width: 50%;
    min-width: 250px;
}

El elemento intentará ocupar el 50% pero nunca será inferior a 250px. Esta propiedad resulta muy útil en diseños responsive.

18.4 Propiedad max-width

max-width establece el ancho máximo permitido.

Anchura y asegurar ancho máximo

.caja {
    width: 90%;
    max-width: 1200px;
}

Este patrón es extremadamente habitual. Por defecto, en pantallas pequeñas ocupará el 90%, mientras que en pantallas grandes nunca superará los 1200px. De esta forma evitamos que el contenido resulte excesivamente ancho.

18.5 La propiedad height

height define la altura del área de contenido.

Altura

.caja { height: 200px; }

El contenido dispondrá de una altura de 200px. Si el contenido ocupa más espacio del disponible, puede producirse un desbordamiento, que estudiaremos en el siguiente apartado.

Un porcentaje en height solo funciona correctamente cuando el elemento padre tiene una altura definida. Si el elemento padre no tiene altura definida, el porcentaje puede no producir el resultado esperado.

18.6 Propiedad min-height

La propiedad min-height establece una altura mínima.

Altura

.caja { min-height: 200px; }

Aunque el contenido sea muy pequeño, la caja tendrá al menos 200px de altura. Si el contenido crece, el elemento también crecerá.

Es recomendable usar min-height antes que una altura fija cuando el contenido puede crecer.

18.7 Propiedad max-height

max-height limita la altura máxima.

Máxima altura

.caja { max-height: 400px; }

Si el contenido supera ese tamaño, podrá producirse un desbordamiento dependiendo de la propiedad overflow. Esta combinación es muy frecuente en paneles laterales y listas con desplazamiento.

19 Overflow / desbordamiento

En ocasiones, el contenido de un elemento ocupa más espacio del disponible. Esto puede ocurrir porque el texto es demasiado largo, una imagen es muy grande o hemos establecido unas dimensiones fijas demasiado pequeñas.

La propiedad overflow controla qué debe hacer el navegador cuando el contenido desborda los límites del elemento. Es una propiedad muy utilizada en paneles, tarjetas, menús, ventanas modales y contenedores con desplazamiento.

Supongamos una caja con un alto fijo como el siguiente ejemplo:

Caja

.caja {
    width: 100px;
    height: 100px;
    border: 2px solid black;
}

Si introducimos un texto muy largo, el contenido puede superar la altura disponible, lo que se denomina overflow o desbordamiento. El navegador debe decidir qué hacer con ese contenido, y para ello utilizamos la propiedad overflow, que podemos configurar con una de las siguientes opciones:

  • auto: Las barras aparecen solo cuando son necesarias.
  • hidden: El contenido sobrante se oculta.
  • scroll: Siempre aparecen barras de desplazamiento.
  • visible: El contenido sobresale del elemento.

Una vez decidido qué configuración debemos hacer, la añadimos al CSS:

Caja con overflow

.caja {
    width: 100px;
    height: 100px;
    border: 2px solid black;
    overflow: auto;
}
 como: , ,  y

19.1 Control independiente de cada eje

A la hora de controlar el desbordamiento, podemos controlarlo de manera separada para el eje horizontal y el vertical. Para ello están las propiedades

  • overflow-x: para el eje horizontal.
  • overflow-y: para el eje vertical.

04j y 04k

Usa overflow y sus variantes junto con las propiedades de anchura y altura vistas anteriormente.

20 Padding

El padding es el espacio interior que existe entre el contenido de un elemento y su borde. Forma parte del modelo de caja (Box Model) y se utiliza para crear separación interna, mejorar la legibilidad y aumentar el área útil de elementos como botones, tarjetas o formularios.

Vamos a recordar la imagen puesta previamente, ya que es importante diferenciarlo del margen:

Modelo caja en MDN
Modelo caja Chrome
Modelo caja Firefox

Recordamos que:

  • Padding: espacio interior entre el contenido y el borde.
  • Margin: espacio exterior entre elementos.

Por lo tanto, podemos hacer el siguiente ejemplo:

Padding

.caja {
    padding: 20px;
}

El contenido quedará separado 20px del borde por todos sus lados. Tal como hemos visto anteriormente, padding tiene una propiedad para cada lado de la caja con padding-top, padding-right, padding-bottom y padding-left.

En el caso de añadir color de fondo sí cubre el padding y llegará hasta el borde.

20.1 Uso de padding en botones

Uno de los usos más habituales del padding es aumentar el área de pulsación de un botón. Aunque el texto sea pequeño, el botón tendrá una superficie mucho más cómoda para el usuario. Este patrón aparece prácticamente en cualquier interfaz moderna.

04h

Crea distintos elementos añadiendo padding. Modifica un botón para añadir un padding personalizado y así darle más área de pulsación. Compara cómo afecta el padding respecto al margen del ejeercicio anterior.

21 Bordes

Los bordes permiten delimitar visualmente los elementos de una página web. CSS ofrece un conjunto de propiedades para controlar su grosor, estilo, color y forma.

Los bordes son uno de los componentes fundamentales del modelo de caja (Box Model) y se utilizan constantemente para crear botones, tarjetas, formularios, tablas y otros elementos de la interfaz.

21.1 La propiedad border

La forma más sencilla de crear un borde consiste en utilizar la propiedad abreviada border, a la que se le pasan tres parámetros:

  • Grosor del borde: Se puede añadir con una unidad de medida o con palabras clave como thin, medium, thick.
  • Estilo de línea: hay distintas palabras claves que indican el tipo de borde:
    • none: Sin borde.
    • solid: Línea continua.
    • dashed: Línea discontinua.
    • dotted: Línea de puntos.
    • double: Línea doble.
    • groove: Efecto tridimensional hundido.
    • ridge: Efecto tridimensional elevado.
    • inset: Aspecto interior.
    • outset: Aspecto exterior.
  • Color del borde.

En el siguiente ejemplo se puede ver el código en una única propiedad o separado cada parámetro en su propiedad:

Propiedad border

p { 
    border: 2px solid black;
}

Propiedad border

p {
    border-width: 2px;
    border-style: solid;
    border-color: black;
}

La propiedad border-width es una propiedad “general” que acepta de uno a cuatro parámetros para las distintas zonas, tal como se ha explicado anteriormente.

04e

Crea distintos bordes con distintos grosores, estilos y colores.

21.2 Bordes diferentes en cada lado

CSS permite configurar cada lado del borde de forma independiente con las propiedades border-top, border-right, border-bottom y border-left.

Funcionan igual que border, por lo que podemos asignar a cada lado un grosor, estilo y color distintos.

Y si queremos asignar cada característica concreta por separado, tenemos propiedades separadas como:

  • border-top-width
  • border-right-style
  • border-bottom-color

Y así para cada lado de la caja y propiedad.

21.3 Bordes redondeados con border-radius

Una de las propiedades más utilizadas es border-radius, que permite redondear las esquinas.

Propiedad border-radius

.a { border-radius: 5px; }
.b { border-radius: 1rem; }
.c { border-radius: 50%; }

Círculo perfecto

.avatar {
    width: 120px;
    height: 120px;
    border-radius: 50%;
}

Cada esquina puede configurarse de forma independiente a través de las propiedades específicas:

  • border-top-left-radius
  • border-top-right-radius
  • border-bottom-right-radius
  • border-bottom-left-radius

21.4 Bordes elípticos

border-radius también permite definir radios horizontales y verticales diferentes.

Borde elíptico

.caja {
    border-radius: 50px / 20px;
}

Esto genera esquinas con forma elíptica en lugar de circular. Aunque es una característica interesante, en la mayoría de los diseños se utilizan radios iguales. Para entender bien los bordes elípticos podemos ver cómo funcionan en la web border-radius generator de MDN.

04f

Crea bordes distintos para cada lado de la caja. Crea otros bordes con borde redondeados, elípticos y de distintos tamaños

22 Márgenes

Los márgenes son el espacio exterior que existe alrededor de un elemento, después del borde. Permiten separar unos elementos de otros y son una de las partes fundamentales del modelo de caja (box model). Recordamos una vez más:

  • Padding: espacio interior entre el contenido y el borde.
  • Margin: espacio exterior entre elementos.

La forma más sencilla de establecer márgenes es mediante la propiedad margin:

Margen de 20px

.caja {
    margin: 20px;
}

Cada zona también tiene una propiedad específica: margin-top, margin-right, margin-bottom y margin-left.

Podemos indicar los distintos tipos de unidades que ya hemos visto previamente:

Margen de 20px

.caja {
    margin: 1em 20px 2rem 5%;
}

Si usamos porcentaje para el margen, hará que dependa del tamaño de la ventana, lo que puede ser útil en diseños responsive.

Podemos añadir márgenes negativos, lo que hará que el contenido se desplace hacia el lado contrario al “natural”. Los márgenes negativos son una herramienta potente, pero deben utilizarse con moderación porque pueden provocar solapamientos difíciles de mantener.

Cuidado al usar márgenes negativos, puede provocar solapamientos no deseados.

22.1 margin: auto

El valor especial auto permite que el navegador calcule automáticamente el margen. El caso más conocido es el centrado horizontal.

Margen auto

.caja {
    margin: auto;
}

Es importante darse cuenta que si sólo indicamos auto desaparece automáticamente el margen superior e inferior

22.2 Márgenes y fondo

Una característica importante es que el color de fondo no se extiende al margen.

Por ejemplo:

Margen y fondo

.caja {
    margin: 20px;
    background-color: lightblue;
    border: 1px solid black;
}

El color azul solo ocupa hasta llegar al borde. Todo lo que va después, que es el margen, no tendrá ese color de fondo.

Es importante entender hasta dónde llega el contenido de la caja, y el color de fondo no sobrepasa el borde.

22.3 Colapso de márgenes

Una característica exclusiva de los márgenes verticales es el colapso de márgenes (margin collapsing).

Supón Bloque A y B, ambos seguidos verticalmente. El A tiene margin-bottom=20px, el B margin-top=30px. ¿Cuál es la separación vertical entre ambos?

La lógica supondría pensar en 50px, pero no, ya que los márgenes verticales adyacentes colapsan y se utiliza el mayor de ellos, en este caso, 30px. En la documentación se explican todos los casos.

También hay que tener en cuenta el colapso no se produce en todos los casos. Por ejemplo:

  • Márgenes horizontales.
  • Elementos Flexbox.
  • Elementos Grid.
  • Elementos con posicionamiento especial.
  • Elementos separados por padding o borde.

Por ello, en diseños modernos basados en Flexbox o Grid este comportamiento aparece con mucha menos frecuencia.

04g

Crea distintos elementos añadiendo márgenes. Comprueba qué sucede al ponerlo como auto, diferencia entre márgenes verticales y horizontales, y comprueba el colapso vertical de elementos adyacentes.

Variables, funciones y organización

23 Variables en CSS

Las variables CSS, también conocidas como propiedades personalizadas (Custom Properties), permiten almacenar valores reutilizables dentro de una hoja de estilos. Gracias a ellas podemos definir colores, tamaños, márgenes o cualquier otro valor una única vez y reutilizarlo en todo el proyecto.

Su uso facilita el mantenimiento del código, evita duplicar valores y hace mucho más sencillo crear temas claros, oscuros o modificar la identidad visual de una aplicación.

Aunque hoy día resulta extraño no usarlas, las variables no fueron efectivas en muchos navegadores hasta 2016, y previamente su uso sólo existía en los pre-procesadores CSS.

23.1 Cómo crear una variable en CSS

Una variable CSS es una propiedad cuyo nombre comienza por dos guiones (--), para después poder usarla con la función var() indicando el nombre dado previamente. La razón de que las variables empiecen por -- es para distinguir las propiedades personalizadas de las estándar de CSS.

Declaración de una variable

:root {
  /* COLORES */
  --color-main: #2563eb;
  --color-ok: #16a34a;
  --color-error: #dc2626;
  --color-text: #222222;
  /* ESPACIO */
  --espacio-md: 1rem;
  /* BORDES */
  --bordes: 2px;
  --radio: 10px;
}

Uso de la variable

h1 {
    color: var(--color-main);
}
a {
    color: var(--color-main);
}
.ok {
    border: var(--bordes) solid var(--color-ok);
    border-radius: var(--radio);
    padding: var(--espacio-md);
}

Lo más habitual es declarar las variables dentro del selector :root, de esta manera las variables estarán disponibles en toda la página. Por este motivo, suele utilizarse como lugar donde se almacena la configuración global del diseño.

Las variables se pueden usar tantas veces como sea necesario, y si en el futuro se quieren realizar modificaciones, sólo es necesario cambiarlo en la declaración, y eso hará que toda la página cambie.

Tal como se puede ver en el ejemplo, en las variables se pueden usar no sólo para colores, sino también para espaciados e incluso tipografías.

Es recomendable agrupar las variables por categorías y mantener una convención de nombres descriptivos.

23.2 Variables locales y herencia

En el apartado anterior hemos visto cómo crear variables “globales”, ya que se han definido en :root, pero podemos crear variables locales a un elemento. Hay que tener en cuenta que las variables CSS se heredan, por lo que si definimos una variable en un elemento, sus hijos podrán utilizarla.

Variable local y heredada

.tarjeta {
    --color-local: blue;
}

.tarjeta p {
    color: var(--color-local);
}

La variable únicamente existe dentro de .tarjeta y de sus elementos descendientes. Esto permite crear componentes con configuraciones propias.

Es importante que al crear variables locales, cada componente puede definir otra variable con el mismo nombre, y por tanto serán definiciones distintas, ya que cada componente mantiene su propio contexto:

Variable local en componente

.alerta {
    --color: #dc2626;

    color: var(--color);
    border: 2px solid var(--color);
}

Variable local en componente

.exito {
    --color: #16a34a;

    color: var(--color);
}

23.3 Reasignación de variables para reutilización

Podemos hacer componentes genéricos y después crear variantes sólo modificando el valor de una variable, de esta manera no tenemos que repetir todas las propiedades.

Componente genérico

.boton {
  --color-boton: #2563eb;
  background: var(--color-boton);
  border: 2px solid var(--color-boton);
  color: white;
}

Sólo modificamos color

.boton-rojo {
    --color-boton: #dc2626;
}

.boton-verde {
    --color-boton: #16a34a;
}

Después, en el HTML el componente tendrá las clases que necesitemos.

05a

Crea distintas variables globales, locales, que se hereden y modifiquen en distintos componentes y haz uso de ellas.

23.4 Valores por defecto con var()

La función var() admite un segundo parámetro que actúa como valor de respaldo. Si la primera variable no existe, utilizará el segundo valor.

Valor principal y de respaldo

color: var(--color-texto, black);

Este mecanismo resulta útil cuando desarrollamos componentes reutilizables.

23.5 Variables y modo oscuro

Una de las grandes ventajas de las variables CSS es la creación de temas. Hoy en día es habitual que las webs cuenten con un modo claro y un modo oscuro.

Temas

/* tema claro*/
:root {
    --fondo: white;
    --texto: #222;
}
/* tema oscuro */
body.dark {
    --fondo: #111;
    --texto: #eee;
}

Usar tema

body {
    background: var(--fondo);
    color: var(--texto);
}

Al cambiar la clase del <body>, toda la interfaz cambia automáticamente.

23.6 Variables y calc()

Las variables pueden combinarse con funciones CSS, de esta manera el navegador realiza el cálculo automáticamente.

Variable

:root {
    --espacio: 1rem;
}

Uso con calc

.caja {
    padding: calc(var(--espacio) * 2);
}

Esta combinación es muy potente para crear sistemas de diseño flexibles.

24 Funciones CSS

Las funciones CSS son expresiones especiales que permiten realizar cálculos, manipular colores, utilizar variables o generar valores dinámicos dentro de una hoja de estilos. Una función se reconoce porque está formada por un nombre seguido de paréntesis. Ya hemos visto alguna de ellas como:

  • calc(): realiza cálculos permitiendo distintas unidades de medida.
  • min(): devuelve el valor mínimo.
  • max(): devuelve el valor máximo.
  • clamp(): limita el valor entre un mínimo, uno preferido y un máximo.
  • var(): para uso de variables.
  • url(): para poder añadir imágenes.

Existen otras funciones, casi todas ellas funciones matemáticas, que podemos ver en la documentación y es interesante conocerlas, ya que quizá sean de utilidad en nuestro proyecto.

24.1 Función if()

Aunque CSS nació como un lenguaje de hoja de estilos, ya hemos visto que cuenta con funciones, variables, permite realizar cálculos, y como está en constante evolución, en 2025 se propuso crear el condicional if().

El condicional if() a día de hoy sólo es funcional en Chrome, Opera y derivados. No lo vamos a usar.

Condicional if()

.ok {
    background-color: if(
        style(--black: true): black;
        else: white;
    );
    color: if(
        style(--black: true): white;
        else: black;
    );
}

Usar tema

<div class="ok">
    Lorem ipsum ... 
</div>
<div class="ok" style="--black: true">
    Lorem ipsum ...
</div>

En el ejemplo vemos cómo hacer uso del condicional para modificar el color del texto y el fondo.

24.2 Creación de funciones

De nuevo, este apartado sólo sirve para ver que CSS está evolucionando y añadiendo características más propias de un lenguaje de programación que de una hoja de estilos.

La regla @function nos permitirá definir funciones reutilizables, a las que les podremos pasar parámetros y devolver valores.

La regla @function a día de hoy sólo es funcional en Chrome, Opera y derivados. No la vamos a usar.

Declaración de función

:root {
  --espacio-md: 1rem;
}

@function --double(--value) {
  result: calc(var(--value) * 2);
}

Uso de función

p {
  --base-spacing: 10px;
  border-radius: --double(var(--espacio-md));
  padding: --double(var(--espacio-md));
}

Se ha declarado una función que recibe como parámetro un valor y devuelve el doble del mismo. A la hora de usar la función se le ha pasado una variable ya existente, de esta manera podemos ver cómo CSS casi se vuelve un “lenguaje de programación”

05b

Prueba este ejemplo en Chrome y en otro navegador no compatible.

Posiciones y visibilidad

25 display

La propiedad display determina cómo se representa un elemento HTML dentro del documento. Es una de las propiedades más importantes de CSS, ya que controla si un elemento ocupa toda la línea, se comporta como texto, puede alinearse con otros elementos o incluso si desaparece completamente del flujo de la página.

Ya hemos visto previamente que los elementos se pueden diferenciar entre elementos de bloque y elementos en línea, sin embargo CSS permite modificar este comportamiento mediante la propiedad display.

Los valores que podemos poner a display son:

Valor Uso principal
block Elemento de bloque
inline Elemento en línea
inline-block Mezcla de bloque y línea
none Oculta el elemento
flex Contenedor Flexbox
inline-flex Flexbox en línea
grid Contenedor Grid
inline-grid Grid en línea

En esta unidad nos centraremos en los cuatro primeros. Flexbox y Grid se estudiarán en las siguientes unidades.

25.1 display: block

Podemos convertir cualquier elemento en un elemento de bloque.

HTML

<span>Inicio</span>

CSS

span {
    display: block;
}

Ahora el <span> comenzará en una línea nueva y ocupará todo el ancho disponible. Este recurso es muy útil para convertir enlaces o elementos en línea en componentes más grandes.

25.2 display: inline

Podemos convertir un elemento de bloque en un elemento en línea.

HTML

<div>Uno</div>
<div>Dos</div>
<div>Tres</div>

CSS

div {
    display: inline;
}

El resultado serán los tres elementos en una única línea, uno junto a otro. Sin embargo, presentan una limitación importante: no respetan correctamente width ni height, ya que los elementos en línea se dimensionan principalmente según su contenido. Cuando necesitamos controlar el tamaño suele utilizarse inline-block que veremos a continuación.

25.3 display: inline-block

La opción inline-block combina las ventajas de ambos modelos. Características:

  • Se coloca en la misma línea que otros elementos.
  • Permite definir width y height.
  • Respeta padding y margin.

CSS

.boton {
    display: inline-block;
    width: 140px;
    padding: 12px;
    border: 1px solid black;
}

Es una propiedad muy utilizada para crear botones y pequeños componentes antes de la popularización de Flexbox.

25.4 display: none

El valor none elimina completamente el elemento del flujo del documento.

HTML

<p>Primer párrafo</p>
<p class="oculto">Segundo</p>
<p>Tercer párrafo</p>

CSS

.oculto {
    display: none;
}

El segundo párrafo desaparece y deja de ocupar espacio.

25.4.1 Diferencia entre display: none y visibility: hidden

Aunque ambas propiedades ocultan elementos, su comportamiento es diferente.

  • display: none
    • No se muestra.
    • No ocupa espacio.
    • Desaparece del flujo del documento.
  • visibility: hidden
    • No se muestra.
    • Sí ocupa espacio.
    • El resto de elementos mantiene su posición.

Estudiaremos visibility con detalle más adelante.

25.5 Valores: flex y grid

Además de los valores clásicos, display activa sistemas completos de maquetación.

  • display: flex: Convierte el elemento en un contenedor flexible.
  • display: grid: Convierte el elemento en un contenedor de rejilla.

Estos dos modelos los veremos en profundidad más adelante.

25.6 Valores: inline-flex y inline-grid

También existen versiones en línea. Se comportan como un elemento en línea respecto al documento, pero su contenido interno utiliza Flexbox o Grid. Son útiles para pequeños componentes como grupos de botones o iconos.

25.7 Cambiar el comportamiento de un elemento

Uno de los puntos fuertes de CSS es que el comportamiento visual puede modificarse sin alterar el HTML. Por ejemplo, un menú estilo navbar puede escribirse como una lista:

HTML

<ul>
    <li>Inicio</li>
    <li>Productos</li>
    <li>Contacto</li>
</ul>

Posteriormente, CSS puede convertir sus elementos en una distribución horizontal mediante display. Esto permite mantener un HTML semántico y utilizar CSS únicamente para la presentación.

06a

Comprueba las diferencias entre los elementos de bloque y los elementos en línea y cómo afecta display con block, inline y inline-block a su comportamiento. Trata de hacer un navbar con una lista.

26 position

Por defecto, los elementos HTML aparecen en el mismo orden en que están escritos en el documento. El navegador los coloca uno detrás de otro respetando el flujo normal de la página.

La propiedad position permite modificar ese comportamiento y controlar la posición exacta de un elemento. Gracias a ella podemos crear menús fijos, ventanas emergentes, etiquetas sobre imágenes o elementos que permanezcan visibles durante el desplazamiento de la página.

Los valores disponibles son:

Valor Descripción
static Posición normal
relative Desplazamiento respecto a su posición original
absolute Posición absoluta respecto a un ancestro
fixed Posición fija respecto a la ventana
sticky Combinación de relativa y fija

Cada uno modifica la forma en la que el navegador calcula la posición del elemento. Para mover un elemento también se utilizan las propiedades top, right, bottom y left que veremos en los ejemplos para posicionar el elemento.

26.1 Flujo normal del documento

Observemos un documento sencillo.

HTML

<header>Cabecera</header>

<main>Contenido</main>

<footer>Pie de página</footer>

Sin aplicar ninguna propiedad de posicionamiento, el navegador coloca los elementos siguiendo el orden del HTML. Este comportamiento recibe el nombre de flujo normal del documento (Normal Flow).

Todos los elementos tienen inicialmente position: static.

26.2 position: static

Es el valor por defecto. El elemento permanece dentro del flujo normal y las propiedades top, right, bottom y left son ignoradas.

CSS

div {
    position: static;
    top: 50px;
}

En este ejemplo, top no producirá ningún efecto. Normalmente no es necesario escribir position: static, ya que todos los elementos lo poseen inicialmente.

26.3 position: relative

El valor relative desplaza un elemento respecto a su posición original.

HTML

<div class="caja">
    Caja
</div>

CSS

.caja {
    position: relative;
    top: 20px;
    left: 20px;
}

El resultado es que la caja se mueve 20px hacia la derecha y arriba (añade 20px a la izquierda y arriba del elemento). Lo importante es que su espacio original sigue existiendo. Es decir, el resto de elementos continúa comportándose como si la caja no se hubiera movido.

Ejemplo de

Las propiedades top, right, bottom y left tienen en cuenta el espacio a ese lado del elemento.

Además de pequeños desplazamientos, relative tiene una función muy importante: servir de referencia para elementos absolutos, que veremos después.

26.4 position: absolute

Un elemento absoluto sale del flujo normal del documento.

HTML

<div class="padre">
    <div class="hijo"></div>
</div>

CSS

.padre {
    position: relative;
}

.hijo {
    position: absolute;
    top: 20px;
    left: 10px;
}

La caja hija aparecerá situada un poco hacia abajo y la derecha del elemento padre. El resto de elementos actuarán como si el hijo no ocupase espacio.

Ejemplo de

Un elemento absoluto busca el primer ancestro cuyo position no sea static, y en caso de no haber, la referencia será toda la página. Por eso es muy habitual ver una combinación como la que aparece en el ejemplo.

Un elemento absoluto busca el primer ancestro cuyo position no sea static.

Si ningún ancestro está posicionado, la referencia será toda la página.

Pongamos otro ejemplo, esta vez con un texto superpuesto a una imagen:

HTML

<div class="producto">
    <img src="camiseta.jpg" alt="">
    <span class="oferta">-20%</span>
</div>

CSS

.producto {
    position: relative;
}

.oferta {
    position: absolute;
    top: 10px;
    left: 10px;
    background: crimson;
    color: white;
}

26.5 position: fixed

Un elemento fijo permanece siempre en la misma posición de la ventana del navegador. Aunque el usuario haga scroll, el menú continuará visible.

CSS

.menu {
    position: fixed;

    top: 0;
    left: 0;
}

Los elementos fijos se utilizan para:

  • Cabeceras.
  • Botones de volver arriba.
  • Chats flotantes.
  • Barras de navegación.

También salen del flujo normal del documento.

26.6 position: sticky

El valor sticky combina el comportamiento de relative y fixed. Inicialmente el elemento se comporta como uno normal. Cuando alcanza una determinada posición durante el desplazamiento, queda fijado.

CSS

aside {
    position: sticky;
    top: 20px;
}

El elemento permanecerá pegado a 20px del borde superior mientras exista espacio dentro de su contenedor. Es muy útil para índices y barras laterales.

06b

Usa la propiedad position para crear los siguientes ejemplos:

  • Caja con posición estática.
  • Añade a una imagen un texto de “Descuento” con posición relativa abajo-izquierda.
  • Crea un navbar que esté fixed arriba.
  • Crea un mensaje de “aviso” que sea sticky mientras vemos unos párrafos.

¿Qué hay “raro” al hacer scroll en este ejercicio? Lo solucionaremos en el ejercicio 6d.

27 float (visión histórica)

Antes de la aparición de Flexbox y CSS Grid, la propiedad float era la herramienta más utilizada para crear diseños con columnas, menús horizontales y distribuciones complejas. Durante más de una década fue prácticamente la única solución disponible para maquetar páginas web, aunque realmente fue diseñada con un objetivo muy diferente.

Hoy en día float ya no se utiliza para crear maquetaciones, pero sigue formando parte del estándar CSS y todavía resulta útil para rodear imágenes con texto (su finalidad original), igual que en un procesador de textos, tal como se ve en revistas y periódicos.

La propiedad admite cuatro valores principales:

Valor Descripción
left Flota hacia la izquierda
right Flota hacia la derecha
none Sin flotación
inline-start / inline-end Versiones adaptadas a la dirección del texto (uso menos frecuente)

Con left y right el elemento se desplazará al lado izquierdo y derecho respectivamente, y el texto (o elementos posteriores) ocuparán ese espacio dejado. Es el uso principal hoy día.

HTML

<img src="moon.jpg" class="foto">

<p>Lorem ipsum dolor...</p>
<p>Lorem ipsum dolor...</p>

CSS

.foto {
    float: left;
    margin-right: 1rem;
    margin-bottom: 0.5rem;
}

Cuando un elemento flota:

  • Sale parcialmente del flujo normal.
  • Se desplaza hacia un lateral.
  • Los elementos posteriores intentan rodearlo.

06c

Usa la propiedad float para rodear dos imágenes, una colocándola a la izquierda, y la otra a la derecha.

27.1 Usos históricos

Debido a la falta de otros sistemas, durante los años 2000 float se utilizaba para crear maquetación para la que no había sido diseñado, sobre todo la creación de columnas. Aunque visualmente funcionaba, generaba muchos problemas de mantenimiento.

Entre los inconvenientes más famosos era el colapso del contenedor, en el que el elemento padre dejaba de reconocer la altura y por tanto el elemento se desplazaba.

Debido a ello, empezaron a crearse hacks para tratar de mejorar la maquetación y evitar estos problemas, que hoy día están obsoletos debido a la aparición de Flexbox y Grid.

No se debería usar float para realizar maquetaciones, sólo para rodear una imagen por texto.

28 La propiedad z-index

En muchas interfaces web existen elementos que se superponen entre sí: ventanas modales, menús desplegables, cabeceras fijas, etiquetas sobre imágenes o botones flotantes. Cuando dos elementos ocupan la misma zona de la pantalla, el navegador necesita decidir cuál se dibuja por encima.

La propiedad z-index controla el orden de apilamiento (stacking order) de los elementos posicionados. Cuanto mayor sea su valor, más arriba aparecerá el elemento respecto a los demás.

Por defecto, los elementos HTML se dibujan siguiendo el orden del documento: los que aparecen más tarde en el HTML suelen representarse encima cuando existe superposición. Este comportamiento puede modificarse mediante z-index.

La letra Z viene de la representación tridimensional. En diseño gráfico bidimensional se usan dos ejes: X para horizontal e Y para vertical. Si añadimos el tercer eje Z sería el orden de dibujado.

28.1 Cómo modificar z-index

El valor de z-index puede ser positivo, cero o negativo. Cuanto mayor sea el número más arriba se dibujará el elemento, pero sólo afecta sobre elementos posicionados con position (salvo el valor static).

HTML

<div class="caja roja"></div>
<div class="caja azul"></div>

CSS

.caja {
    position: relative;
    width: 120px;
    height: 120px;
}
.roja {
    background: crimson;
    z-index: 20;
}

.azul {
    background: royalblue;
    z-index: 10;
    left: 60px;
    top: -60px;
}

Las dos cajas se superponen parcialmente. Si no existe z-index, el orden dependerá del flujo del documento. En el momento en el que se añade un valor a la propiedad, se tendrá en cuenta para dibujar las cajas, en este caso aparecerá la roja encima de la azul, debido al valor numérico.

A la izquierda sin , a la derecha con

Si ambos elementos tuviesen el mismo valor, se mantendrá el orden de HTML, el elemento escrito más tarde se dibujará encima.

El uso más habitual de z-index es en ventanas modals, navbar, menús desplegables, … para asegurar que siempre están “por encima” del resto del documento.

28.2 Contexto de apilamiento

Un concepto importante es el stacking context o contexto de apilamiento, que es cuando un elemento crea su propio contexto, los z-index de sus hijos solo se comparan entre ellos.

En la documentación de MDN hay un ejemplo en el que se explica el apilamiento:

HTML

<section>
  <div id="div1">#1</div>
  <div id="div2">#2</div>
</section>
<div id="div3">#3</div>

CSS

/*...*/
#div1 {
  z-index: 5;
}

#div2 {
  z-index: -9;
}

#div3 {
  z-index: 0;
}
section {
  position: absolute;
  z-index: 2;
}

En este ejemplo hay dos contextos: uno dentro de “section” (entre “div1” y “div2”), y otro entre “section” y “div3”. Ambos se calculan por separado, y dentro de cada contexto tienen en cuenta sus propios valores.

¿Cuál crees que es el orden de dibujado del ejemplo anterior?

06d

  • Usa la propiedad z-index para ver el ejemplo puesto previamente. Comprueba el comportamiento al añadir y quitar la propiedad.
  • Arregla del ejercicio 6b el problema que había con el scroll y el navbar.
  • Comprueba si has acertado tu respuesta al contexto de apilamiento.

Los contextos de apilamiento pueden ser creados, por distintas propiedades que aparecen en la documentación de MDN, como por ejemplo:

  • Elementos posicionados con z-index.
  • opacity inferior a 1.
  • Algunas transformaciones (transform).
  • filter y otras propiedades gráficas.

28.3 Escala de apilamiento

No existe una numeración oficial, pero muchos proyectos utilizan una escala organizada para distintos elementos:

Elemento Valor orientativo
Contenido normal 1
Tarjetas 10
Cabecera fija 100
Menús 200
Modal 1000
Diálogos críticos 2000

Lo importante no es el número exacto, sino mantener una jerarquía coherente. También es importante dejar buena separación entre los distintos valores, por si más adelante queremos añadir en medio nuevos contextos.

¿Cuál es el valor mínimo y máximo? ¡Depende! Ya que el valor es un “integer”, y por tanto depende del sistema operativo y/o navegador.

29 La propiedad visibility

En desarrollo web existen varias formas de ocultar un elemento. La más conocida es display: none, pero no siempre es la opción adecuada. En muchas ocasiones necesitamos que un elemento desaparezca visualmente sin modificar la distribución del documento.

La propiedad visibility controla precisamente eso: permite hacer invisible un elemento manteniendo el espacio que ocupa dentro de la página. Es una propiedad sencilla, pero muy útil en animaciones, tablas, interfaces dinámicas y componentes interactivos.

Los valores más importantes son:

Valor Descripción
visible El elemento se muestra
hidden El elemento se oculta, pero conserva su espacio
collapse Comportamiento especial para tablas

El valor por defecto de todos los elementos es visible, por lo que no es necesario indicarlo ni se explicará. El uso más habitual es:

  • Ocultar temporalmente información manteniendo el diseño.
  • Mostrar y ocultar componentes sin desplazar otros elementos.
  • Interfaces con estados visibles/invisibles.
  • Tablas donde determinadas filas deben desaparecer visualmente.
  • Animaciones combinadas con opacity.

29.1 visibility: hidden

Este es el valor más interesante ya que en este caso el elemento desaparece visualmente, mantiene su tamaño y sigue ocupando el espacio en el documento.

HTML

<p>Primer párrafo</p>

<p class="oculto">Segundo párrafo</p>

<p>Tercer párrafo</p>

CSS

.oculto {
    visibility: hidden;
}

En este ejemplo, el espacio del segundo párrafo continúa existiendo. Anteriormente se ha explicado la diferencia con display:none.

Aunque el elemento siga “ocupando” espacio, no puede recibir interación del usuario mediante el ratón.

29.2 visibility: collapse

Existe un valor que está pensado principalmente para filas y columnas de tablas: collapse.

En la mayoría de navegadores modernos este valor se comporta de forma similar a hidden, aunque su implementación completa depende del tipo de elemento. En proyectos habituales rara vez se utiliza fuera de tablas.

06e

  • Usa la propiedad visibility para ocultar elementos y comprueba cómo su espacio permanece.
  • ¿Qué sucede al usar collapse en tablas?

29.3 Herencia de visibility

La propiedad visibility es heredable, lo que hace que todos los hijos de un elemento con valor hidden también estarán ocultos.

30 La propiedad opacity

En muchas interfaces modernas encontramos elementos que aparecen y desaparecen suavemente: ventanas modales, menús desplegables, imágenes al pasar el ratón o botones que cambian de intensidad. Todos estos efectos tienen un elemento en común: la transparencia.

La propiedad opacity controla el nivel de transparencia de un elemento completo, permitiendo que sea totalmente visible, parcialmente transparente o completamente invisible sin dejar de ocupar espacio en el documento, continúa existiendo en el documento y puede seguir recibiendo eventos del ratón.

A diferencia de visibility, opacity está pensada para crear efectos visuales y animaciones.

Para controlar el valor de opacity es un valor comprendido entre 0 (completamente transparente) y 1, completamente opaco (este es el valor por defecto). Por ejemplo:

Valor Resultado
0 Se vuelve invisible
0.25 Muy transparente
0.5 Semitransparente
0.75 Ligeramente transparente
1 Totalmente visible

Cuando modificamos la propiedad opacity afecta a todo el elemento, por lo que se vuelve transparente tanto fondo, como texto, imágenes, bordes e iconos.

opacity afecta a todo el elemento, también al fondo, como texto, imágenes, bordes e iconos.

30.1 Transiciones suaves

La opacidad puede animarse fácilmente mediante transition, ya que el cambio deja de ser instantáneo y pasa a realizarse de forma progresiva, teniendo en cuenta el tiempo indicado. Las transiciones se estudiarán en profundidad en una unidad posterior, pero sirva el siguiente ejemplo:

HTML

<img src="img/moon.jpg" alt="" class="imagen">

CSS

.imagen {
    opacity: 0.5;
    transition: opacity 0.3s;
}
.imagen:hover {
    opacity: 1;
}

Este ejemplo es muy habitual en galerías de imágenes.

06f

  • Duplica el ejercicio anterior y compara visibility con opacity.
  • Añade un listener en distintas cajas, ¿cuándo hace efecto?
  • Crea una galería de imágenes con opacity y una transición al pasar el ratón.

31 Ajustando imágenes y vídeos con object-fit

Uno de los problemas más habituales al trabajar con imágenes y vídeos es adaptar un archivo multimedia a un contenedor de tamaño fijo. Si simplemente modificamos width y height, es muy fácil que la imagen aparezca deformada o pierda sus proporciones.

La propiedad object-fit permite controlar cómo se ajusta una imagen o un vídeo dentro de su propio contenedor, manteniendo o modificando su relación de aspecto según nuestras necesidades.

Es una propiedad muy utilizada en tarjetas, galerías de imágenes, perfiles de usuario, tiendas online y aplicaciones móviles.

object-fit solo funciona sobre elementos multimedia como <img> y <video>. No debe confundirse con background-size, que se utiliza para imágenes de fondo.

Imaginemos la siguiente situación, donde ponemos una foto con una resolución de 1920x1080px:

HTML

<img src="paisaje.jpg" class="foto" alt="">

Forzar tamaño contenedor

.foto {
    width: 300px;
    height: 300px;
}

La imagen va a aparecer deformada, ya que el navegador ajusta el ancho y la altura de forma independiente. Con object-fit evita este problema indicando cómo debe adaptarse la imagen al contenedor. Los valores principales son:

Valor Descripción
contain Mantiene la proporción completa. Pueden quedar huecos.
cover Rellena recortando el exceso, rellena el contenedor completo.
fill Rellena deformando la imagen. No se recomienda su uso.
none Mantiene el tamaño original
scale-down Elige entre none y contain

Por lo tanto, para arreglar el ejemplo anterior podemos poner:

Forzar imagen con object-fit

.foto {
    width: 300px;
    height: 300px;
    object-fit: contain;
}

En la práctica, los valores más utilizados son cover y contain.

Ejemplos de valores: , , ,  y

06g

  • Crea una galería de imágenes y usa object-fit.
  • ¿Qué valor crees que es mejor?

32 La propiedad object-position

En el apartado anterior vimos que object-fit: cover permite rellenar completamente un contenedor recortando parte de la imagen. Sin embargo, surge una nueva pregunta: ¿qué parte de la imagen debe conservarse?

La propiedad object-position responde precisamente a esa cuestión. Permite elegir qué zona de una imagen o un vídeo permanecerá visible cuando el contenido sea recortado dentro de su contenedor.

Es una propiedad muy utilizada en avatares, fotografías de productos, retratos y cabeceras con imágenes panorámicas.

Para imágenes más pequeñas que el contenedor, permite elegir dónde colocar la imagen dentro del contenedor.

object-position puede aceptar dos valores:

  • Valor horizontal
  • Valor vertical

Los valores pueden ser: top, center, bottom, left, right, un porcentaje o una medida.

El valor por defecto es el centro de la imagen.

HTML

<img src="paisaje.jpg" class="a">

<img src="icono.jpg" class="b">

CSS

.a {
    width: 100px;
    height: 100px;
    object-fit: cover;
    object-position: top left;
}
.b {
    width: 400px;
    height: 400px;
    object-fit: none;
    object-position: 25% 50%;
}

En los ejemplos anteriores suponemos que:

  1. La image no entra en el espacio otorgado:
    • La imagen se va a recortar, pero la imagen se alinea la parte de arriba izquierda con el contenedor, por lo tanto se recortará por abajo y la derecha.
  2. La imagen es más pequeña que el contenedor:
    • La imagen se coloca sobre horizontalmente hacia la izquierda (25%) y verticalmente centrada.

06h

Usando el ejercicio anterior de base, prueba a hacer los contenedores más grandes/pequeños con imágenes más grandes/pequeñas y usa object-position con distintos valores.

Maquetación moderna

33 Introducción

Hasta ahora hemos aprendido a crear el aspecto visual de los elementos mediante colores, tipografías, bordes, márgenes y el modelo de cajas. Sin embargo, todavía nos falta cómo distribuir los elementos dentro de una página.

Durante muchos años esta fue una de las tareas más complejas de CSS. Los desarrolladores utilizaban tablas, elementos flotantes (float) e incluso posicionamiento absoluto para construir menús, columnas y páginas completas. Estas técnicas funcionaban, pero eran difíciles de mantener y nunca fueron diseñadas realmente para crear maquetaciones.

A partir de CSS3 aparecieron dos tecnologías que cambiaron por completo la forma de diseñar interfaces:

  • Flexbox, pensado para distribuir elementos en una única dimensión.
  • CSS Grid, diseñado para crear cuadrículas bidimensionales con filas y columnas simultáneamente.

34 Flexbox

Flexbox (Flexible Box Layout) es un sistema de maquetación que organiza elementos en una sola dirección, ya sea horizontal o vertical, que permite distribuir y alinear elementos de forma sencilla dentro de un contenedor.

Su principal ventaja es que el navegador reparte automáticamente el espacio disponible entre los elementos, evitando muchos de los problemas que existían con float.

Actualmente Flexbox es la herramienta más utilizada para crear:

  • Menús horizontales.
  • Barras de navegación.
  • Botones alineados.
  • Tarjetas.
  • Cabeceras.
  • Formularios.
  • Barras de herramientas.

Flexbox siempre trabaja con dos tipos de elementos:

  • Contenedor flex: el elemento padre que activa Flexbox.
  • Elementos flex: los hijos directos del contenedor.

34.1 Contenedor flex

El contenedor flex es el elemento padre que contendrá otros elementos que se alinearán de manera horizontal, o vertical, en el espacio disponible.

HTML

<div class="contenedor">
    <div class="caja">A</div>
    <div class="caja">B</div>
    <div class="caja">C</div>
</div>

CSS

.contenedor {
    display: flex;
}
.caja {
    width:50px;
    height: 50px;
    border: 1px solid black;
}

Por defecto los elementos se alinean en filas, uno seguido de otro, de izquierda a derecha. Si el contenedor es más grande que el espacio ocupado por los elementos hijos, por defecto sólo se ocupa el espacio más a la izquierda del mismo.

Si queremos modificar las propiedades por defecto tenemos las siguientes propiedades:

  • flex-direction: determina la dirección del eje (fila o columna).
  • flex-wrap: si no hay espacio para todos los hijos, salta de línea o columna.
  • flex-flow: es la combinación de las propiedades anteriores.
  • gap: para indicar la separación entre los elementos hijos.
  • row-gap: separación para filas.
  • column-gap: separación para columnas.

Estas propiedades afectan al conjunto de los elementos, nunca a un hijo individual.

34.1.1 flex-direction

Nos va a permitir elegir qué tipo de eje queremos utilizar (fila o columna) y el orden del mismo. Los posibles valores son:

  • row: Crea una fila.
  • row-reverse: Crea una fila pero inversa, empezando desde el lado derecho hacia la izquierda, poniendo al final del todo el primer elemento hijo, después el segundo, … Es importante destacar que solo cambia la representación visual, no el orden del documento HTML.
  • column: Crea una columna.
  • column-reverse: Crea columna invertida, como la fila pero en modo columna

34.1.2 flex-wrap

Por defecto, Flexbox intenta colocar todos los elementos en una única línea, y si no hay espacio, los elementos hijos pueden comprimirse. Con flex-wrap podemos modificar este comportamiento, dependiendo del valor indicado:

  • nowrap: usará siempre una única línea. Este es el comportamiento por defecto.
  • wrap: permite varias líneas si no hay espacio suficiente
  • wrap-reverse: permite varias líneas pero en orden inverso.
Ejemplo de  y  en una fila

34.1.3 flex-flow

Esta propiedad combina flex-direction y flex-wrap. Básicamente evita tener que escribir las dos propiedades anteriores y así sólo tener una:

CSS

.contenedor {
    flex-flow: row wrap;
}

Aunque es completamente válida, muchos equipos prefieren escribir ambas propiedades por separado para mejorar la legibilidad.

34.1.4 gap

Tradicionalmente era necesario utilizar márgenes para separar elementos. Flexbox introdujo una solución mucho más limpia, la propiedad gap. El espacio se aplica automáticamente entre los elementos, sin afectar a los bordes exteriores del contenedor.

CSS

.contenedor {
    gap: 30px;
}

Actualmente gap es la opción recomendada frente al uso de márgenes para separar componentes flexibles.

También es posible controlar cada dirección por separado.

  • row-gap: Controla la separación entre filas.
  • column-gap: Controla la separación entre columnas.

Estas propiedades son especialmente útiles cuando utilizamos flex-wrap.

07a

Crea un contenedor padre que sea flexible:

  • Añade varios elementos dentro.
  • Combina las propiedades vistas previamente.
  • Haz la ventana más pequeña para ver cómo se reordenan los elementos hijos.
  • Añade distinta separación entre ellos.

34.2 Elementos flexibles

Los elementos flexibles (contenidos dentro de un contenedor flexible) pueden crecer, reducir su tamaño, tener un tamaño inicial diferente, cambiar su orden visual o alinearse de forma distinta al resto de sus compañeros.

Las propiedades principales, con un resumen de su uso, son:

  • flex-grow: el elemento crece proporcionalmente.
  • flex-shrink: el elemento reduce su tamaño cuando falta espacio.
  • flex-basis: tamaño inicial del elemento.
  • order: orden visual.
  • align-self: alineación individual.

Estas propiedades se aplican sobre los hijos del contenedor, nunca sobre el propio contenedor.

34.2.1 flex-grow

La propiedad flex-grow indica cuánto puede crecer un elemento cuando existe espacio libre dentro del contenedor. Por defecto el valor es 0, por lo tanto los elementos no crecen. Esta propiedad no representa píxeles, sino proporciones.

Cambiar tamaño

.c1 { flex-grow: 1; }

El elemento con esta propiedad crecerá ocupando el espacio sobrante del contenedor padre. Si todos los elementos hijos tienen el mismo valor, todos crecerán por igual y se repartirán el espacio equitativamente. De esta manera podemos crear columnas del mismo tamaño.

En cambio, si tenemos tres hijos y tienen los siguientes valores:

Cambiar tamaño

.c1 { flex-grow: 1; }
.c2 { flex-grow: 2; }
.c3 { flex-grow: 1; }

De esta manera los tres hijos se dividen el espacio dando lugar a que “c1” y “c3” tendrán el mismo tamaño y “c2” será el doble de tamaño de los dos anteriores.

34.2.2 flex-shrink

Mientras flex-grow controla el crecimiento, flex-shrink controla cuánto puede reducirse un elemento cuando falta espacio. El valor por defecto es 1, lo que significa que el elemento puede encogerse.

Impide que se haga más pequeño

.c4 {
    width: 150px;
    flex-shrink: 0;
}

De esta manera, este elemento no se va a hacer más pequeño, siendo útil para logotipos e iconos.

34.2.3 flex-basis

flex-basis define el tamaño inicial de un elemento antes de repartir el espacio. Podemos imaginarlo como el punto de partida desde el que Flexbox calcula el reparto.

Tamaño inicial

.c5 {
    flex-basis: 200px;
}

En muchas ocasiones sustituye al uso de width, ya que width define la anchura del elemento, mientras que flex-basis define el tamaño inicial dentro del algoritmo de Flexbox.

Cuando trabajamos con Flexbox suele recomendarse utilizar flex-basis en lugar de width, ya que está pensado específicamente para este sistema de distribución.

34.2.4 Propiedad abreviada flex

Para no escribir las tres propiedades anteriores, podemos utilizar la propiedad flex. Esta propiedad sigue el orden grow shrink basis, por lo tanto, las siguientes instrucciones son iguales:

Propiedades separadas

.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 200px;
}

Una única propiedad

.item {
    flex: 1 1 200px;
}

34.2.5 order

order modifica el orden visual de un elemento.

HTML

<div class="contenedor">
    <div class="a">A</div>
    <div class="b">B</div>
    <div class="c">C</div>
</div>

CSS

.a { order: 2; }
.b { order: 3; }
.c { order: 1; }

En este caso el resultado visual será C A B. Sólo cambia la representación visual, mientras que la jerarquía HTML se mantiene.

34.2.6 align-self

Hasta ahora todos los elementos compartían la misma alineación vertical. Con align-self vamos a poder hacer que un único elemento tenga una alineación diferente.

CSS

.destacado {
    align-self: center;
}

Este elemento se alinea centrado verticalmente, mientras que el resto de elementos mantiene la alineación del contenedor.

07b

Partiendo del ejercicio anterior utiliza las propiedades para los elementos dentro de un contenedor flex.

35 Alineaciones

Uno de los principales motivos por los que Flexbox sustituyó a float fue la facilidad con la que permite alinear elementos horizontal y verticalmente. Antes de Flexbox, centrar un elemento en una página requería combinaciones de márgenes, posicionamiento absoluto o incluso tablas. Con Flexbox, la alineación se realiza mediante tres propiedades muy claras:

  • justify-content: Alineación sobre el eje principal.
  • align-items: Alineación sobre el eje transversal.
  • align-content: Alineación de varias filas o columnas cuando existe flex-wrap.

Para entender la diferencia entre eje principal y transversal sirva la siguiente tabla:

flex-direction: row flex-direction: column
Eje principal Horizontal Vertical
Eje transversal Vertical Horizontal

Antes de utilizar estas propiedades, es importante identificar siempre cuál es el eje principal del contenedor.

35.1 justify-content

La propiedad justify-content distribuye los elementos a lo largo del eje principal: espacio horizontal cuando trabajamos con filas. Los valores principales son:

  • flex-start: Es el valor por defecto. Los elementos se agrupan al inicio del contenedor.
  • flex-end: Los elementos se agrupan al final del contenedor.
  • center: Los elementos se agrupan en el centro del contenedor.
  • space-between: Reparte el espacio entre los elementos. Los extremos quedan pegados a los bordes del contenedor.
  • space-around: Cada elemento recibe espacio a ambos lados. Los espacios exteriores son aproximadamente la mitad de los interiores.
  • space-evenly: Distribuye el espacio de forma completamente uniforme. Todos los espacios, incluidos los de los extremos, son iguales.

Ejemplo de justify-content

.contenedor { justify-content: space-between; }
Ejemplo de  con distintos valores

07c

Crea contenedores con las distintas variaciones que permite justify-content para alinear sus elementos hijos.

35.2 align-items

La propiedad align-items controla la alineación sobre el eje transversal. Si trabajamos en una fila, significa la alineación vertical. Esta propiedad tiene varios valores, por lo que conviene mirar la documentación, pero los principales son:

  • stretch: Es el valor por defecto. Los elementos se estiran para ocupar toda la altura del contenedor, siempre que no tengan una altura definida. Es muy útil para crear columnas de igual altura.
  • center: Los elementos ocupan su altura definida y se alinean respecto a su eje vertical.
  • flex-start: Los elementos se alinean verticalmente en la parte alta del contenedor.
  • flex-end: Los elementos se alinean verticalmente en la parte baja del contenedor.
  • baseline: Se alinean respecto a la línea base del texto.

En las explicaciones se ha tomado como referencia el uso de filas.

Ejemplo de align-items

.contenedor {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}
Distintos ejemplos de . Versionado de MDN

07d

Comprueba los valores explicados de align-items y haz ejemplos propios.

35.3 align-content

La propiedad align-content suele confundirse con align-items , pero su función es diferente. Solo actúa cuando existe flex-wrap y hay varias filas o columnas. Con este parámetro se alinean las filas completas, no los elementos individuales (que es lo que sucedía en el parámetro anterior). Los valores son similares a los anteriores:

  • center: Las filas se alinean en el centro dek eje vertical del elemento contenedor.
  • start: Las filas se alinean verticalmente en la parte alta del contenedor.
  • end: Las filas se alinean verticalmente en la parte baja del contenedor.
  • space-between, space-around, space-evenly: Funciona igual que lo explicado en justify-content, pero a nivel de filas.

Si sólo hay una fila, align-content no produce ningún efecto.

Ejemplo de align-content

.contenedor {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
}

La propiedad align-content actúa sobre la fila/columna completa.

Distintos ejemplos de . Versionado de MDN

07e

Comprueba los valores explicados de align-items y haz ejemplos propios.

36 CSS Grid

Hasta ahora hemos utilizado Flexbox para distribuir elementos en una única dirección. Sin embargo, muchas interfaces necesitan controlar filas y columnas al mismo tiempo: galerías de imágenes, paneles de administración, calendarios o la distribución completa de una página web.

CSS Grid Layout, conocido simplemente como Grid, es un sistema de maquetación bidimensional diseñado específicamente para crear este tipo de cuadrículas. Mientras Flexbox organiza elementos en una fila o en una columna, Grid permite definir una estructura completa formada por filas y columnas simultáneamente. Actualmente Grid es la herramienta recomendada para construir el layout principal de una aplicación web.

Podemos definir que existen dos tipos de cuadrículas/grid:

  • Grid explícito: se define manualmente el número y el tamaño de las filas y/o columnas. El desarrollador tiene un diseño fijo definido explícitamente. Normalmente se usa para la definición general de la web, o sistema de columnas de lectura…
  • Grid implícito: está formado por las filas y/o columnas que el navegador crea automáticamente cuando hacen falta. Normalmente en galería de fotos, o en diseños de portada de páginas web con un número de elementos fijos pero de tamaños distintos… Ocurre cuando hay más elementos de los que se ha especificado en la cuadrícula inicial.

36.1 Contenedor Grid

Para activar Grid basta con convertir un elemento en un contenedor de cuadrícula, y a partir de ese momento, todos sus hijos directos pasan a ser elementos de la cuadrícula.

HTML

<div class="contenedor">
    <div class="caja">A</div>
    <div class="caja">B</div>
    <div class="caja">C</div>
</div>

CSS

.contenedor {
    display: grid;
}
.caja {
    width:50px;
    height: 50px;
    border: 1px solid black;
}

Aunque todavía no hemos definido filas ni columnas, el elemento ya es un contenedor Grid. Las propiedades que veremos en este apartado siempre se aplican sobre el contenedor. Una cuadrícula/grid está formada por dos tipos de pistas (tracks):

  • Columnas: grid-template-columns
  • Filas: grid-template-rows

Hay una característica especial llamada grid-template-areas que veremos más adelante.

36.1.1 grid-template-columns

Es la propiedad más importante de Grid. y sirve para generar columnas:

CSS

.contenedor {
    display: grid;
    grid-template-columns: 150px 150px 150px;
}

Cada valor define el ancho de una columna, por lo que en el ejemplo anterior se crean tres columnas de 150px cada una.

36.1.1.1 La unidad fr

La unidad fr (fraction) representa una fracción del espacio disponible.

CSS

.contenedor {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
}

Las tres columnas dividen el espacio en distintas proporciones, en este caso la columna central ocupa el doble que los laterales. El funcionamiento es muy similar a flex-grow. Esta unidad se puede utilizar también con filas.

36.1.2 grid-template-rows

Las filas se definen de forma equivalente.

CSS

.contenedor {
    display: grid;
    grid-template-rows: 80px 200px 60px;
}

En este caso se ha creado un grid que consta de tres filas con distintos tamaños cada una.

36.2 gap en Grid

Al igual que Flexbox, Grid utiliza gap para separar elementos, que sustituye al uso de márgenes y genera una separación uniforme entre filas y columnas.

CSS

.contenedor {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    gap: 20px;
}

También existen row-gap y column-gap.

36.3 La función repeat()

Cuando existen muchas columnas iguales, escribirlas manualmente resulta repetitivo, por lo que podemos usar la función repeat(). Por ejemplo, en lugar de escribir 1fr 1fr 1fr 1fr para generar cuatro columnas, podemos usar lo siguiente:

CSS

.contenedor {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}

El resultado es exactamente el mismo y el código es más legible. repeat() es una de las funciones más utilizadas en CSS Grid.

36.4 Grids adaptables

Podemos crear grids responsive utilizando minmax() y auto-fit.

CSS

.contenedor {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 20px;
}

A continuación la explicación de la función:

  • repeat: la función trata de repetir el sistema de columnas.
    • auto-fit: Trata de rellenar el espacio con columnas, pero si está vacía, la columna colapsa/desaparece.
    • minmax: es una función que recibe dos parámetros: mínimo y máximo, que genera un rango igual o superior al mínimo, e inferior o igual al máximo.

Por lo tanto, se trata de crear un sistema de columnas que al menos cada una mida 220px, y si existe más espacio se crearán nuevas.

Este patrón es uno de los más utilizados en desarrollo web moderno.

07f

Crea un contenedor padre que sea una cuadrícula con grid y usa las propiedades vistas previamente y usa el sistema de repetición.

36.5 Otros parámetros

Existen otros parámetros para poder controlar y hacer que las grids se ajusten a nuestras necesidades. A continuación algunos del listado que aparece en la documentación.

  • grid-auto-flow: controla cómo funciona el algoritmo de colocación automática, especificando exactamente cómo se distribuyen en la cuadrícula los elementos colocados automáticamente (filas o columnas).
  • grid-auto-columns: especifica el tamaño de las columnas del grid.
  • grid-auto-rows: especifica el tamaño de las filas del grid.
  • grid-column-start: especifica la posición inicial de un elemento dentro de la columna de la cuadrícula.
  • grid-column-end: especifica la posición final de un elemento dentro de la columna de la cuadrícula.
  • grid-row-start: especifica la posición inicial de un elemento dentro de la fila de la cuadrícula.
  • grid-row-end: especifica la posición final de un elemento dentro de la fila de la cuadrícula.

36.6 Grid Areas

Hasta ahora hemos construido rejillas definiendo el número de filas y columnas, dejando que los elementos se coloquen automáticamente. Sin embargo, cuando diseñamos la estructura completa de una página web, suele ser más cómodo dar un nombre a cada zona del layout en lugar de trabajar con números de fila y columna.

Grid Areas permite asignar nombres como “header”, “menu”, “main” o “footer a las distintas regiones de una rejilla, consiguiendo un código mucho más legible y fácil de mantener. Mediante la propiedad grid-template-areas podemos hacer esta separación que puede resultar más visual.

Imaginemos típica página web con distintos apartados:

HTML

<div id="page">
  <div id="logo">logo</div>
  <header>Header</header>
  <nav>Navigation</nav>
  <main>Main area</main>
  <div id="ads">ads</div>
  <footer>Footer</footer>
</div>

CSS

#page {
  display: grid;
  width: 100%;
  height: 100vh;
  grid-template-areas:
    "logo head head"
    "nav  main ads"
    ".    foot .";
  grid-template-rows: 50px 1fr 30px;
  grid-template-columns: 150px 1fr 150px;
}
#page > header {
  grid-area: head;
}
#page > nav {
  grid-area: nav;
}
/* resto áreas */

En grid-template-areas se puede apreciar cómo está separado cada elemento de manera “visual”, generando tres filas y tres columnas, y cada “celda” tiene un nombre. Cuando un nombre se repite en la misma fila, se expande horizontalmente, y lo mismo ocurre con las columnas verticalmente. Las áreas marcadas con punto (.) son celdas vacías. El resultado sería el siguiente:

Ejemplo básico de

A la hora de poner nombres en las “celdas” las áreas deben formar rectángulos, no puede haber formas “extrañas”:

07g

Crea plantillas de webs modernas con grid-template-areas

37 Grid y Flexbox juntos

Grid y Flexbox no son tecnologías competidoras, sino complementarias. Lo habitual es hacer uso ellas de manera conjunta, ya que cada una aporta ciertas características que hace que sea más simple de usar que la otra. Además, ambas forman parte del estándar de CSS, son compatibles con todos los navegadores modernos y pueden utilizarse conjuntamente dentro de un mismo proyecto.

En la siguiente tabla se puede ver un resumen completo de distintas características de ambas tecnologías:

Flexbox Grid
Dimensiones 1 2
Filas
Columnas
Control simultáneo de filas y columnas No
Reparto automático del espacio Excelente Excelente
Layout completo Limitado Ideal
Componentes pequeños Ideal Posible
Galerías Aceptable Excelente

Por ejemplo, un uso combinado de ambas tecnologías podría ser:

  • Plantilla general: creada con Grid, con distintos apartados:
    • Header: Uso de Flexbox para colocar logo, secciones, caja de búsqueda…
    • Sidebar
    • Main: Depende del contenido, se puede usar Flexbox o Grid.
    • Footer: Flexbox para añadir secciones.

Diseño responsive

38 Introducción

Cuando Internet comenzó a popularizarse durante los años noventa, la mayoría de los usuarios navegaba desde un ordenador de sobremesa, y la tecnología de resolución de monitores era de tamaño similar. Las páginas web se diseñaban pensando en una única resolución, por lo que era habitual crear sitios con un ancho fijo de 800 o 1024 píxeles.

Con el paso del tiempo aparecieron portátiles, pantallas panorámicas, tablets, teléfonos inteligentes e incluso televisores conectados a Internet. De repente, una misma página debía verse correctamente en dispositivos con pantallas de apenas 320 píxeles y en monitores de más de 2.500 píxeles de ancho. Esta diversidad hizo necesario un nuevo enfoque de diseño: el Responsive Web Design.

En la actualidad, el diseño responsive es un requisito imprescindible en cualquier desarrollo web. No consiste únicamente en hacer que una página “quepa” en un móvil, sino en adaptar la distribución, el tamaño de los elementos y la experiencia de usuario a cada dispositivo.

Un diseño responsive no consiste sólo que en la página quepa en un móvil, sino en adaptar la distribución, el tamaño de los elementos y la experiencia de usuario a cada dispositivo.

38.1 Web adaptativa frente a web responsive

Aunque a menudo se utilizan como sinónimos, existen diferencias entre ambos conceptos.

Diseño adaptativo (Adaptive) Diseño responsive
Varias versiones del sitio Una única versión
Anchuras predeterminadas Diseño fluido
Cambios en puntos concretos Adaptación continua
Mayor mantenimiento Más flexible

El diseño adaptativo crea varias versiones del mismo sitio (por ejemplo, una para móvil y otra para escritorio). El diseño responsive utiliza una única estructura que se adapta mediante CSS.

Hoy en día, el enfoque recomendado es el responsive.

39 Viewport

Cuando una página web se visualiza en un ordenador, el navegador dispone normalmente de una pantalla relativamente grande. Sin embargo, cuando se visita esa misma página desde un teléfono móvil, el área disponible es mucho menor.

Cuando aparecieron los primeros smartphones, muchos sitios web no estaban preparados para pantallas pequeñas. Para intentar mostrar páginas diseñadas para ordenadores, los navegadores móviles utilizaban un viewport virtual considerablemente más ancho que la pantalla física. El resultado era una página diminuta que el usuario tenía que ampliar mediante zoom.

Para que el navegador pueda interpretar correctamente el tamaño de la página en dispositivos móviles existe el concepto de viewport, que es el área visible de una página web dentro de la ventana del navegador. Es fundamental entender qué es antes de empezar a trabajar con Media Queries y diseño responsive.

39.1 El viewport no es necesariamente igual a la resolución de pantalla

Es importante no confundir estos los conceptos de viewport y resolución de pantalla. Hoy en día los dispositivos móviles pueden tener una resolución física igual que la de una pantalla de ordenador (1920 x 1080 píxeles, o incluso más) pero eso no significa que una página web disponga de un viewport de 1080px de ancho.

Los dispositivos móviles utilizan una densidad de píxeles (ppi o pixels per inch) diferente a la de las pantallas tradicionales y los navegadores utilizan un viewport lógico para representar las páginas. Por este motivo, cuando hablamos de CSS normalmente trabajamos con píxeles CSS, no con los píxeles físicos del panel.

39.2 La etiqueta meta viewport

Para indicar al navegador móvil cómo debe utilizar el viewport se utiliza una etiqueta <meta> dentro de <head>. La configuración habitual es:

HTML con cabecera viewport

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Mi página</title>
    </head>
    <body>
        <h1>Mi página responsive</h1>
    </body>
</html>

Esta etiqueta es prácticamente obligatoria en cualquier página web moderna que pretenda ser responsive. A continuación una explicación de cada atributo de la etiqueta, aunque conviene mirar la documentación para ver todos los posibles atributos:

  • <meta … >: es una etiqueta HTML que representa metadatos que no pueden ser representados por otras etiquetas. Dentro de ella acepta distintos atributos:
    • name="viewport": el nombre de los metadatos, en este caso indicando que hacemos referencia al viewport.
    • content="…": el contenido de los metadatos. Es una lista de valores separado por comas que contiene parejas de clave-valor, del estilo key=value. En este caso están definidos las siguientes claves:
      • width=device-width: indica al navegador que el ancho del viewport debe coincidir con el ancho disponible del dispositivo en píxeles CSS.
      • initial-scale=1.0: indica el nivel de zoom inicial de la página. Puede ser un valor entre 0 y 100 donde 1 es el 100%, es decir, no hay zoom adicional.

La etiqueta meta viewport debe ir en la cabecera <head>.

08a

Crea una página HTML con la etiqueta meta viewport y comprueba con tu móvil cómo se ve. Elimina la etiqueta y vuelve a comprobarlo.

39.3 Unidades relacionadas con el viewport

CSS dispone de unidades relacionadas con el viewport tal como se ha visto previamente. Un ejemplo sería:

HTML con cabecera viewport

.content {
    height: 100vh;
}

Esta regla indica que el elemento tendrá una altura equivalente al 100% de la altura del viewport.

39.4 Viewport y orientación del dispositivo

Un teléfono puede utilizarse en dos orientaciones, en vertical y horizontal. El ancho y la altura del viewport cambian al girar el dispositivo. Esto permite que las páginas responsive adapten automáticamente su distribución.

39.5 No bloquear el zoom del usuario

Dentro de la configuración de la etiqueta viewport existe la posibilidad de bloquear el zoom del usuario:

HTML con cabecera viewport

<meta name="viewport"
      content="width=device-width, initial-scale=1.0, 
               maximum-scale=1.0, user-scalable=no"
>

No es recomendable utilizar user-scalable=no para una página normal. Impedir que el usuario amplíe el contenido puede perjudicar la accesibilidad, especialmente a personas que necesitan aumentar el tamaño de la página para poder leerla. En iPhone, desde iOS 10 Apple ignora esa configuración.

No es recomendable bloquear el zoom del usuario.

40 Media Queries

Una página responsive no cambia automáticamente su diseño por sí sola. El navegador necesita un mecanismo que le permita aplicar unos estilos u otros según las características del dispositivo. Ese mecanismo recibe el nombre de Media Queries.

Las Media Queries son una característica de CSS que permite escribir reglas condicionales. Gracias a ellas podemos modificar el número de columnas, el tamaño de la tipografía, ocultar elementos o reorganizar completamente un layout cuando cambia el tamaño del viewport. Son uno de los pilares del Responsive Web Design propuesto por Ethan Marcotte en 2010.

40.1 Configuración de Media Queries

Las Media Queries se evalúan antes de aplicar un bloque de estilos, y su sintaxis es la siguiente:

Sintaxis

@media (condición) {
  /* Reglas CSS */
}

Ejemplo

@media(max-width:768px){
/*pantallas pequeñas*/
  body {
    background: red;
  }
}

Ejemplo

@media(min-width:768px){
/*pantallas grandes*/
  body {
    background: gray;
  }
}

La sintaxis más habitual para la condición es utilizar:

  • min-width: para aplicar cuando como mínimo es el tamaño indicado.
  • max-width: para aplicar las reglas cuando como máximo es el tamaño indicado.

Las reglas que hay dentro de la Media Query solo se aplican cuando la condición es verdadera.

Los ejemplos anteriores pueden estar en el mismo fichero de configuración, y podemos utilizar tantas como necesitemos para la misma aplicación web.

40.2 Combinar condiciones

Se pueden combinar distintas condiciones mediante and:

Combinar Media Queries

@media (min-width: 768px) and (max-width: 1199px) {
    body {
        background: beige;
    }
}

Esta regla solo se aplicará entre 768px y 1199px. Es útil cuando queremos crear estilos específicos para tablets.

40.3 Según orientación del dispositivo

Las Media Queries también pueden detectar la orientación del dispositivo, teniendo en cuenta esi está en modo portrait (vertical) o landscape (horizontal).

Orientación del dispositivo

@media (orientation: landscape) {
    body {
        background: beige;
    }
}

Esto permite adaptar algunos componentes cuando el usuario gira el dispositivo.

40.4 Otras características disponibles

Aunque el ancho es la condición más utilizada, existen muchas otras.

Característica Ejemplo
Anchura (como mínimo) min-width
Anchura (como máximo) max-width
Altura (como máximo) max-height
Orientación orientation
Impresión print
Pantalla screen

Por ejemplo, para imprimir también podemos modificar la web:

Media Query al imprimir

@media print {
    nav {
        display: none;
    }
}

El navegador aplicará estos estilos únicamente al generar la impresión o un PDF, y así no imprimirá la barra de navegación.

40.5 Orden de las reglas

El orden del CSS sigue siendo importante al hacer uso de Media Queries. Si ambas reglas tienen la misma especificidad, la que aparece más abajo y cuya condición se cumple será la que prevalezca.

Orden de las reglas

h1 { font-size: 16px; }

@media (min-width: 768px) {
    h1 {
        font-size: 32px;
    }
}

Este comportamiento sigue las reglas normales de la cascada.

40.6 Ejemplos

A continuación varios ejemplos de media queries que modifican los estilos según lo visto anteriormente.

En este ejemplo el comportamiento es el siguiente:

  • En móvil → 1.5rem.
  • En tablet y ordenador → 3rem.

Ejemplo básico

h1 { font-size: 1.5rem; }

@media (min-width: 768px) {
  h1 {
    font-size: 3rem;
  }
}

Los estilos base corresponden al dispositivo más pequeño.

En el siguiente ejemplo se modifica cómo se visualiza un Grid, dependiendo del tamaño de la pantalla

Ejemplo con Grid

#grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}
@media (min-width: 768px) {
  #grid {
      grid-template-columns: repeat(3, 1fr);
      gap: 3rem;
    }
}

Para dispositivos con pantalla grande habrá tres columnas, mientras que en pantallas pequeñas sólo se verá una.

08b

Crea una página HTML que tenga distintos media queries para distintos tamaños de pantalla. Comprueba que funciona haciendo zoom en el navegador del escritorio y con el móvil.

41 Breakpoints y puntos de ruptura

En el apartado anterior aprendimos que las Media Queries permiten aplicar estilos cuando se cumple una determinada condición. La pregunta que nos puede surgir es: ¿en qué anchuras debemos cambiar el diseño?:

Los breakpoints o puntos de ruptura son precisamente los valores del viewport a partir de los cuales una interfaz modifica su distribución. Gracias a ellos una misma página puede reorganizarse para ofrecer una experiencia adecuada en teléfonos móviles, tablets, ordenadores portátiles o monitores de escritorio.

Es importante comprender que un breakpoint no representa un dispositivo concreto, sino un momento en el que decidimos aplicar una Media Query diferente para ajustar el diseño a ese tamaño.

Hemos visto previamente distintos ejemplos como el siguiente:

Media Query

@media (min-width: 768px) {
  /* CSS */
}

En este caso, 768 px es el breakpoint, que quiere decir “cuando el viewport alcance 768px o más, aplica ciertas reglas”.

41.1 Breakpoints habituales

Aunque cada proyecto puede utilizar valores diferentes, y podemos elegir los que más nos convengan, existen algunos puntos de ruptura muy extendidos:

Breakpoints. Fuente: devsheets

/* Standard Breakpoints */
/* Mobile First Approach */
@media (min-width: 320px)  { /* Mobile Small */ }
@media (min-width: 480px)  { /* Mobile Large */ }
@media (min-width: 576px)  { /* Mobile XL */ }
@media (min-width: 768px)  { /* Tablet */ }
@media (min-width: 1024px) { /* Desktop */ }
@media (min-width: 1200px) { /* Large Desktop */ }
@media (min-width: 1440px) { /* Extra Large */ }

/* Desktop First Approach */
@media (max-width: 1439px) { /* Below XL */ }
@media (max-width: 1199px) { /* Below Large */ }
@media (max-width: 1023px) { /* Below Desktop */ }
@media (max-width: 767px)  { /* Below Tablet */ }
@media (max-width: 479px)  { /* Below Mobile Large */ }

Estos valores son orientativos y no forman parte del estándar de CSS. Cada proyecto debe elegir los breakpoints que mejor se adapten a su diseño.

Los frameworks CSS también hacen uso de estos sistemas, y aunque todos ellos suelen hacer uso de aliases, los tamaños son parecidos entre sí. Por ejemplo, existe cierta diferencia entre Bootstrap y TailwindCSS:

Bootstrap Tailwindcss
sm min-width: 576px min-width: 640px
md min-width: 768px min-width: 768px
lg min-width: 992px min-width: 1024px
xl min-width: 1200px min-width: 1280px
xxl / 2xl min-width: 1400px min-width: 1536px

41.1.1 Conocer el tamaño del viewport con JavaScript

Durante el desarrollo de una página responsive es muy útil saber cuál es el tamaño real del viewport sobre el que está trabajando el navegador. Aunque las Media Queries aplican automáticamente los estilos adecuados, conocer estas dimensiones nos ayuda a comprobar si estamos entrando en un determinado breakpoint o a depurar el comportamiento de nuestro diseño.

JavaScript permite obtener el ancho y la altura del viewport mediante las propiedades window.innerWidth y window.innerHeight. Estas propiedades devuelven el tamaño del área visible del navegador en píxeles CSS, es decir, las mismas unidades que utiliza CSS para evaluar las Media Queries.

Conocer tamaño de pantalla

console.log("Ancho:", window.innerWidth);
console.log("Alto:", window.innerHeight);

Al ejecutar este código desde la consola del navegador veremos dos números que cambiarán al redimensionar la ventana. Si, por ejemplo, reducimos la anchura de la ventana por debajo de 768px, el valor de window.innerWidth también disminuirá y las Media Queries correspondientes comenzarán a aplicarse.

Es importante entender que el viewport también cambia cuando hacemos zoom en un navegador de escritorio. Al aumentar el zoom al 125% o al 150%, el navegador muestra una porción menor de la página, por lo que el viewport efectivo disminuye y por tanto los valores devueltos serán más pequeños.

Del mismo modo, al reducir el zoom, el viewport aumenta y el valor obtenido será mayor. Por esta razón, las Media Queries y JavaScript siempre trabajan con el viewport efectivo y no con la resolución física del monitor.

Una forma muy cómoda de observar estos cambios consiste en escuchar el evento resize, que se dispara cada vez que cambia el tamaño del viewport (ya sea al redimensionar la ventana o al modificar el zoom en muchos navegadores).

Conocer tamaño de pantalla

window.addEventListener("resize", () => {
    console.log(
        `Viewport: ${window.innerWidth} × ${window.innerHeight}`
    );
});

Este pequeño script resulta muy útil durante el desarrollo, ya que permite visualizar en tiempo real las dimensiones sobre las que está trabajando nuestro diseño responsive.

Es importante no dejar este código en producción para evitar posibles problemas de rendimiento.

41.2 Diseño para contenido, no para dispositivos

Un error muy frecuente es pensar en crear un breakpoint para iPhone o un dispositivo concreto. En realidad, el diseño responsive moderno evita trabajar para dispositivos específicos.

El diseño responsive moderno evita trabajar para dispositivos específicos.

La estrategia correcta es observar cuándo el contenido deja de verse correctamente. Por ejemplo, si un elemento comienza a verse demasiado estrecha a los 720px, ese puede ser el breakpoint adecuado, aunque no coincida con ningún dispositivo concreto. El contenido debe ser quien determine el cambio de diseño.

41.3 Breakpoints y herramientas de desarrollo

Los navegadores incorporan un modo de diseño responsive dentro de las herramientas de desarrollo. Desde él podemos:

  • Simular teléfonos y tablets.
  • Introducir un ancho personalizado.
  • Ver el viewport en tiempo real.
  • Comprobar cuándo se activan las Media Queries.

Es una herramienta imprescindible para desarrollar interfaces responsive sin necesidad de disponer físicamente de varios dispositivos.

Los navegadores incorporan un listado de simulación de dispositivos pre-configurados, y aparte, podemos añadir un dispositivo propio con los datos que nos interesen.

08c

Modifica el ejercicio anterior y añade la función javascript para conocer en tiempo real el viewport.

42 Diseño Mobile First

Durante muchos años los sitios web se diseñaban pensando primero en los ordenadores. Una vez terminada la versión de escritorio, los desarrolladores intentaban adaptarla a móviles mediante numerosas Media Queries y excepciones. Este enfoque funcionaba, pero producía hojas de estilo difíciles de mantener y páginas poco optimizadas para dispositivos móviles.

A partir de 2010 el número de usuarios que navegaban desde teléfonos móviles comenzó a crecer rápidamente. Muchas páginas seguían estando diseñadas para pantallas grandes y ofrecían una mala experiencia en dispositivos pequeños.

El diseñador Luke Wroblewski popularizó la filosofía Mobile First proponiendo una idea muy sencilla: comenzar por el dispositivo con más limitaciones (de tamaño) y añadir funcionalidades a medida que aumenta el espacio disponible. Este enfoque obliga a priorizar el contenido realmente importante desde el principio. Hoy en día es el enfoque recomendado por la mayoría de frameworks y guías de desarrollo web.

La secuencia de trabajo es:

  1. Diseñar para móvil.
  2. Adaptar para tablet.
  3. Mejorar para escritorio.
  4. Aprovechar el espacio en monitores grandes.

En CSS esto significa que los estilos normales son los de móvil, y las Media Queries utilizan generalmente min-width.

42.1 Estructura típica de un proyecto

En Mobile First los estilos se escriben de menor a mayor tamaño.

Estructura mobile first

/* Estilos base (móvil) */
body { margin: 0; }
/* ... */

@media (min-width: 768px) {
  /* Adaptaciones para Tablet */
}

@media (min-width: 1200px) {
  /* Adaptaciones para Escritorio */
}

Observa que las Media Queries añaden estilos, no sustituyen toda la hoja de estilos.

42.2 Ventajas del enfoque Mobile First

A la hora de diseñar nuestra aplicación web, el empezar con el enfoque mobile first nos ayuda a mejorar el rendimiento, ya que los dispositivos móviles suelen tener menos potencia y conexiones más lentas. Diseñar primero para ellos favorece páginas más ligeras y rápidas.

Por otro lado, el espacio reducido obliga a preguntarse qué información es realmente importante, y cuál debería ser su sitio en la web, así como cuáles son secundarios. Esto ayuda a producir interfaces más limpios.

Por último, en lugar de eliminar estilos de escritorio, únicamente vamos añadiendo mejoras conforme aumenta el ancho disponible.

43 Diseño Desktop First

El Desktop First comienza diseñando la versión de escritorio y posteriormente adapta la interfaz a pantallas cada vez más pequeñas utilizando Media Queries con max-width. Aunque hoy en día no suele ser la opción recomendada para proyectos nuevos, es muy importante conocerla porque todavía está presente en numerosos sitios web y proyectos heredados.

La secuencia de trabajo es:

  1. Diseñar para ordenador.
  2. Adaptar para portátil.
  3. Adaptar para tablet.
  4. Adaptar para móvil.

Durante los años 2000 la inmensa mayoría de los usuarios navegaba desde ordenadores de sobremesa. Era lógico que los diseñadores comenzaran creando páginas de 960 píxeles de ancho y posteriormente añadieran algunas adaptaciones para dispositivos pequeños cuando empezaron a aparecer los smartphones.

Un ejemplo muy típico era el siguiente:

Ejemplo desktop first

.wrapper {
    width: 960px;
    margin: 0 auto;
}

Cuando llegaron los teléfonos móviles, fue necesario añadir Media Queries para modificar esa estructura.

43.1 Estructura típica de Desktop First

Los estilos principales pertenecen al escritorio.

Estructura desktop first

/* Estilos base (escritorio) */
body { font-size: 18px; }

/* adaptaciones */
@media (max-width: 992px) { }
@media (max-width: 768px) { }
@media (max-width: 576px) { }

Observa que ahora las condiciones utilizan anchuras máximas.

43.2 Ventajas e inconvenientes de Desktop First

Este enfoque todavía puede resultar útil en algunos casos.

  • Aplicaciones de uso interno: Si una aplicación solo va a utilizarse en ordenadores de oficina, puede tener sentido diseñar primero para escritorio.
  • Proyectos heredados: Muchos sitios desarrollados hace años ya siguen esta filosofía. En estos casos suele ser más práctico mantener la misma estructura que reescribir completamente el CSS.

Pero también presenta varios inconvenientes cuando el objetivo es crear una aplicación pública moderna:

  • Más reglas correctivas: Es habitual tener que “deshacer” estilos del escritorio.
  • Más código: debido al punto anterior, normalmente se usan más reglas CSS que en mobile first.

44 Imágenes adaptativas y responsives

Las imágenes representan habitualmente el mayor porcentaje del peso de una página web. Un diseño responsive no consiste únicamente en reorganizar columnas y menús: también debe conseguir que las imágenes se adapten al tamaño del dispositivo, mantengan su proporción y, cuando sea posible, descarguen la versión más adecuada para cada pantalla.

Hay que diferenciar dos conceptos muy importantes:

  • Imágenes adaptativas: el navegador descarga una versión diferente según el dispositivo.
  • Imágenes responsivas: la misma imagen cambia de tamaño y se adapta al espacio disponible.

Supongamos una fotografía de 3000 × 2000 píxeles:

  • Si la mostramos en un teléfono de 390 píxeles de ancho, el navegador tendrá que reducir enormemente su tamaño.
  • Si además la imagen ocupa varios megabytes, estaremos descargando mucho más contenido del necesario.

Los principales problemas son:

  • Mayor tiempo de carga.
  • Más consumo de datos móviles.
  • Peor experiencia de usuario.
  • Peor posicionamiento en buscadores.

Por ello, las imágenes deben formar parte del diseño responsive.

44.1 Imágenes responsive y aspect-ratio

A la hora de añadir imágenes en nuestra web lo habitual es querer que cambie de tamaño al espacio disponible, y que mantenga su proporción para que no se vea mal.

Imágenes responsive

img {
    max-width: 100%;
    height: auto;
}

Esta sencilla regla consigue que la imagen:

  • Nunca sea más ancha que su contenedor.
  • Mantenga automáticamente su proporción (gracias a height:auto).
  • Se reduzca cuando el espacio disponible disminuye.

Es una práctica recomendada en prácticamente cualquier proyecto web.

Existe pequeñas diferencias entre width: 100% y max-width: 100%:

  • width:100%: La imagen siempre ocupa todo el ancho del contenedor, incluso si originalmente era más pequeña.
  • max-width:100%: La imagen solo se reduce cuando es necesario, pero nunca se amplía por encima de su tamaño original. Esta suele ser la opción recomendada.

Ejemplo para una galería creada con Grid, que tiene imágenes responsives:

HTML

<section class="galeria">
  <img src="1.jpg" alt="">
  <img src="2.jpg" alt="">
  <img src="3.jpg" alt="">
</section>

CSS

.galeria {
  display: grid;
  grid-template-columns: 
            repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

.galeria img {
    width: 100%;
    height: auto;
    object-fit: cover;
}

En lugar de usar height:auto también se puede usar aspect-ratio:auto, ya que mantendrá la proporción. Esta propiedad permite forzar las imágenes a un ratio especificado, aunque lo ideal es añadir siempre el fallback: aspect-ratio: auto 16/9:

CSS

.galeria img {
    width: 100%;
    aspect-ratio: auto 16/9;
}

44.2 Imágenes adaptativas con srcset

Hasta ahora siempre descargábamos la misma imagen, pero HTML permite ofrecer varias versiones de un mismo recurso mediante srcset. De esta manera el navegador elige automáticamente la imagen más adecuada según:

  • El ancho del viewport.
  • La resolución del dispositivo.
  • La densidad de píxeles.

Esto reduce el consumo de datos y mejora el rendimiento.

HTML

<img alt="Paisaje"
    src="foto-800.jpg"
    srcset="
        foto-400.jpg 400w,
        foto-800.jpg 800w,
        foto-1200.jpg 1200w
    "
    sizes="
        (max-width: 768px) 100vw,
        50vw
    ">

El atributo sizes se combina con srcset y de esta manera lo que conseguimos es:

  • En pantallas menores de 768 px la imagen ocupará el 100 % del viewport.
  • En pantallas mayores ocupará aproximadamente el 50 %.

Con esta información el navegador puede seleccionar la versión más eficiente antes de descargarla.

44.2.1 El elemento <picture>

A veces no basta con cambiar la resolución: queremos mostrar una fotografía diferente según el dispositivo.

Para ello existe el elemento <picture>.

Imágenes diferentes según tamaño

<picture>
    <source
        media="(max-width: 768px)"
        srcset="cabecera-mobile.jpg"
    >
    <source
        media="(min-width: 769px)"
        srcset="cabecera-desktop.jpg"
    >
    <img src="cabecera-desktop.jpg" alt="Cabecera">
</picture>

El navegador elegirá la primera imagen cuya condición se cumpla. Este método es muy útil cuando el encuadre de la fotografía cambia entre móvil y escritorio.

44.2.2 Imágenes de fondo

Las imágenes utilizadas mediante CSS también pueden ser responsivas.

Imágenes diferentes según tamaño

.hero {
    background-image: url("hero-mobile.jpg");
}
@media (min-width: 768px) {
    .hero {
        background-image: url("hero-desktop.jpg");
    }
}

De esta forma cada dispositivo descarga una imagen distinta. Es una técnica habitual en cabeceras de gran tamaño.

08d

Comprueba el funcionamiento de usar distintas imágenes para tamaños distintos.

44.3 Formatos modernos de imagen

Además del diseño responsive, también conviene utilizar formatos eficientes, ya que mejoran el algoritmo de compresión y pueden hacer que ocupen menos:

Formato Uso recomendado
JPEG Fotografías
PNG Transparencias
SVG Iconos y logotipos
WebP Fotografías optimizadas
AVIF Máxima compresión

Actualmente WebP y AVIF ofrecen una excelente relación entre calidad y tamaño de archivo, por lo que son muy recomendables para proyectos modernos.

45 Tipografía adaptable

Uno de los objetivos principales del diseño responsive es garantizar que el contenido sea legible en cualquier dispositivo. No basta con reorganizar columnas o cambiar el tamaño de las imágenes: la tipografía también debe adaptarse al espacio disponible.

Una tipografía adaptable ajusta el tamaño del texto de forma progresiva según el tamaño del viewport, evitando que las letras sean demasiado pequeñas en un móvil o excesivamente grandes en un monitor de gran resolución. Para conseguirlo, CSS ofrece unidades relativas y funciones como clamp().

Sigue siendo habitual encontrar estilos como este:

Tipografía estática

h1 { font-size: 48px; }

p { font-size: 16px; }

Y aunque funciona, presenta varios inconvenientes:

  • En un móvil, un título de 48 px puede ocupar demasiadas líneas.
  • En un monitor 4K, un texto de 16 px puede resultar pequeño.
  • Obliga a crear numerosas Media Queries para ajustar cada tamaño.

Por ello, en diseño responsive se prefieren unidades relativas y tamaños fluidos.

45.1 Escala tipográfica

Aunque ya se ha visto previamente al hablar de la unidad relativa rem, es conveniente recordar que es recomendable utilizar una escala tipográfica consistente.

Tipografía relativa

h1    { font-size: 2.5rem; }
h2    { font-size: 2rem; }
h3    { font-size: 1.5rem; }
p     { font-size: 1rem; }
small { font-size: 0.875rem; }

Esta jerarquía facilita la lectura y mantiene la coherencia visual del sitio. Aparte, tiene en cuenta el tamaño por defecto del navegador que ha podido ser modificado por el usuario.

45.2 Adaptar la tipografía con Media Queries

Ahora ya sólo queda hacer que la sea tipografía responsive haciendo uso de Media Queries para adaptarla al tamaño que nos interese. Teniendo en cuenta el anterior ejemplo:

Añadido media queries

@media (min-width: 768px) {
    h1 { font-size: 3.5rem; }
}

45.2.1 Unidades del viewport

CSS también permite relacionar el tamaño del texto con el ancho del viewport mediante la unidad vw.

Tipografías según el viewport

h1 { font-size: 6vw; }

Si el viewport mide 1000px:

  • 1vw = 10 px
  • 6vw = 60 px

Si el viewport mide 400px:

  • 1vw = 4 px
  • 6vw = 24 px

El texto cambia automáticamente de tamaño al modificar la ventana. El problema es que al usar vw puede hacer que en un monitor muy grande el título puede hacerse enorme, mientras que en un móvil muy pequeño puede resultar demasiado reducido.

Por ello, normalmente se combina vw con límites mínimos y máximos mediante clamp().

45.3 Uso de clamp()

Ya se ha visto la función clamp() anteriormente, pero es ahora cuando le encontramos el valor añadido, ya que nos va a solucionar el problema de usar vw. Actualmente la técnica recomendada para crear tipografía fluida.

Tipografías relativa con clamp()

h1 { font-size: clamp(2rem, 5vw, 4rem); }

La regla anterior nos permite hacer que la tipografía:

  • Nunca será menor de 2 rem.
  • Intentará crecer utilizando 5vw.
  • Nunca superará 4 rem.

El navegador calcula automáticamente el valor adecuado.

Si usamos clamp() de manera correcta nos ahorra crear Media Queries para la tipografía.

45.4 Otros aspectos a tener en cuenta

Existen otros aspectos que tienen que ver con la tipografía que deberíamos tener en cuenta a la hora de adaptar nuestra página web, entre otros:

  • Altura de línea: La legibilidad no depende únicamente del tamaño de la letra. La altura de línea (line-height) también es fundamental.
  • Longitud de línea: Los párrafos demasiado anchos son difíciles de leer, por ello, es recomendable limitar su anchura con max-width. Un ancho de 60–75 caracteres por línea suele considerarse óptimo para textos largos. Un ancho de 70–80 caracteres por línea suele considerarse óptimo para textos largos.
  • Espaciado entre párrafos: Además del interlineado, conviene separar visualmente los párrafos. Para ello se puede usar p {margin-bottom:1rem;} y de esta manera hace que el espaciado crezca proporcionalmente con el resto de la tipografía.

46 Contenedores fluidos

Uno de los principios fundamentales del diseño responsive consiste en evitar que los elementos tengan un tamaño fijo cuando no es necesario. En lugar de diseñar cajas de 960px o 1200px de ancho, los contenedores modernos se adaptan al espacio disponible utilizando porcentajes, unidades relativas y límites máximos.

Un contenedor fluido es un elemento cuya anchura crece y disminuye junto con el viewport, manteniendo al mismo tiempo una lectura cómoda en pantallas grandes. Esta técnica se utiliza en prácticamente todos los frameworks modernos, como Bootstrap, Tailwind CSS o Bulma.

46.1 Contenedor fluido junto con max-width

La evolución a la hora de crear contenedores ha sido la siguiente:

Ancho fijo

.container {
  width: 960px;
  margin: 0 auto;
}

Fluido

.container {
  width: 100%;
}

Usando max-width

.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem;
}
  • Ancho fijo: Este diseño funcionaba correctamente en monitores de la época, pero presentaba varios inconvenientes:
    • En móviles aparecía desplazamiento horizontal.
    • En pantallas pequeñas el contenido no cabía.
    • Era necesario crear numerosas Media Queries para corregir el diseño.
  • Uso de porcentajes: Ahora el contenedor ocupa siempre todo el ancho disponible. Sin embargo, en un monitor de gran tamaño los párrafos pueden resultar excesivamente largos.
  • Uso de max-width: En un móvil ocupará todo el ancho, en un portátil crecerá progresivamente y en pantallas muy anchas (estilo ultra-wide) nunca superará los 1200 px.
    • El uso de margin ayuda a centrar el contenido.
    • Con padding hacemos que el texto no esté pegado al borde del dispositivo.

46.2 Mejorando el contenedor

Podemos mejorar el contenedor fluido creado anteriormente utilizando menos reglas, pero manteniendo el comportamiento:

Mejorando contenedor

.container {
    width: min(100%, 1200px);
    margin-inline: auto;
    padding-inline: 1rem;
}

Novedades:

  • min() elige el valor menor entre 100% y 1200px.
  • margin-inline sustituye a margin-left y margin-right.
  • padding-inline aplica el relleno horizontal respetando la dirección del texto.

Componentes de una interfaz

47 Componentes de una interfaz

Hasta ahora hemos aprendido a construir páginas web utilizando HTML, CSS, Flexbox, Grid y diseño responsive. Sin embargo, una interfaz de usuario no es únicamente una distribución de elementos: está formada por componentes reutilizables que aparecen en prácticamente cualquier aplicación web.

Una cabecera, un menú, una tarjeta o un formulario son ejemplos de componentes de interfaz. Cada uno resuelve un problema concreto y puede reutilizarse en diferentes páginas de un mismo proyecto.

47.1 Cabeceras <header>

La cabecera (header) es la zona superior de una página web. Normalmente contiene la identidad del sitio, la navegación principal y, en ocasiones, herramientas como el buscador o el acceso de usuario.

Es uno de los componentes más importantes de cualquier interfaz, ya que suele aparecer en todas las páginas de un mismo sitio y constituye el principal punto de navegación para el usuario.

En HTML existe un elemento semántico específico para representar la cabecera <header>. Este elemento indica que el contenido pertenece a la parte introductoria de una página o de una sección. Una cabecera puede contener:

  • Logotipo o nombre del sitio.
  • Menú de navegación.
  • Buscador.
  • Iconos de usuario.
  • Botones de acceso.

No existe un único diseño correcto; dependerá del tipo de aplicación que estemos desarrollando. El ejemplo más sencillo únicamente mostraría el nombre del sitio, pero hoy día una web suele tener distintos apartados, accesibles a través de una barra de navegación:

HTML

<header class="header">
  <h1 class="logo">MiWeb</h1>
  <nav>
    <a href="#">Inicio</a>
    <a href="#">Cursos</a>
    <a href="#">Blog</a>
    <a href="#">Contacto</a>
  </nav>
</header>

CSS

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    padding: 1rem 2rem;

    background-color: #1f2937;
}

.logo {
    margin: 0;
    color: white;
}

.header nav {
    display: flex;
    gap: 1.5rem;
}

.header a {
    color: white;
    text-decoration: none;
}

Flexbox resulta la mejor opción para este tipo de distribución horizontal.

47.2 Menús de navegación con <nav>

El menú de navegación <nav> es el componente que permite al usuario desplazarse entre las diferentes páginas o secciones de un sitio web. Junto con la cabecera, constituye uno de los elementos más importantes de la experiencia de usuario, ya que facilita el acceso al contenido y ayuda a comprender la estructura de la aplicación.

En el ejemplo anterior ya se ha creado dentro de la cabecera el elemento semántico <nav>. Este elemento mejora la accesibilidad y ayuda a los lectores de pantalla a identificar la navegación principal del sitio.

Una página puede contener varios elementos <nav> si existen distintos bloques de navegación: por ejemplo, un menú principal y otro en el pie de página.

Desde el punto de vista semántico, un menú representa un conjunto de elementos relacionados. Por ello, es muy habitual construirlo mediante listas.

HTML

<nav>
  <a href="#" class=active>Inicio</a>
  <!-- ... -->
</nav>

CSS

.active {
  border-bottom: 2px solid white;
}

47.2.1 Usabilidad en la navegación

Dada la importancia de los menús de navegación, es importante indicar al usuario en qué sección se encuentra. Por lo tanto, en la cabecera, en la sección en la que nos encontramos se suele añadir un estilo propio para que se vea claramente.

HTML

<header class="header">
  <h1 class="logo">MiWeb</h1>
  <nav>
    <ul class="menu">
      <li><a href="#">Inicio</a></li>
      <li><a href="#">Cursos</a></li>
      <li><a href="#">Blog</a></li>
      <li><a href="#">Contacto</a></li>
    </ul>
  </nav>
</header>

CSS

.menu {
  display: flex;
  gap: 1.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}
.menu a {
  text-decoration: none;
}

Una interfaz debe proporcionar retroalimentación cuando el usuario interactúa con ella. Para ello, en la navegación se suele usar el efecto :hover con reglas CSS especiales para modificar el color, por ejemplo.

Efecto :hover

nav a:hover {
    color: #2563eb;
}

47.2.2 Cabecera responsive

Es importante, teniendo en cuenta todo lo visto hasta ahora, que debemos tener en cuenta cómo queremos que se visualice la cabecera en distintos dispositivos, por lo que tenemos que hacerla responsive para que se adapte. Normalmente:

  • En dispositivos móviles la cabecera y los enlaces de navegación tienen una disposición vertical.
  • En navegadores de escritorio ocupan todo el ancho, el logo está a la izquierda, y los enlaces de navegación pueden estar seguidos, centrados o a la derecha del todo.

09a

Crea una página HTML que una cabecera que se asemeje a un proyecto real. Debe contener:

  • Nombre de la página o logotipo
  • Menú de navegación con 3-4 enlaces
  • Caja de búsqueda
  • Botón para acceder/hacer login.

Añade efecto :hover al menú y que se vea en qué página de la aplicación nos encontramos.

48 Barras laterales

La barra lateral (sidebar) es un componente de interfaz que agrupa opciones de navegación, herramientas o información secundaria en uno de los laterales de la pantalla. Es muy habitual en paneles de administración, plataformas educativas, gestores de contenidos y aplicaciones empresariales.

A diferencia del menú principal, que suele situarse en la cabecera, la barra lateral permite organizar un gran número de opciones sin ocupar espacio vertical. Normalmente contiene:

  • Navegación principal.
  • Categorías.
  • Accesos rápidos.
  • Configuración.
  • Información del usuario.

48.1 Estructura HTML básica

La estructura semántica suele utilizar <aside> para representar contenido complementario.

HTML

<div class="layout">
  <aside class="sidebar">
    <h2>Panel</h2>
    <nav>
      <a href="#">Inicio</a>
      <a href="#">Alumnos</a>
      <a href="#">Cursos</a>
      <a href="#">Configuración</a>
    </nav>
  </aside>
  <main>
    <h1>Contenido principal</h1>
  </main>
</div>

CSS

.layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

.sidebar {
  padding: 1rem;
}

main {
  padding: 2rem;
}

El elemento <aside> indica que este contenido es complementario respecto al contenido principal representado por <main>. Grid es la herramienta más adecuada para crear una barra lateral, con el que, a través de CSS, se han creado dos columnas: una primera de 240px para la barra lateral y el resto para el contenido principal <main>.

48.2 Menú interno con Flexbox

Dentro del sidebar, dado que queremos categorizar de manera vertical los enlaces, o apartados, podemos hacer uso de Flexbox para organizar los enlaces.

CSS

.sidebar nav {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

Cada enlace aparece debajo del anterior con una separación uniforme. De esta manera, podemos ver cómo Grid organiza la página y Flexbox organiza los componentes, en este caso de la barra lateral.

48.4 Posición fija durante el scroll

En paneles de administración es habitual que el menú permanezca visible, y que no se mueva con el scroll. Para ello podemos añadir las siguiente reglas dentro de la versión de escritorio.

Mantener sidebar fijo

.sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
}

09b

Partiendo del ejercicio anterior: - Añade una barra lateral. - Modifica el comportamiento entre el móvil y el escritorio.

49 Tarjetas

Las tarjetas (cards) son uno de los componentes más utilizados en el diseño de interfaces modernas. Una tarjeta es un contenedor que agrupa información relacionada dentro de una superficie visual independiente, facilitando la organización del contenido y su reutilización.

Actualmente encontramos tarjetas en casi cualquier aplicación: productos de una tienda online, cursos de una plataforma educativa, noticias, perfiles de usuario, paneles de estadísticas o publicaciones de redes sociales. Suele contener título, texto, etiquetas, botones, iconos, y/o una imagen.

La estructura básica es tan sencilla como:

HTML

<article class="card">
  <img src="curso.jpg"
      alt="Curso de HTML">
  <h2>Curso de HTML</h2>
  <p>
    Aprende los fundamentos
    del desarrollo web.
  </p>
</article>

CSS

.card {
    padding: 1.5rem;
    border: 1px solid #d1d5db;
    border-radius: 0.75rem;
    background-color: white;
}

.card h2 {
    margin-top: 0;
}
.card img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: 0.5rem;
}

Utilizamos <article> porque representa una unidad de contenido independiente que podría reutilizarse en otras partes del sitio.

Se ha añadido una imagen que cubre la parte superior de la tarjeta, y añadiendo bordes redondeados tanto a la tarjeta como a la imagen para mejorar el aspecto.

49.1 Tarjetas y posicionamiento en Grid

El uso de tarjetas es un patrón perfecto para crear una cuadrícula/grid. A la hora de colocar las tarjetas podemos hacerlo de diferentes formas, y por tanto, ajustar la configuración del grid al diseño que más queramos:

  • Tener siempre el mismo número de columnas: este diseño es adecuado si tenemos controlado el tamaño de pantalla, y si sabemos que no se va a ver en otro sistema. NO es el sistema recomendado,
  • Las tarjetas siempre tienen el mismo ancho: ideal si queremos que siempre se vean igual. El problema es que no es adaptable al tamaño de la pantalla.
  • Usar grid responsive: las tarjetas tendrán un tamaño mínimo asignado, pero se adaptarán al tamaño de la pantalla. Este es el sistema recomendado hoy día.

50 Botones

Los botones son uno de los componentes con los que más interactúan los usuarios. Permiten enviar formularios, abrir ventanas, confirmar acciones, cancelar operaciones o navegar dentro de una aplicación. Un buen diseño de botones mejora la usabilidad, transmite claramente la importancia de cada acción y proporciona una respuesta visual inmediata al usuario.

En HTML existen dos elementos muy utilizados: <button> y <a>. Aunque ambos pueden tener el mismo aspecto mediante CSS, su significado semántico es diferente:

  • <button>: ejecuta una acción.
  • <a>: navega a otra página.

50.1 El elemento <button>

El elemento semántico para ejecutar acciones es <button>. Las acciones más habituales son enviar un formulario, abrir un cuadro de diálogo, ejecutar una función de JavaScript o confirmar/cancelar una acción.

HTML

<button>Guardar</button>

<button disabled>Cancelar</button>

CSS

button {
    padding: 0.75rem 1.25rem;
    border: none;
    border-radius: 0.5rem;
    background-color: #2563eb;
    color: white;
    cursor: pointer;
}

A la hora de modificar los atributos de un botón podemos hacer que tenga más área de pulsación, esquinas redondeadas y modificar el color, entre otras cosas.

50.2 Estados de un botón

Un botón puede encontrarse en distintos estados visuales, y por tanto podemos usarlo como reglas CSS:

  • button: el estado por defecto.
  • button:hover: estado al pasar el ratón por encima.
  • button:active: cuando se hace click en el botón.
  • button:disabled: el botón está desactivado, no se puede hacer hacer click.

50.3 Diferencia entre botones y agrupación

No todas las acciones tienen la misma importancia, por tanto, si existen botones para realizar distintas acciones, deberían tener colores y/o formas distintas, o indicaciones con distintos iconos. Los botones deben ser fácilmente identificables y utilizables, para ello, como buenas prácticas es importante:

  • Utilizar texto descriptivo de la acción que realiza.
  • Evitar depender únicamente del color para diferenciar acciones.
  • Mantener suficiente contraste entre texto y fondo.
  • Proporcionar un área de pulsación amplia (al menos unos 44 × 44 px en interfaces táctiles).
  • Utilizar el atributo disabled cuando la acción no esté disponible.
Ejemplo de botones en Bootstrap

En muchas aplicaciones es habitual alinear botones para realizar distintas acciones y que estén cerca entre sí. La mejor manera es hacer uso de Flexbox, y su sistema de alineación, ya se horizontal o vertical. Algunos frameworks permiten la agrupación de botones, que se usa para botones con acciones relacionadas entre sí.

Grupo de botones con Bulma

09c

Partiendo del ejercicio anterior: - Crea un sistema grid que contenga tarjetas - Cada tarjeta debe tener una imagen, un encabezado, un pequeño texto y un enlace tipo botón. - Añade en alguna tarjeta un texto de “oferta” como si fuese un producto rebajado.

51 Formularios

Los formularios <form> son el principal mecanismo mediante el cual una aplicación web recoge información del usuario, desde un inicio de sesión hasta una matrícula, una compra online o un formulario de contacto, prácticamente cualquier sitio web necesita formularios bien diseñados.

Un buen formulario no solo debe ser estéticamente agradable: también debe ser claro, accesible, fácil de completar y adaptable a dispositivos móviles. Los elementos más habituales que encontraremos dentro de un formulario son:

  • Etiquetas (label): cada campo debe tener una etiqueta descriptiva. El atributo for conecta la etiqueta con el id del campo <input>correspondiente. Esta relación mejora la accesibilidad y permite que al pulsar sobre el texto también se active el campo de entrada.
  • Campos de texto (input): Existen distintos tipos para determinados tipos de datos, y es importante elegir el correcto, ya que mejora la validación y la experiencia de usuario en dispositivos móviles.
    • text: Texto general
    • email: Correo electrónico
    • password: Contraseñas
    • tel: Teléfono
    • number: Valores numéricos
    • date: Fechas
  • Áreas de texto (textarea): para añadir textos largos.
  • Listas desplegables (select): permite seleccionar entre distintas opciones.
  • Casillas de verificación (input type="checkbox"): permite elegir varias opciones.
  • Casillas de selección (inpuyt type="radio"): permite elegir una opción entre varias.
  • Botones (button)

El formulario agrupa todos los controles de entrada y permite enviar la información al servidor cuando el usuario pulsa el botón correspondiente.

HTML

<form>
  <div class="form-group">
    <label for="nombre">Nombre</label>
    <input
      id="nombre"
      type="text"
    >
  </div>

  <div class="form-group">
    <label for="email">Correo</label>
    <input
      id="email"
      type="email"
    >
  </div>
</form>

CSS

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

input,
textarea,
select {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid #d1d5db;
    border-radius: 0.5rem;
    font: inherit;
    box-sizing: border-box;
}

El ejemplo anterior crea un formulario básico con:

  • Anchura completa.
  • Espaciado cómodo.
  • Esquinas redondeadas.
  • Tipografía coherente con el resto de la página.

Unificando cada label con su input en un grupo permite crear un sistema Flexbox, que en este caso se ha alineado de manera vertical, pero se podría modificar a modo horizontal para la vista de escritorio.

09d

Crea un formulario que se vea diferente en distintos dispositivos.

52 Tablas

Las tablas permiten representar información organizada en filas y columnas. Son especialmente útiles cuando necesitamos mostrar datos que tienen una relación entre sí, como listados de alumnos, productos, horarios, resultados o estadísticas.

Aunque CSS permite transformar prácticamente cualquier conjunto de elementos en una tabla visual, cuando los datos son realmente tabulares debemos utilizar los elementos HTML específicos para tablas, lo que proporciona una estructura semántica que facilita la accesibilidad y permite a los navegadores interpretar correctamente la información.

Una tabla se construye mediante los siguientes elementos:

  • <table>: Contenedor de la tabla.
  • <thead>: Encapsula las filas que forman la cabecera de la tabla. Es opcional.
  • <tbody>: Encapsula las filas que forman el contenido principal de la tabla. Es opcional.
  • <tfoot>: Encapsula las filas que forman la parte baja de la tabla. Es opcional.
  • <tr>: Fila.
  • <th>: Celda de encabezado.
  • <td>: Celda de datos.

HTML

<table>
  <thead>
    <tr>
      <th>Student ID</th>
      <th>Name</th>
      <th>Major</th>
      <th>Credits</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>3741255</td>
      <td>Jones, Martha</td>
      <td>Computer Science</td>
      <td>240</td>
    </tr>
    <tr>
      <td>3971244</td>
      <td>Nim, Victor</td>
      <td>Russian Literature</td>
      <td>220</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th colspan="3">Totals</td>
      <td>460</td>
    </tr>
  </tfoot>
</table>

CSS

thead, tfoot {
  border-bottom: 2px solid rgb(160 160 160);
  text-align: center;
  background-color: #2c5e77;
  color: white;
}

tbody {
  background-color: #e4f0f5;
}
table {
  border-collapse: collapse;
  border: 2px solid rgb(140 140 140);
  font-family: sans-serif;
  font-size: 0.8rem;
  letter-spacing: 1px;
}

th, td {
  border: 1px solid rgb(160 160 160);
  padding: 8px 10px;
}
tbody > tr > td:last-of-type {
  text-align: center;
}
tbody tr:nth-child(even) {
    background-color: #f3f4f6;
}

52.1 Estilos de tablas

Los navegadores apenas añaden estilos a las tablas, lo que puede dificultar su lectura, por lo que resulta importante añadir estilos propios. Entre los estilos que suele ser recomendable añadir son:

  • Encabezados: añadir un estilo para las cabeceras permite visualizar claramente qué representa cada columna.
  • Bordes: permite separar el contenido para mejorar su visualización.
  • Filas alternas: para tablas largas conviene alternar los colores de filas pares/impares.
  • Efecto :hover: para facilitar la lectura, también se puede destacar la fila sobre la que se encuentra el cursor.
  • Tablas responsive: uno de los principales problemas de las tablas es su comportamiento en pantallas pequeñas. La solución sencilla consiste en permitir desplazamiento horizontal con overflow-x: auto en el contenedor padre de la tabla.

09e

Crea una tabla que contenga lo expuesto previamente.

53 Modals

Un modal es una ventana que aparece sobre el contenido principal de una página para mostrar información o solicitar una acción al usuario. Mientras el modal está abierto, normalmente el usuario debe interactuar con él antes de continuar con el contenido que queda detrás.

Los moal se utilizan habitualmente para:

  • Mostrar información adicional.
  • Confirmar acciones importantes.
  • Mostrar formularios para crear/editar datos.
  • Avisar de determinadas situaciones.
  • Mostrar imágenes o contenido ampliado.

Los modal debe utilizarse con moderación. Si una acción puede realizarse directamente sobre la página, normalmente es preferible no interrumpir al usuario con una ventana modal.

Se va a explicar cómo se creaban previamente a la aparición de la etiqueta <dialog> y después con la nueva etiqueta.

53.2 Elemento <dialog>

Desde el 2022 existe para todos los navegadores el elemento <dialog> que fue propuesto por Chrome. Con esta etiqueta podemos crear un elemento modal (aunque puede no serlo también) para generar un componente interactivo, alerta o una subventana.

Con los ejemplos más básicos no es necesario hacer uso de JavaScript, ya que existe un atributo desde 2023 popovertarget que permite asociar un botón para que abra el diálogo, teniendo en cuenta el id.

HTML

<button popovertarget="my-dialog">Open dialog</button>

<dialog id="my-dialog" popover>
  <p>bla bla</p>
  <button popovertarget="my-dialog" popovertargetaction="hide">Close</button>
</dialog>

<dialog> ofrece funcionalidades inspiradas en la forma “tradicional” de hacerlos, sólo que esta vez el navegador es capaz de realizar ciertas acciones y por tanto no tenemos que hacerlas de manera manual. Es una opción especialmente interesante en aplicaciones web modernas y es recomendable ver las distintas opciones que existen en la documentación de MDN.

HTML y CSS son tecnologías en constante evolución, por lo que cada cierto tiempo se añaden características para simplificar acciones al desarrollador.

53.3 Aspectos a tener en cuenta

A la hora de crear un modal se pueden tener ciertos aspectos en cuenta para mejorar el aspecto y la usabilidad general. Algunas de ellas son obligatorias, mientras que otras son optativas:

  • Hacer que el overlay oscurezca el fondo, para mejorar la visibilidad del contenido del modal.
  • No hay que olvidar hacer que el modal tenga un z-index superior al contenido general.
  • Añadir una animación de visualización/ocultación puede mejorar a que el usuario sepa dónde fijar la mirada.
  • Evitar el scroll de fondo mejora la sensación para hacer que el foco sea el modal

CSS

body.modal-open {
    overflow: hidden;
}

JavaScript

//Al abrir el modal, se añade una clase
btn.addEventListener("click", () => {
  modal.classList.add("is-open");
  document.body.classList.add("modal-open");
});
// falta quitar la clase al cerrar el modal

Con el ejemplo anterior, se evita poder hacer scroll en la página cuando el modal está abierto.

09f

Crea una página HTML que contenga:

  • Botón que abra un modal creado custom.
  • Botón que abra un <dialog>.
    • Comprueba las opciones que tiene y mira si resulta interesante alguna.

54 Avisos y/o alertas

Los avisos y alertas son componentes utilizados para mostrar al usuario información importante sobre el estado de una aplicación. A diferencia de los modales, las alertas normalmente no bloquean la interacción con el resto de la página, por lo que permiten continuar trabajando mientras permanecen visibles. Son especialmente útiles para comunicar:

  • Operaciones realizadas correctamente.
  • Errores.
  • Advertencias.
  • Información adicional.
  • Cambios en el estado de una aplicación.

Un ejemplo típico sería mostrar el mensaje de que los datos de un formulario se han guardado correctamente tras ser enviados.

HTML

<div class="aviso alert-info ">
  Los datos se han guardado.
</div>
<div class="aviso alert-error ">
  ¡ERROR!
</div>

CSS

.aviso {
    padding: 1rem;
    border-radius: 0.5rem;
    border: 1px solid transparent;
    margin: 10px 0;
}
.alert-info {
    background-color: #dbeafe;
    color: #1e3a8a;
}

54.1 Tipos de avisos

A la hora de crear avisos o alertas habría que tener en cuenta qué tipo de aplicación estamos construyendo, y los posibles avisos que queremos informar al usuario final. En una aplicación estándar, podríamos crear:

  • Aviso informativo: indica información útil para el usuario.
  • Aviso de confirmación/éxito: para indicar que la operación se ha realizado correctamente (guardar datos, crear usuario, …).
  • Alerta de advertencia: cuando se necesita la atención del usuario, aunque no es un error.
  • Alerta de error: para indicar que no se ha podido realizar la acción, o ha terminado con error.
Ejemplo de avisos

54.2 Posibles mejoras

A la hora de crear los avisos y alertas, nos puede interesar añadir las siguientes características:

  • Iconos: Un icono puede ayudar a identificar rápidamente el tipo de mensaje.
  • Título: Podemos añadir un título para separar el contenido.
  • Botón de cerrar: Para que el aviso/alerta desaparezca, añadir un botón de cerrado.
  • Alerta temporal: Algunas aplicaciones muestran mensajes durante unos segundos y después los ocultan automáticamente. Resulta útil para mensajes de confirmación, pero no debemos ocultar automáticamente mensajes importantes que el usuario necesite tiempo para leer.
  • ID del error: Para poder debuggear qué ha sucedido, podemos añadir un código único de error para que el usuario informe de dicho error.
  • Indicar dónde ha dado error: Esto es especialmente útil en formularios. Añadir un borde rojo en el registro de entrada que ha fallado indica claramente al usuario dónde está el error.

09g

Crea distintos diálogo de aviso y alerta:

  • Añade distintos colores para cada tipo de aviso.
  • Añade un título.
  • Añade un icono alineado con el texto (usa Flexbox).

56 Paginación

La paginación es un componente de navegación que permite dividir una gran cantidad de contenido en varias páginas. En lugar de mostrar todos los resultados al mismo tiempo, se presentan pequeños grupos de elementos y se permite al usuario desplazarse entre ellos.

Es habitual encontrar paginación en:

  • Listados de productos.
  • Resultados de búsquedas.
  • Listados de alumnos.
  • Noticias.
  • Artículos.
  • Registros de una base de datos.
  • Paneles de administración.

La paginación no es únicamente un elemento visual. Los enlaces deben permitir realmente acceder a las diferentes páginas de contenido. La paginación representa una navegación, por lo que podemos utilizar <nav> tal como hemos visto previamente, o una lista.

HTML

<nav aria-label="Paginación">
    <a href="?page=1">Anterior</a>
    <a href="?page=1">1</a>
    <a href="?page=2" class="active">2</a>
    <a href="?page=3">3</a>
    <a href="?page=4">4</a>
    <a href="?page=2">Siguiente</a>
</nav>

CSS

.pagination a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    min-height: 1.5rem;
    padding: 0.5rem;
    border: 1px solid #d1d5db;
    border-radius: 0.5rem;
    color: #374151;
    text-decoration: none;
    font-weight: bold;
}

En el ejemplo se ha añadido sólo el CSS para los enlaces, que al igual que sucede en muchas páginas, genera un pequeño borde para cada número.

Ejemplo de paginación

56.1 Diseño habitual

Dado que la paginación es un sistema de navegación, a simple vista nos debe mostrar claramente distintos aspectos, entre los que podemos destacar:

  • Página en la que nos encontramos.
  • Efecto :hover sobre los enlaces.
  • Deshabilitar “anterior” o “siguiente” si estamos en la primera o última página respectivamente.
  • Cuando existen muchas páginas no tiene sentido mostrar todos los números.

09i

Crea un sistema de paginación de uso habitual con las características de diseño especificadas.

57 Acordeones

Un acordeón es un componente de interfaz que permite mostrar y ocultar bloques de contenido. Cada bloque suele estar formado por un título o encabezado que el usuario puede pulsar para desplegar la información asociada.

Son especialmente útiles cuando tenemos mucha información que no queremos mostrar completamente al mismo tiempo. Algunos ejemplos habituales son:

  • Preguntas frecuentes.
  • Secciones de ayuda.
  • Opciones de configuración.
  • Descripciones adicionales.
  • Información agrupada por categorías.

Un acordeón puede tener inicialmente todos sus contenidos cerrados.

57.1 Estructura básica

Tal como pasa con otros elementos, originalmente este sistema se construía de manera “artesanal” usando HTML, CSS y JavaScript, pero desde 2020 existe dos etiquetas nuevas <details> y <sumamry> que nos facilita la creación ya que no es necesario el uso de JavaScript.

Método “artesanal”

<div class="accordion">
  <div class="accordion-item">
    <button class="accordion-header">
      Cabecera
    </button>
    <div class="accordion-content">
        <p>Contenido.</p>
    </div>
  </div>
  <!-- Más secciones -->
</div>

Método nuevo

<details>
  <summary>Cabecera</summary>
  <p>
    Contenido.
  </p>
</details>

El siguiente paso es tener el código CSS para añadir estilos personalizables, ocultar la sección por defecto, y el código JavaScript para ocultar/desocultar la sección en el método antiguo.

CSS

.accordion {
    border: 1px solid #d1d5db;
    border-radius: 0.5rem;
    overflow: hidden;
    width: 40%;
}
.accordion summary, 
.accordion .accordion-header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border: none;
    background-color: #f3f4f6;
    padding: 1rem 0rem 1rem 1rem;
    cursor: pointer;
    font-weight: 600;
    list-style: none;
    font: inherit;
}

JavaScript

const headers = 
document.querySelectorAll(".accordion-header");

headers.forEach(header => {
    header.addEventListener("click", () => {
        const item = header.parentElement;
        item.classList.toggle("is-open");
    });
});
Ejemplo de acordeón

57.2 Diseño y ayudas

Para facilitar la usabilidad de los acordeones es habitual hacer uso de los siguientes diseños y/o ayudas:

  • Diferenciar cabecera de contenido: normalmente la cabecera suele ser de un color y el contenido de otro.
  • Añadir una flecha o icono para indicar si la sección está abierta o cerrada. Al cambiar el estado, el icono debe cambiar.
  • Si existen varias secciones de acordeón juntas, hay que separar las distintas secciones.
  • En algunos casos al abrir un contenedor queremos cerrar el resto. Esto dependerá de la información y/o aplicación que estamos realizando.

09j

Crea un sistema de acordeón con el método nuevo y el método “manual”/“antiguo”. Dale el diseño CSS que más te guste y si es necesario el código JavaScript.

Frameworks CSS: Bootstrap

58 Frameworks CSS

Un framework CSS es un conjunto de archivos CSS, componentes y utilidades ya preparados que permiten desarrollar interfaces web de una forma más rápida y estructurada. En lugar de tener que escribir desde cero todos los estilos necesarios para una página, el framework proporciona clases y componentes que podemos utilizar directamente en nuestro HTML.

Por ejemplo, si queremos crear un botón con CSS puro, normalmente tendríamos que definir nosotros mismos propiedades como el color, el fondo, el borde, el tamaño, el espacio interior y los diferentes estados del botón. En un framework podemos encontrar clases que ya proporcionan este tipo de estilos. Ejemplo de un botón propio y uno creado con Bootstrap

CSS propio para botón

.boton {
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 0.5rem;
    background-color: #0d6efd;
    color: white;
    cursor: pointer;
}

Botón HTML con Bootstrap

<button class="btn btn-primary">
    Aceptar
</button>

Tal como se puede ver, el desarrollador no tiene que implementar desde cero todas las reglas CSS necesarias para conseguir el aspecto básico del botón, sólo añadir un par de clases al HTML para conseguir el mismo resultado.

Existen numerosos frameworks y sistemas de estilos:

Algunos frameworks proporcionan componentes visuales completos mientras que otros se centran más en clases de utilidad que permiten construir el diseño combinando pequeñas reglas.

58.1 ¿Qué proporciona un framework CSS?

Aunque cada framework tiene sus propias características, normalmente proporciona diferentes tipos de herramientas. Entre ellas podemos encontrar:

  • Sistema de layout para organizar los elementos.
  • Grid para crear distribuciones mediante filas y columnas.
  • Clases de utilidad para propiedades frecuentes.
  • Componentes visuales como botones, tarjetas, menús o alertas.
  • Estilos para formularios.
  • Diseño responsive.
  • Tipografía.
  • Colores.
  • Espaciado.
  • Bordes y sombras.
  • Estados interactivos.

Por tanto, un framework CSS no es simplemente una colección de colores y botones. Proporciona una serie de herramientas que permiten construir interfaces siguiendo unas reglas comunes.

58.2 Frameworks CSS y clases

Una de las características habituales de estos frameworks es el uso intensivo de clases CSS. Por ejemplo, podemos encontrar clases destinadas a controlar el espaciado o a controlar el layout:

Margen superior e inferior

<div class="mt-2 mb-2">
    Contenido
</div>

Botón HTML con Bootstrap

<div class="container">
  Contenido
</div>

La clase utilizada dependerá del framework concreto. La idea fundamental es que el HTML utiliza las clases proporcionadas por el framework para aplicar los estilos que necesitamos.

58.3 Frameworks CSS y diseño responsive

Una de las razones por las que los frameworks CSS se hicieron especialmente populares es que facilitan la creación de interfaces responsive. Recordemos que una interfaz responsive debe adaptarse a diferentes tamaños de pantalla.

Un framework proporciona normalmente clases y reglas que ya contemplan diferentes tamaños de pantalla. Por ejemplo, Bootstrap utiliza diferentes breakpoints para adaptar su sistema de layout, lo que permite construir layouts responsive sin tener que definir manualmente todas las media queries necesarias.

58.4 Ventajas e inconvenientes de utilizar un framework CSS

Los frameworks CSS proporcionan numerosas ventajas, pero no siempre son la mejor opción. Su utilización debe depender de las características del proyecto.

Ventajas Inconvenientes
Desarrollo más rápido Dependencia del framework
Diseño responsive HTML con muchas clases
Algunos disponen de componentes reutilizables Personalización: no siempre resulta sencilla
Consistencia visual Curva de aprendizaje
Compatibilidad
Documentación y comunidad

58.5 Framework CSS como herramienta, no como sustituto de CSS

Un framework CSS no debe entenderse como un sustituto de CSS. El framework está construido utilizando CSS y proporciona una capa de abstracción sobre él. Aprender un framework no debería significar dejar de aprender CSS.

Un desarrollador que conoce CSS puede utilizar un framework de forma consciente, modificarlo cuando sea necesario y solucionar problemas cuando el comportamiento predeterminado no sea suficiente.

59 Bootstrap

Bootstrap es un framework CSS orientado al desarrollo de interfaces web. Proporciona un conjunto de estilos, componentes y utilidades que permiten construir páginas web de forma más rápida y mantener una apariencia coherente entre sus diferentes elementos.

Bootstrap fue creado originalmente por desarrolladores de Twitter y se publicó como proyecto de código abierto en 2011. Con el tiempo se convirtió en uno de los frameworks CSS más conocidos y utilizados para el desarrollo de interfaces web.

Su objetivo principal es proporcionar una base sobre la que construir una interfaz sin tener que implementar desde cero todos los estilos habituales.

59.1 Instalación e inclusión de Bootstrap

Para utilizar Bootstrap en una página web necesitamos incorporar sus archivos al proyecto. Existen diferentes formas de hacerlo, pero las dos más habituales son utilizar una CDN (content delivery network, red de distribución de contenidos) o descargar Bootstrap e incluir sus archivos dentro del propio proyecto.

La opción elegida depende de las necesidades del proyecto. Para comenzar a trabajar con Bootstrap, una CDN resulta especialmente sencilla porque no necesitamos descargar ni configurar ningún archivo. En proyectos donde queremos tener un mayor control sobre las dependencias, podemos instalar Bootstrap dentro del propio proyecto.

HTML con Bootstrap

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bootstrap demo</title>
  <link 
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" 
    rel="stylesheet" 
    integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" 
    crossorigin="anonymous">
</head>
<body>
  <h1>Hello, world!</h1>
  <script 
    src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" 
    integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" 
    crossorigin="anonymous"></script>
</body>
</html>

El ejemplo anterior muestra la página HTML mínima usando Bootstrap a través del CDN. Se ha añadido las siguientes etiquetas:

  • meta name="viewport": ya hemos visto anteriormente que es la etiqueta para tener diseño responsive.
  • link para bootstrap.min.css: es la hoja de estilos de Bootstrap con todas las reglas necesarias para poder usarlo. Es la versión “minimizada” (sin saltos de línea).
    • Atributo integrity: permite al navegador comprobar que el archivo descargado coincide con el contenido esperado, que es un hash criptográfico.
    • Atributo crossorigin: indica cómo debe realizarse la solicitud de un recurso situado en otro origen.
  • <script> para bootstrap.bundle.min.js: Bootstrap proporciona un fichero JavaScript ya que algunos componentes son interactivos y lo necesitan. Es un bundle porque incluye también Popper, una dependencia utilizada por algunos componentes interactivos. Es importante que este fichero se cargue tras la carga de todo el documento HTML. Por lo tanto:
    • Debe ir al final del documento, justo antes de cerrar </body>. De esta manera el navegador puede procesar primero el contenido HTML antes de cargar y ejecutar determinados scripts.
    • Se podría añadir la etiqueta en el <head> usando defer para que se ejecute al final de la descarga.

Si elegimos la opción de tener los ficheros descargados, debemos guardarlos junto con el código HTML (normalmente se usan los directorios css y js) y después añadirlos usando la ruta correcta en el HTML.

La diferencia entre ambos sistemas podría resumirse en la siguiente tabla:

CDN Archivos locales
No necesitamos descargar Bootstrap manualmente Los archivos forman parte del proyecto
Configuración muy sencilla Tenemos mayor control
El navegador obtiene el recurso de Internet No necesitamos obtener Bootstrap desde una CDN
Muy cómodo para ejemplos y prototipos Adecuado cuando queremos controlar las dependencias
Dependemos de la disponibilidad de la CDN Tenemos que mantener los archivos

Como alternativa, también se puede hacer la instalación mediante sistemas como npm.

Para comprobar que se ha cargado correctamente, podemos añadir un botón, con su clase correspondiente, para ver si se renderiza de manera correcta:

Botón HTML con Bootstrap

<button class="btn btn-primary">
    Aceptar
</button>

59.2 Instalar sólo ciertos módulos

En el apartado anterior hemos instalado/confiugrado Bootstrap al completo, pero existe la posibilidad de hacer la instalación de sólo ciertos módulos, ya que cuentan con una separación que separa:

  • Layout: Sistema de estructura del documento que contiene breakpoints, sistema Grid, columnas, …
  • Content: Contiene las variables para los colores base, y el sistema reboot para tener consistencia.
  • Components: Es la parte que tiene todos los componentes que genera botones, tablas, alertas, acordeones…
  • Utilities: Contiene utilidades para hacer bordes, formas, anchuras, alturas…

En ciertos proyectos puede interesar cargar sólo ciertos componentes en lugar de todo el framework, por lo que es interesante ver la documentación para decidir qué interesa más.

59.3 CSS propio junto con Bootstrap

A la hora de crear nuestro proyecto no tenemos que decantarnos sólo en usar Bootstrap, ya que también podemos crear nuestro fichero CSS propio para tener nuestras reglas propias y de esta manera personalizar el proyecto.

Lo que tenemos que hacer es cargar nuestro fichero CSS después del fichero Bootstrap, ya que de esta manera, las reglas que realicemos, por cascada/especificidad/origen, tendrán más prioridad que las de Bootstrap si las realizamos de manera correcta cuando intentemos sobreescribir estilos.

10a y 10b

Crea:

  • HTML usando Bootstrap a través de CDN.
  • Añade botones, algún componente que haga uso de Bootstrap.
  • Crea una hoja de estilos propia, con reglas que añadan clases y usalas junto con Bootrap.
  • Crea otro HTML que use Bootstrap de manera local, tras descargar los ficheros necesarios.

59.4 Contenedores en Bootstrap

Bootstrap proporciona un sistema de contenedores que permite controlar la anchura del contenido de una página y mantenerlo centrado dentro del viewport.

Un contenedor resulta especialmente útil en pantallas grandes. Si colocásemos todo el contenido ocupando el 100 % de una pantalla muy ancha, las líneas de texto podrían resultar demasiado largas y la interfaz podría perder estructura.

Existen distintos contenedores que se adaptan al tamaño del viewport:

Diferencia entre contenedores de Bootstrap
Extra small <576px Small ≥576px Medium ≥768px Large ≥992px X-Large ≥1200px XX-Large ≥1400px
.container 100% 540px 720px 960px 1140px 1320px
.container-sm 100% 540px 720px 960px 1140px 1320px
.container-md 100% 100% 720px 960px 1140px 1320px
.container-lg 100% 100% 100% 960px 1140px 1320px
.container-xl 100% 100% 100% 100% 1140px 1320px
.container-xxl 100% 100% 100% 100% 100% 1320px
.container-fluid 100% 100% 100% 100% 100% 100%

Teniendo en cuenta cómo queremos que nuestra aplicación se vea, habrá que elegir la clase container que mejor nos convenga. Cuando redimensionamos la ventana, el contenedor modificará su tamaño teniendo en cuenta la tabla anterior.

10c

Crea un HTML que contenga:

  • Distintos tipos de contenedores.
  • Comprueba qué pasa al redimensionar la ventana.
  • Busca cómo añadirle padding y margen superior e inferior usando las clases propias de Bootstrap.
  • Analiza con las herramientas de desarrollador del navegador el CSS de cada contenedor, las reglas CSS que Bootstrap aplica y los breakpoints que tienen.

59.5 Sistema de columnas

Una de las características más conocidas de Bootstrap es su sistema de columnas. Este sistema permite distribuir el espacio disponible de una página en diferentes columnas y crear layouts responsive de una forma sencilla. El sistema se basa principalmente en tres clases:

  • .container: controla principalmente la anchura del contenido.
  • .row: crea una fila para organizar las columnas.
  • .col: permite distribuir el espacio disponible entre las columnas.

Bootstrap utiliza tradicionalmente un sistema basado en 12 columnas. Esto no significa que tengamos que crear siempre 12 elementos HTML, sino que el ancho disponible de una fila se puede dividir conceptualmente en 12 partes. Pueden ser 2+10, 4+8, 6+6…

Es importante diferenciar el sistema de columnas de Bootstrap de CSS Grid. Bootstrap utiliza un sistema basado en Flexbox para su sistema tradicional de filas y columnas, mientras que CSS Grid es un sistema de layout propio de CSS.

Es importante diferenciar el sistema de columnas de Bootstrap (basado en Flexbox) y CSS Grid. Ambos pueden resolver problemas similares, pero no son exactamente lo mismo.

59.5.1 Clases col-*

Para indicar cuántas de las 12 columnas queremos utilizar podemos emplear clases como:

  • col: para especificar que se va a crear una columna. El ancho lo decidirá automáticamente Bootstrap, dependiendo de cuántas columnas haya.
  • col-1: usa el ancho de una única columna.
  • col-2: usa el ancho de dos columnas.
  • col-12: usa todo el ancho de las 12 columnas.

De esta manera podemos crear contenedores que sólo usen el número de columnas que nos interesa para una misma fila. En una misma fila los contenedores que haya no pueden superar las 12 columnas, porque de ser así pasará a la siguiente fila.

Ejemplo de dos columnas

<div class="row">
  <div class="col">
    Columna izquierda
  </div>
  <div class="col-6">
    Columna derecha
  </div>
</div>

Ejemplo 3 columnas

<div class="row">
  <div class="col-2">
    Columna pequeña
  </div>
  <div class="col-5">
    Columna ancha
  </div>
  <div class="col-5">
    Columna ancha
  </div>
</div>

¿Qué pasa si las columnas en total supera el número 12?

59.5.2 Columnas vacías

Podemos utilizar menos de 12 unidades en la suma total en una fila, lo que hará que al final se deje espacio libre sin usar.

Ejemplo 3 columnas

<div class="row">
  <div class="col-2">
    Columna pequeña
  </div>
  <div class="col-5">
    Columna ancha
  </div>
  <div class="col-5">
    Columna ancha
  </div>
</div>

Si lo que queremos es poner columnas vacías al principio o en medio tenemos las clases offset y offset-*.

Ejemplo con columnas vacías

<div class="row">
  <div class="offset-3 col-2">
    Columna pequeña
  </div>
  <div class="col-5">
    Columna ancha
  </div>
</div>

¿Cómo crees que se estructura el ejemplo anterior?

59.5.3 Separación entre columnas

Bootstrap incorpora también un sistema de gutter, es decir, el espacio existente entre columnas. Las columnas no tienen por qué quedar pegadas visualmente. Bootstrap gestiona el espacio entre ellas mediante propiedades relacionadas con el padding y el margin.

Podemos modificar estos espacios utilizando clases específicas de Bootstrap, g-0, g-1 hasta g-5.

Si queremos controlar el espacio horizontal están las clases gx-* y para el espacio vertical gy-*.

59.5.4 Columnas responsive

Una de las principales ventajas del sistema de columnas es que podemos indicar diferentes tamaños dependiendo del breakpoint.

Ejemplo con columnas responsive

<div class="row">
  <div class="col-6 col-xl-3">
    Contenido
  </div>
  <div class="col-6 col-xl-9">
    Contenido
  </div>
</div>

En este ejemplo en pantallas de tamaño grande las columnas tendrán tamaño 3+9, y cuando saltemos el breakpoint a tamaño menor a “XL” (en Bootstrap <1200px) se pasará a tener dos columnas de tamaño 6+6.

Para indicar el tamaño de los breakpoints de las columnas tenemos distintos sufijos, que coinciden con lo visto anteriormente: sm, md, lg, xl y xxl.

Este sistema está pensado para trabajar muy bien con el enfoque Mobile First.

59.5.5 Alineación de columnas

Como las filas utilizan Flexbox, podemos utilizar clases de Bootstrap relacionadas con la alineación. Podemos diferenciar entre alineación vertical y horizontal.

Si el contenedor donde tenemos las columnas es más alto que el contenido, podemos realizar las siguientes alineaciones verticales:

  • Centrar de manera vertical toda la fila, tenemos las siguientes clases que hay que añadir al row:
    • align-items-start
    • align-items-center
    • align-items-end
  • Si queremos alinear la columna de manera independiente, tenemos que aplicar una de las siguientes clases al col correspondiente:
    • align-self-start
    • align-self-center
    • align-self-end

Por otro lado, si queremos centrar las columnas en el eje horizontal de manera responsive dentro del contenedor, tenemos las siguientes clases aplicables al row correspondiente.

  • justify-content-start
  • justify-content-center
  • justify-content-end
  • justify-content-around
  • justify-content-between
  • justify-content-evenly
Ejemplo de alineación de columnas con Bootstrap

59.5.6 Orden de columnas

Bootstrap también proporciona clases para modificar el orden visual de las columnas. Para ello existen las clases order-*, donde podemos añadir un número del 1 al 5. También existen las clases order-first y order-last.

10d

Crea un HTML que contenga distintos sistemas de columnas:

  • Donde haya diferentes columnas y anchuras distintas
  • Comprueba qué sucede cuando superas las 12 columnas, o cuando no llenas todas.
  • Añade columnas vacías con offset.
  • Añade clases para tener columnas responsive, modificando la anchura de ellas al cambiar el tamaño de ventanas.
  • Comprueba los sistemas de alineación tanto horizontal como vetical.
  • Haz una prueba de cambiar de orden las columnas.

59.6 Iconos

Los iconos son elementos gráficos que permiten representar de forma visual una acción, una información o una funcionalidad. Son muy habituales en las interfaces modernas y pueden aparecer en botones, menús, formularios, barras de navegación o mensajes.

Bootstrap no incluye iconos directamente dentro del framework CSS principal. Para trabajar con ellos existe una biblioteca independiente llamada Bootstrap Icons, desarrollada por el mismo proyecto.

Bootstrap Icons es una colección de iconos diseñada para utilizarse junto con Bootstrap, aunque también puede utilizarse independientemente. La biblioteca proporciona cientos de iconos en formato SVG.

Aparte de Bootstrap Icons existen otras bibliotecas con finalidad similar, tener iconos:

Utilizar una biblioteca de iconos permite mantener una coherencia visual en el proyecto, son fáciles de usar, suelen disponer de gran cantidad de iconos y como los iconos son vectoriales, podemos modificar el tamaño sin perder calidad.

59.6.1 Incluir Bootstrap Icons en el proyecto

Dado que es un proyecto independiente, es necesario incluir una nueva hoja de estilos para los iconos, y de esta manera poder utilizar sus clases.

Al igual que sucedía con Bootstrap, podemos descargarnos la hoja de estilos para tenerlo en nuestro proyecto o usar una CDN. En ambos casos es añadir la hoja de estilos, sólo que modificando la dirección dependiendo del método elegido.

HTML con Bootstrap Icons

<head>
  <!-- resto de cosas -->
  <link rel="stylesheet" href="css/bootstrap-icons.min.css">
</head>

59.6.2 Uso de Bootstrap Icons

Una vez incluida la biblioteca podemos utilizar los iconos mediante sus clases. En la página web del proyecto podemos ver y buscar entre los distintos iconos que hay, y al elegir uno nos muestra distintos ejemplos del mismo, también como usarlo y nos permite descargar el icono en formato SVG.

Distintos iconos

<h1><i class="bi bi-bootstrap"></i> Icons</h1>

<i class="bi bi-person fs-1 rojo"></i>

<button class="btn btn-primary bi bi-save-fill">
Guardar
</button>


<div class="alert alert-success bi bi-check-circle-fill" role="alert">
  A simple success alert.
</div>

En el ejemplo anterior se han añadido distintos iconos, y se han incluido en un botón y también en un aviso de alerta. De esta manera, los usuarios pueden identificar el propósito de ambos.

Podemos añadir nuestras propias clases para añadir colores a los iconos, o modificar el tamaño. Para esto último, también están las clases propias fs-1 a fs-6 para modificar el tamaño de la fuente.

Ejemplo con Bootstrap Icons

10e

Usa Bootstrap Icons:

  • En botones, avisos, párrafos…
  • Añade reglas propias para añadir colores
  • Copia el ejercicio 09b y añade iconos en los menús.

Anexos

60 Etiquetas HTML ordenadas alfabéticamente

Guía de referencia para todas las etiquetas en orden alfabético. Obtenidas de W3C:

Tag Descripción
<a> Defines a hyperlink
<abbr> Defines an abbreviation or an acronym
<address> Defines contact information for the author/owner of a document
<area> Defines an area inside an image map
<article> Defines an article
<aside> Defines content aside from the page content
<audio> Defines embedded sound content
<b> Defines bold text
<base> Specifies the base URL/target for all relative URLs in a document
<bdi> Isolates a part of text that might be formatted in a different direction from other text outside it
<bdo> Overrides the current text direction
<blockquote> Defines a section that is quoted from another source
<body> Defines the document’s body
<br> Defines a single line break
<button> Defines a clickable button
<canvas> Used to draw graphics, on the fly, via scripting (usually JavaScript)
<caption> Defines a table caption
<cite> Defines the title of a work
<code> Defines a piece of computer code
<col> Specifies column properties for each column within a <colgroup> element
<colgroup> Specifies a group of one or more columns in a table for formatting
<data> Adds a machine-readable translation of a given content
<datalist> Specifies a list of pre-defined options for input controls
<dd> Defines a description/value of a term in a description list
<del> Defines text that has been deleted from a document
<details> Defines additional details that the user can view or hide
<dfn> Specifies a term that is going to be defined within the content
<dialog> Defines a dialog box or window
<div> Defines a section in a document
<dl> Defines a description list
<dt> Defines a term/name in a description list
<em> Defines emphasized text
<embed> Defines a container for an external application
<fieldset> Groups related elements in a form
<figcaption> Defines a caption for a <figure> element
<figure> Specifies self-contained content
<footer> Defines a footer for a document or section
<form> Defines an HTML form for user input
<h1> to <h6> Defines HTML headings
<head> Contains metadata/information for the document
<header> Defines a header for a document or section
<hgroup> Defines a header and related content
<hr> Defines a thematic change in the content
<html> Defines the root of an HTML document
<i> Defines a part of text in an alternate voice or mood
<iframe> Defines an inline frame
<img> Defines an image
<input> Defines an input control
<ins> Defines a text that has been inserted into a document
<kbd> Defines keyboard input
<label> Defines a label for an <input> element
<legend> Defines a caption for a <fieldset> element
<li> Defines a list item
<link> Defines the relationship between a document and an external resource (most used to link to style sheets)
<main> Specifies the main content of a document
<map> Defines an image map
<mark> Defines marked/highlighted text
<menu> Defines an unordered list
<meta> Defines metadata about an HTML document
<meter> Defines a scalar measurement within a known range (a gauge)
<nav> Defines navigation links
<noscript> Defines an alternate content for users that do not support client-side scripts
<object> Defines a container for an external application
<ol> Defines an ordered list
<optgroup> Defines a group of related options in a drop-down list
<option> Defines an option in a drop-down list
<output> Defines the result of a calculation
<p> Defines a paragraph
<param> Defines a parameter for an object
<picture> Defines a container for multiple image resources
<pre> Defines preformatted text
<progress> Represents the progress of a task
<q> Defines a short quotation
<rp> Defines what to show in browsers that do not support ruby annotations
<rt> Defines an explanation/pronunciation of characters (for East Asian typography)
<ruby> Defines a ruby annotation (for East Asian typography)
<s> Defines text that is no longer correct
<samp> Defines sample output from a computer program
<script> Defines a client-side script
<search> Defines a search section
<section> Defines a section in a document
<select> Defines a drop-down list
<small> Defines smaller text
<source> Defines multiple media resources for media elements (<video> and <audio>)
<span> Defines a section in a document
<strong> Defines important text
<style> Defines style information for a document
<sub> Defines subscripted text
<summary> Defines a visible heading for a <details> element
<sup> Defines superscripted text
<svg> Defines a container for SVG graphics
<table> Defines a table
<tbody> Groups the body content in a table
<td> Defines a cell in a table
<template> Defines a container for content that should be hidden when the page loads
<textarea> Defines a multiline input control (text area)
<tfoot> Groups the footer content in a table
<th> Defines a header cell in a table
<thead> Groups the header content in a table
<time> Defines a specific time (or datetime)
<title> Defines a title for the document
<tr> Defines a row in a table
<track> Defines text tracks for media elements (<video> and <audio>)
<u> Defines some text that is unarticulated and styled differently from normal text
<ul> Defines an unordered list
<var> Defines a variable
<video> Defines embedded video content
<wbr> Defines a possible line-break

NO soportadas en HTML5:

Tag Descripción
<acronym> Not supported in HTML5. Use <abbr> instead. Defines an acronym
<applet> Not supported in HTML5. Use <embed> or <object> instead. Defines an embedded applet
<basefont> Not supported in HTML5. Use CSS instead. Specifies a default color, size, and font for all text in a document
<big> Not supported in HTML5. Use CSS instead. Defines big text
<center> Not supported in HTML5. Use CSS instead. Defines centered text
<dir> Not supported in HTML5. Use <ul> instead. Defines a directory list
<font> Not supported in HTML5. Use CSS instead. Defines font, color, and size for text
<frame> Not supported in HTML5. Defines a window (a frame) in a frameset
<frameset> Not supported in HTML5. Defines a set of frames
<noframes> Not supported in HTML5. Defines an alternate content for users that do not support frames
<strike> Not supported in HTML5. Use <del> or <s> instead. Defines strikethrough text
<tt> Not supported in HTML5. Use CSS instead. Defines teletype text