Imágenes en la web: la etiqueta img, formatos, posicionamiento y fondos con CSS

Por: Artiko
htmlcssjavascriptdomfrontendimagenesimgbackground-imagesrcsetrutas-relativasaccesibilidad

Imágenes en la web: la etiqueta img, formatos, posicionamiento y fondos con CSS

En el capítulo 4 armamos tablas y aprendimos a darles estilo: bordes colapsados, encabezados fijos, filas alternadas y celdas alineadas. Todo ese contenido era texto. Ahora vamos a incorporar el otro gran tipo de contenido de la web: las imágenes.

Una imagen no es texto que el navegador dibuja con una fuente, sino un archivo externo que hay que descargar por separado. Eso cambia varias cosas a la vez: aparece el concepto de ruta, aparece el concepto de formato, aparece el peso en kilobytes, aparece el problema de qué mostrar mientras la imagen todavía no llega y aparece el problema de qué mostrar si nunca llega. Este capítulo cubre todo ese recorrido, desde la etiqueta <img> más simple hasta fondos compuestos con CSS y resolución de rutas relativas.

El índice completo del curso está en /tecnologias/superclubnet/00-indice/.

La etiqueta img: lo mínimo que funciona

El elemento <img> incrusta una imagen en el documento. Es un elemento vacío: no tiene contenido entre etiquetas y por lo tanto no lleva etiqueta de cierre. Toda su información viaja en atributos.

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Primera imagen</title>
  </head>
  <body>
    <h1>Consola en exhibición</h1>
    <img src="consola.png" alt="Consola de videojuegos de 64 bits con dos controles conectados">
  </body>
</html>

Con dos atributos ya tenemos una imagen funcional:

  • src (source, origen): la ruta del archivo de imagen. Es obligatorio; sin él no hay nada que mostrar.
  • alt (alternative text, texto alternativo): la descripción textual de la imagen. Es obligatorio en la práctica, aunque el navegador no se queje si falta.

Todo lo demás —tamaño, borde, posición, comportamiento de carga— es opcional y se controla con más atributos o con CSS.

Cómo llega realmente la imagen a la pantalla

Vale la pena entender la secuencia completa, porque explica muchos comportamientos que después parecen misteriosos: por qué la página “salta” mientras carga, por qué a veces aparece un ícono roto, por qué el texto alternativo se ve un instante.

sequenceDiagram
    participant U as Usuario
    participant N as Navegador
    participant S as Servidor
    U->>N: Escribe la URL de la pagina
    N->>S: GET /pagina.html
    S-->>N: 200 OK, cuerpo HTML
    N->>N: Parsea el HTML y construye el DOM
    N->>N: Encuentra un elemento img con src
    N->>N: Resuelve la ruta relativa contra la URL base
    N->>S: GET /consola.png
    N->>N: Sigue parseando el resto del documento
    S-->>N: 200 OK, bytes de la imagen
    N->>N: Decodifica el archivo a mapa de pixeles
    N->>N: Calcula el tamaño final y repinta
    N-->>U: Muestra la imagen en su lugar

Tres consecuencias prácticas de este diagrama:

  1. La petición de la imagen es independiente de la del HTML. Una página con veinte imágenes hace veintiún viajes al servidor como mínimo. Cada archivo cuesta latencia además de bytes.
  2. El navegador no espera la imagen para seguir leyendo el HTML. Por eso el texto aparece antes que las fotos.
  3. Hasta que la imagen no llega, el navegador no sabe cuánto mide salvo que se lo digamos nosotros. Ese es el origen del “salto” de contenido que veremos más adelante.

Los atributos del elemento img

AtributoPara qué sirveEjemplo
srcRuta del archivo de imagensrc="fotos/mapa.jpg"
altTexto alternativo, leído por lectores de pantalla y mostrado si la imagen fallaalt="Mapa del circuito"
titleTexto emergente al dejar el cursor encimatitle="Circuito Arcoíris"
widthAncho intrínseco declarado, en píxeles, sin unidadwidth="640"
heightAlto intrínseco declarado, en píxeles, sin unidadheight="360"
loadingeager carga de inmediato, lazy difiere hasta que se acerque al viewportloading="lazy"
decodingSugerencia de decodificación: sync, async o autodecoding="async"
srcsetLista de archivos alternativos con su tamaño, para pantallas distintassrcset="foto-640.jpg 640w, foto-1280.jpg 1280w"
sizesAncho que ocupará la imagen en el diseño, para elegir de srcsetsizes="(max-width: 600px) 100vw, 50vw"
referrerpolicyQué información de origen se envía al pedir la imagenreferrerpolicy="no-referrer"
crossoriginControl de peticiones entre orígenes distintoscrossorigin="anonymous"

Los atributos width y height en HTML se escriben sin unidad: width="640", nunca width="640px". En CSS es al revés: ahí sí se escribe la unidad.

alt y title no son lo mismo

Es el punto donde más gente se confunde, y la diferencia es concreta.

  • alt reemplaza a la imagen. Es lo que un lector de pantalla lee en voz alta y lo que el navegador muestra si el archivo no carga. Debe describir el contenido y la función de la imagen para alguien que no puede verla.
  • title acompaña a la imagen. Aparece como globo de ayuda al pasar el mouse. No lo ven quienes navegan con teclado ni quienes usan pantallas táctiles, así que nunca debe contener información imprescindible.
<!-- Imagen informativa: alt describe lo que aporta -->
<img
  src="podio.jpg"
  alt="Tres corredores en el podio; el primer lugar levanta un trofeo dorado"
  title="Final del campeonato 1997"
>

<!-- Imagen decorativa: alt vacío para que el lector de pantalla la ignore -->
<img src="separador-ondas.svg" alt="">

<!-- Imagen que funciona como boton: alt describe la accion, no el dibujo -->
<a href="/carrito/">
  <img src="icono-carrito.svg" alt="Ver el carrito de compras">
</a>

Reglas que conviene memorizar:

  1. Si la imagen aporta información, alt la describe.
  2. Si la imagen es puramente decorativa, alt="" (vacío, pero presente). Omitir el atributo no es lo mismo: sin alt, muchos lectores de pantalla leen el nombre del archivo, que suele ser ruido.
  3. Si la imagen es el contenido de un enlace o botón, alt describe el destino o la acción.
  4. No empieces con “imagen de” ni “foto de”: el lector de pantalla ya anuncia que es una imagen.

width, height y el salto de contenido

Cuando el navegador dibuja el texto de la página todavía no descargó las imágenes, así que reserva cero espacio para ellas. Cuando la imagen finalmente llega, el navegador la inserta y todo lo que estaba debajo se desplaza hacia abajo. Ese salto es incómodo: el usuario estaba a punto de tocar un enlace y el enlace se movió.

La solución es declarar las dimensiones en el HTML:

<img
  src="portada.jpg"
  alt="Portada del juego con el logotipo sobre un fondo azul"
  width="1200"
  height="675"
>

Con esos números el navegador calcula la relación de aspecto (1200 ÷ 675 = 16/9) y reserva la caja del tamaño correcto antes de que llegue un solo byte de la imagen. Cuando además usamos CSS fluido, la combinación correcta es esta:

img {
  max-width: 100%;   /* nunca se desborda de su contenedor */
  height: auto;      /* mantiene la proporcion original */
}

height: auto junto con los atributos width y height del HTML es la fórmula que evita el salto y a la vez permite que la imagen se encoja en pantallas chicas. Los navegadores modernos derivan un aspect-ratio implícito de esos dos atributos justamente para esto.

flowchart TD
    A["El navegador encuentra un img"] --> B{"Tiene width y height<br/>en el HTML?"}
    B -->|Si| C["Reserva la caja con<br/>la proporcion correcta"]
    B -->|No| D["Reserva altura cero"]
    C --> E["Llega la imagen"]
    D --> F["Llega la imagen"]
    E --> G["Se pinta dentro de la caja<br/>ya reservada, sin salto"]
    F --> H["La caja crece de golpe y<br/>empuja el contenido de abajo"]

Formatos de imagen: cuál usar y por qué

Elegir mal el formato es la causa número uno de páginas pesadas. Cada formato está optimizado para un tipo de contenido distinto.

FormatoExtensiónCompresiónTransparenciaAnimaciónFuerte enDébil en
JPEG.jpg, .jpegCon pérdidaNoNoFotografías, degradados suavesTexto, líneas nítidas, transparencia
PNG.pngSin pérdidaSí, con canal alfaNo (salvo APNG)Ilustraciones, capturas de pantalla, logotiposFotografías: archivo muy pesado
GIF.gifSin pérdida, 256 coloresSí, pero binariaAnimaciones cortas antiguasCalidad de color y peso
WebP.webpCon y sin pérdidaSí, con canal alfaSustituto general de JPG y PNG, 25 a 35 % más livianoHerramientas de edición muy antiguas
AVIF.avifCon y sin pérdidaSí, con canal alfaMáxima compresión, alto rango dinámicoCodificación lenta, soporte más reciente
SVG.svgVectorial, texto XMLSí, con SMIL o CSSLogotipos, íconos, diagramas: escala sin perder nitidezFotografías

Un par de precisiones que suelen faltar en las explicaciones rápidas:

  • Con pérdida significa que el algoritmo descarta información que el ojo humano nota poco. Guardar y volver a guardar un JPEG degrada la imagen cada vez, porque la pérdida se acumula.
  • Sin pérdida significa que al descomprimir se recupera exactamente el archivo original. PNG es sin pérdida, por eso una foto en PNG pesa varias veces lo que la misma foto en JPEG.
  • SVG no tiene píxeles. Es un archivo de texto que describe formas: círculos, rutas, polígonos. El navegador lo dibuja a la resolución que haga falta, así que se ve nítido en cualquier pantalla y a cualquier zoom. Un ícono SVG puede pesar menos de 1 KB.

Árbol de decisión de formato

flowchart TD
    A["Que tipo de imagen es?"] --> B{"Es un dibujo hecho<br/>de formas geometricas?"}
    B -->|Si| C["SVG"]
    B -->|No| D{"Necesita transparencia?"}
    D -->|Si| E{"Es una fotografia?"}
    D -->|No| F{"Es una fotografia?"}
    E -->|Si| G["AVIF o WebP<br/>con canal alfa"]
    E -->|No| H["PNG, o WebP<br/>sin perdida"]
    F -->|Si| I["AVIF, con WebP<br/>o JPEG de respaldo"]
    F -->|No| J["PNG o WebP<br/>sin perdida"]
    C --> K["Verificar el peso final<br/>y las dimensiones reales"]
    G --> K
    H --> K
    I --> K
    J --> K

Un mismo archivo en varios formatos: el elemento picture

Si queremos servir AVIF a quien lo soporte, WebP a quien no, y JPEG como último recurso, existe el elemento <picture>. El navegador evalúa las fuentes en orden y usa la primera que entiende.

<picture>
  <source srcset="paisaje.avif" type="image/avif">
  <source srcset="paisaje.webp" type="image/webp">
  <img
    src="paisaje.jpg"
    alt="Vista aerea de un circuito de carreras rodeado de arboles"
    width="1600"
    height="900"
  >
</picture>

Detalles importantes de <picture>:

  • El <img> interior no es opcional: es el elemento que realmente se dibuja y el que lleva alt, width y height. Los <source> solo le indican qué archivo usar.
  • Si el navegador no entiende <picture>, ignora las etiquetas desconocidas y muestra el <img>. Es degradación elegante gratuita.
  • type usa el tipo MIME del formato: image/avif, image/webp, image/jpeg, image/png, image/svg+xml.

Imágenes responsivas con srcset y sizes

Servir una imagen de 2400 píxeles de ancho a un teléfono que la muestra a 360 píxeles desperdicia datos. srcset ofrece varias versiones del mismo archivo y sizes le dice al navegador qué ancho ocupará la imagen en el diseño, para que elija la más adecuada antes de descargar nada.

<img
  src="circuito-800.jpg"
  srcset="
    circuito-400.jpg   400w,
    circuito-800.jpg   800w,
    circuito-1600.jpg 1600w
  "
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
  alt="Curva peraltada del circuito vista desde la tribuna"
  width="800"
  height="450"
>

Cómo se lee eso:

  • 400w no significa “mostrar a 400 píxeles”: es el ancho real en píxeles del archivo. Se llama descriptor de ancho.
  • sizes describe el ancho de presentación: hasta 600 píxeles de viewport la imagen ocupa el 100 % del ancho, hasta 1200 ocupa la mitad, y de ahí en adelante 600 píxeles fijos.
  • El navegador combina sizes con la densidad de la pantalla y elige el archivo del srcset que mejor cubra esa medida.
  • src sigue presente como respaldo para navegadores que ignoren srcset.

Carga diferida

<img
  src="galeria-07.jpg"
  alt="Sala de maquinas arcade con gabinetes iluminados"
  width="900"
  height="600"
  loading="lazy"
  decoding="async"
>
  • loading="lazy" pospone la descarga hasta que la imagen esté por entrar en pantalla. Ideal para galerías largas y contenido debajo del pliegue.
  • loading="eager" es el comportamiento por defecto y conviene dejarlo en las imágenes que se ven apenas carga la página, como una portada.
  • decoding="async" permite que la decodificación no bloquee el pintado del resto.

Aplicar lazy a la imagen principal de la página es contraproducente: retrasa justo la imagen que el usuario ya está mirando.

Dimensionar y recortar con CSS

Los atributos HTML declaran el tamaño intrínseco. El tamaño final en pantalla lo decide CSS.

/* Base sana para cualquier proyecto */
img {
  display: block;      /* elimina el hueco de linea base bajo la imagen */
  max-width: 100%;     /* nunca se desborda del contenedor */
  height: auto;        /* conserva la proporcion */
}

Ese display: block merece explicación. Por defecto <img> es un elemento en línea reemplazado: se comporta como una palabra dentro de un renglón y por lo tanto se apoya sobre la línea base del texto, dejando unos pocos píxeles de espacio debajo. Ese hueco fantasma es la causa de la clásica franja inexplicable bajo una imagen dentro de un contenedor con fondo. Con display: block desaparece; con vertical-align: middle también.

object-fit y object-position

Cuando forzamos un ancho y un alto que no respetan la proporción original, la imagen se deforma. object-fit controla cómo se acomoda el contenido dentro de esa caja.

/* Todas las imagenes ocupan la misma caja de 100 % por 200 px */
.galeria img {
  display: block;
  width: 100%;
  height: 200px;
}

.fill img    { object-fit: fill; }        /* estira y deforma para llenar */
.contain img { object-fit: contain; }     /* entra completa, deja bandas vacias */
.cover img   { object-fit: cover; }       /* llena la caja recortando lo que sobra */
.none img    { object-fit: none; }        /* tamano original, se recorta si no cabe */
.down img    { object-fit: scale-down; }  /* el menor entre none y contain */
ValorDeformaRecortaDeja espacio vacío
fillNoNo
containNoNo
coverNoNo
noneNo
scale-downNoNo

object-position elige qué parte se conserva cuando cover recorta:

.retrato img {
  width: 100%;
  height: 320px;
  object-fit: cover;
  object-position: 50% 20%;  /* centrado horizontal, mas arriba en vertical */
}

Es el ajuste que salva los retratos: con cover y posición centrada, el recorte suele cortar las cabezas; subir el punto de anclaje al 20 % conserva los rostros.

Posicionar imágenes en la página

El flujo natural

Una imagen sin CSS se comporta como una palabra: queda en el renglón, junto al texto que la rodea. Ese es el punto de partida sobre el que actúan todas las técnicas siguientes.

float y clear

float saca la imagen del flujo normal y la empuja a un costado, permitiendo que el texto la envuelva. Es la técnica clásica de las revistas.

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Flotado de imágenes</title>
    <style>
      body {
        font-family: Georgia, "Times New Roman", serif;
        background-color: #0f1115;
        color: #e8eaed;
        max-width: 760px;
        margin: 0 auto;
        padding: 24px;
        line-height: 1.7;
      }

      img {
        max-width: 100%;
        height: auto;
        border-radius: 8px;
      }

      .izquierda {
        float: left;
        width: 40%;
        margin: 0 20px 12px 0;
      }

      .derecha {
        float: right;
        width: 40%;
        margin: 0 0 12px 20px;
      }

      /* Corta el flotado: el contenido siguiente vuelve a empezar abajo */
      .limpiar {
        clear: both;
      }

      /* Centrado real: no se hace con float */
      .centrada {
        display: block;
        margin-left: auto;
        margin-right: auto;
        width: 60%;
      }
    </style>
  </head>
  <body>
    <h1>Imágenes flotadas y centradas</h1>

    <img
      class="izquierda"
      src="mapa.jpg"
      alt="Mapa del circuito con las curvas numeradas"
      width="800"
      height="600"
    >
    <p>
      Este párrafo envuelve la imagen que está flotada a la izquierda. El texto
      ocupa el espacio libre a la derecha de la imagen y baja línea por línea
      hasta superar su altura, momento en el que recupera todo el ancho.
    </p>

    <div class="limpiar"></div>

    <img
      class="derecha"
      src="mapa.jpg"
      alt="Mapa del circuito con las curvas numeradas"
      width="800"
      height="600"
    >
    <p>
      Este otro párrafo envuelve la imagen flotada a la derecha. La lógica es
      idéntica, solo cambia el lado hacia el que se empuja la imagen y, en
      consecuencia, el margen que hay que dejar para que el texto no quede pegado.
    </p>

    <div class="limpiar"></div>

    <img
      class="centrada"
      src="mapa.jpg"
      alt="Mapa del circuito con las curvas numeradas"
      width="800"
      height="600"
    >
    <p>
      La imagen de arriba está centrada. No usa float, porque float no tiene un
      valor de centrado: se convierte en bloque y se le dan márgenes automáticos
      a ambos lados.
    </p>
  </body>
</html>

Los valores válidos de float son left, right, none, inline-start e inline-end. No existe float: center. Si lo escribes, el navegador descarta la declaración por inválida y la imagen se queda donde estaba, lo que da la impresión de que “el centrado no funciona”. Para centrar hay tres caminos claros:

/* 1. Bloque con margenes automaticos */
.centrada {
  display: block;
  margin-inline: auto;
}

/* 2. El contenedor centra el contenido en linea */
.contenedor {
  text-align: center;
}

/* 3. Flexbox: centrado horizontal y vertical */
.contenedor-flex {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 320px;
}

clear es el complemento de float: obliga a un elemento a colocarse por debajo de los elementos flotados previos. Sus valores son left, right, both y none. La técnica moderna evita el <div class="limpiar"> usando un contenedor que se contiene a sí mismo:

.articulo {
  display: flow-root;  /* el contenedor abarca a sus hijos flotados */
}

display: flow-root crea un contexto de formato de bloque nuevo, así que el contenedor “envuelve” a los elementos flotados sin necesidad de elementos extra ni del truco del pseudoelemento.

flowchart LR
    A["Imagen en el flujo"] --> B{"Que necesito?"}
    B -->|"Texto que la envuelva"| C["float: left o right<br/>mas margin del lado del texto"]
    B -->|"Centrada, sola en su linea"| D["display: block<br/>mas margin-inline: auto"]
    B -->|"Alineada con otros elementos"| E["display: flex en el padre<br/>mas justify-content"]
    B -->|"Rejilla de varias imagenes"| F["display: grid en el padre<br/>mas grid-template-columns"]
    C --> G["Cerrar con clear: both<br/>o display: flow-root en el padre"]

Galería con flexbox y con grid

Para colecciones de imágenes, las herramientas actuales son mucho más directas que float.

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Galería flexible</title>
    <style>
      body {
        font-family: system-ui, sans-serif;
        background-color: #0d1117;
        color: #e6edf3;
        margin: 0;
        padding: 24px;
      }

      .tira {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
        justify-content: center;
      }

      .tira img {
        flex: 0 1 200px;
        height: 140px;
        object-fit: cover;
        border-radius: 8px;
      }

      .rejilla {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
        gap: 12px;
        margin-top: 32px;
      }

      .rejilla img {
        width: 100%;
        height: 160px;
        object-fit: cover;
        border-radius: 8px;
      }

      .rejilla img:first-child {
        grid-column: span 2;
        grid-row: span 2;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <h1>Dos maneras de acomodar imágenes</h1>

    <div class="tira">
      <img src="p1.jpg" alt="Curva 1 del circuito" width="600" height="400">
      <img src="p2.jpg" alt="Recta principal" width="600" height="400">
      <img src="p3.jpg" alt="Zona de boxes" width="600" height="400">
      <img src="p4.jpg" alt="Tribuna central" width="600" height="400">
    </div>

    <div class="rejilla">
      <img src="p1.jpg" alt="Curva 1 del circuito" width="600" height="400">
      <img src="p2.jpg" alt="Recta principal" width="600" height="400">
      <img src="p3.jpg" alt="Zona de boxes" width="600" height="400">
      <img src="p4.jpg" alt="Tribuna central" width="600" height="400">
      <img src="p5.jpg" alt="Vista nocturna del circuito" width="600" height="400">
    </div>
  </body>
</html>

repeat(auto-fill, minmax(180px, 1fr)) es una de las expresiones más útiles de CSS Grid: crea tantas columnas como quepan, cada una de al menos 180 píxeles, repartiendo el sobrante en partes iguales. La galería se adapta sola sin escribir una sola media query.

Imágenes de fondo con CSS

Una imagen de fondo no es contenido del documento: es decoración de una caja. Se declara con background-image y se controla con una familia de propiedades relacionadas.

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fondos con CSS</title>
    <style>
      body {
        margin: 0;
        font-family: system-ui, sans-serif;
        color: #ffffff;
        background-color: #05070a;
      }

      .portada {
        min-height: 70vh;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        text-align: center;
        padding: 32px;

        background-image: url("imagenes/portada.jpg");
        background-repeat: no-repeat;
        background-position: center center;
        background-size: cover;
        background-color: #1b2430;  /* se ve mientras la imagen carga */
      }

      .patron {
        min-height: 40vh;
        padding: 32px;
        background-image: url("imagenes/textura.png");
        background-repeat: repeat;
        background-size: 160px auto;
      }

      .franja-fija {
        min-height: 60vh;
        padding: 32px;
        background-image: url("imagenes/montanas.jpg");
        background-repeat: no-repeat;
        background-size: cover;
        background-attachment: fixed;
      }
    </style>
  </head>
  <body>
    <header class="portada">
      <h1>Super Club Net</h1>
      <p>Todo lo que ves aquí atrás es una imagen de fondo.</p>
    </header>

    <section class="patron">
      <h2>Patrón repetido</h2>
      <p>La textura se repite en mosaico hasta cubrir toda la sección.</p>
    </section>

    <section class="franja-fija">
      <h2>Fondo fijo</h2>
      <p>Al desplazar la página, esta imagen se queda quieta.</p>
    </section>
  </body>
</html>

Las propiedades de fondo, una por una

PropiedadValores frecuentesQué hace
background-imageurl("ruta.jpg"), linear-gradient(...), noneDefine la imagen o el degradado de fondo
background-repeatrepeat, no-repeat, repeat-x, repeat-y, space, roundControla la repetición en mosaico
background-sizeauto, cover, contain, 320px auto, 50% 100%Escala la imagen dentro de la caja
background-positioncenter, top left, 50% 20%, right 20px bottom 10pxUbica el punto de anclaje de la imagen
background-attachmentscroll, fixed, localDecide si el fondo se desplaza con la página
background-colorCualquier colorColor sólido detrás de la imagen
background-clipborder-box, padding-box, content-box, textHasta dónde se pinta el fondo
background-originborder-box, padding-box, content-boxDesde dónde se posiciona la imagen
background-blend-modemultiply, overlay, screen, normalCómo se mezclan las capas de fondo entre sí

Dos valores merecen aclaración porque se confunden todo el tiempo:

  • cover escala la imagen hasta cubrir toda la caja, aunque para lograrlo tenga que recortar los bordes. Nunca quedan huecos.
  • contain escala la imagen hasta que entre completa en la caja. Nunca recorta, pero puede dejar espacio vacío a los costados o arriba y abajo.

Es exactamente la misma distinción que en object-fit, aplicada a fondos en lugar de a elementos <img>.

La forma abreviada

Todas esas propiedades tienen una forma corta:

.portada {
  background: #1b2430 url("imagenes/portada.jpg") no-repeat center / cover;
}

El orden dentro de la abreviatura es flexible, salvo por una regla: background-size va después de background-position y separado por una barra. Escribir center / cover sin la barra invalida toda la declaración.

Otra advertencia: la forma abreviada reinicia a su valor inicial todas las propiedades de fondo que no menciones. Si antes habías puesto background-attachment: fixed y luego declaras un background corto sin ese valor, el fixed desaparece.

Varias capas de fondo

background-image acepta una lista separada por comas. La primera capa queda arriba y las siguientes se apilan debajo.

.encabezado {
  min-height: 60vh;
  background-image:
    linear-gradient(to bottom, rgba(5, 7, 10, 0.15), rgba(5, 7, 10, 0.85)),
    url("imagenes/circuito.jpg");
  background-repeat: no-repeat, no-repeat;
  background-position: center, center;
  background-size: cover, cover;
}

Ese degradado oscuro encima de la fotografía es la técnica estándar para que el texto blanco de una portada sea legible sin importar cómo sea la imagen. Nota que las demás propiedades también aceptan listas, y cada valor corresponde por posición a la capa del mismo índice.

Fondos sin archivo: degradados y patrones

CSS puede generar imágenes de fondo sin descargar nada:

.degradado-lineal {
  background-image: linear-gradient(135deg, #1f6feb, #8957e5);
}

.degradado-radial {
  background-image: radial-gradient(circle at 30% 30%, #f0b429, #7b3f00);
}

.degradado-conico {
  background-image: conic-gradient(from 45deg, #e11d48, #f59e0b, #10b981, #e11d48);
}

/* Patron de rayas hecho solo con CSS */
.rayas {
  background-image: repeating-linear-gradient(
    45deg,
    #1b222b 0 12px,
    #232c38 12px 24px
  );
}

Cero peticiones al servidor, cero kilobytes de imagen y escalado perfecto a cualquier tamaño. Para separadores, tramas y fondos sutiles es la opción más eficiente.

img frente a background-image: cuándo usar cada uno

Criterio<img>background-image
NaturalezaContenido del documentoDecoración de una caja
Aparece en el DOMSí, es un elementoNo, es una propiedad de estilo
Texto alternativoSí, con altNo existe equivalente
Lectores de pantallaLa anuncian y describenLa ignoran por completo
Imprimible por defectoMuchos navegadores la omiten
Imágenes responsivassrcset, sizes, <picture>Media queries o image-set()
Recorte y encuadreobject-fit, object-positionbackground-size, background-position
Varias capas superpuestasRequiere posicionamiento manualNativo, con lista separada por comas
Se puede enlazar directoSí, dentro de un <a>No

La regla práctica: si al quitar la imagen se pierde información, va en <img>; si solo se pierde estética, va en background-image. Una fotografía de producto es contenido. Una textura de papel detrás del texto es decoración.

Rutas: relativas frente a absolutas

Todo lo anterior depende de que el navegador encuentre el archivo. La ruta es la instrucción que le damos para lograrlo, y es donde más tiempo se pierde cuando algo no se ve.

Supongamos esta estructura de carpetas del proyecto:

flowchart TD
    R["proyecto/"] --> I["index.html"]
    R --> C["css/"]
    R --> IMG["imagenes/"]
    R --> B["blog/"]
    C --> E["estilos.css"]
    IMG --> L["logo.png"]
    IMG --> F["fondo.jpg"]
    IMG --> IC["iconos/"]
    IC --> M["menu.svg"]
    B --> A1["articulo.html"]
    B --> BI["imagenes/"]
    BI --> G["grafico.png"]

Rutas relativas

Una ruta relativa se resuelve tomando como punto de partida la ubicación del archivo que la contiene. Los símbolos son estos:

NotaciónSignificadoEjemplo desde index.html
archivo.pngMismo directorioindex.html y archivo.png están juntos
./archivo.pngMismo directorio, explícitoEquivale al anterior
carpeta/archivo.pngBajar un nivelimagenes/logo.png
carpeta/sub/archivo.pngBajar dos nivelesimagenes/iconos/menu.svg
../archivo.pngSubir un nivelDesde blog/articulo.html, sube a la raíz
../../archivo.pngSubir dos nivelesSe pueden encadenar sin límite

Desde index.html (que está en la raíz del proyecto):

<img src="imagenes/logo.png" alt="Logotipo del club">
<img src="imagenes/iconos/menu.svg" alt="Abrir el menú">
<img src="blog/imagenes/grafico.png" alt="Gráfico de resultados">

Desde blog/articulo.html:

<!-- Subir un nivel y entrar a imagenes -->
<img src="../imagenes/logo.png" alt="Logotipo del club">

<!-- La carpeta imagenes que esta dentro de blog -->
<img src="imagenes/grafico.png" alt="Gráfico de resultados">

Fíjate en el detalle: imagenes/grafico.png escrito desde blog/articulo.html apunta a blog/imagenes/, no a la carpeta imagenes/ de la raíz. La misma cadena de texto significa archivos distintos según desde dónde se escriba. Esa es la esencia de “relativa”.

Rutas absolutas desde la raíz del sitio

Una ruta que empieza con una barra / no se resuelve contra el archivo actual, sino contra la raíz del sitio: el dominio.

<!-- Funciona igual desde cualquier archivo del sitio -->
<img src="/imagenes/logo.png" alt="Logotipo del club">

Si el sitio está en https://ejemplo.cl, esa ruta apunta a https://ejemplo.cl/imagenes/logo.png sin importar si la escribimos en index.html, en blog/articulo.html o en un archivo diez niveles más adentro. Es la opción más robusta para elementos compartidos como logotipos e íconos.

La contrapartida: al abrir el archivo HTML directamente desde el disco con doble clic (protocolo file://), la barra inicial apunta a la raíz del sistema de archivos, no a la carpeta del proyecto, y las imágenes no aparecen. Por eso conviene probar siempre con un servidor local en lugar de abrir el archivo a mano.

URLs absolutas completas

<img src="https://ejemplo.cl/imagenes/logo.png" alt="Logotipo del club">

Incluyen el esquema (https://) y el dominio. Se usan para imágenes alojadas en otro servidor. Traen dos consideraciones: dependes de la disponibilidad de ese servidor, y si el recurso desaparece o cambia, tu página se rompe sin que hayas tocado nada.

Rutas del sistema de archivos

<img src="/home/usuario/fotos/imagen.jpg" alt="Solo funciona en esta máquina">

Apuntar a una carpeta personal del disco funciona en la computadora donde se escribió y falla en cualquier otra. Es un error frecuente cuando se arrastra una imagen desde el explorador de archivos al editor.

El punto que casi nadie explica: rutas dentro de CSS

Esta es la trampa más común de todo el capítulo. Una ruta relativa dentro de un archivo .css se resuelve contra la ubicación del archivo CSS, no contra la del HTML.

Con la estructura del diagrama anterior, en css/estilos.css esto es correcto:

.portada {
  background-image: url("../imagenes/fondo.jpg");
}

El ../ sube desde css/ hasta la raíz del proyecto y desde ahí entra a imagenes/. Si en cambio escribieras url("imagenes/fondo.jpg"), el navegador buscaría css/imagenes/fondo.jpg, que no existe.

Y si ese mismo CSS estuviera escrito dentro de una etiqueta <style> en index.html, la ruta correcta pasaría a ser url("imagenes/fondo.jpg"), porque ahora el punto de partida es el HTML. La misma declaración, dos rutas distintas según dónde viva.

flowchart TD
    A["url( ... ) dentro de un estilo"] --> B{"Donde esta escrito<br/>ese estilo?"}
    B -->|"En un archivo .css externo"| C["La base es la carpeta<br/>del archivo .css"]
    B -->|"En una etiqueta style del HTML"| D["La base es la carpeta<br/>del documento HTML"]
    B -->|"En un atributo style de un elemento"| D
    C --> E["css/estilos.css necesita<br/>subir con ../ para llegar<br/>a imagenes/"]
    D --> F["index.html llega directo<br/>con imagenes/"]
    E --> G["Si la ruta empieza con /<br/>la base es siempre el dominio"]
    F --> G

Las rutas que empiezan con / esquivan todo este problema, porque siempre se resuelven contra el dominio sin importar dónde estén escritas.

La etiqueta base

Existe un elemento que cambia el punto de partida de todas las rutas relativas del documento:

<head>
  <base href="https://cdn.ejemplo.cl/assets/">
</head>

Con eso, un <img src="logo.png"> en cualquier parte del documento apunta a https://cdn.ejemplo.cl/assets/logo.png. Es una herramienta potente y a la vez peligrosa: afecta también a los enlaces <a href>, así que un <base> mal puesto rompe la navegación completa de la página. Solo debe haber uno y debe ir antes de cualquier otra referencia a un recurso.

data URI: la imagen dentro del documento

Una URL data: incrusta el contenido del archivo directamente en el atributo, codificado normalmente en base64.

<!-- Un cuadrado rojo de 1x1 pixel, en PNG, embebido -->
<img
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
  alt="Cuadrado rojo de un pixel"
  width="1"
  height="1"
>

También funciona en CSS, y con SVG queda especialmente legible porque no hace falta codificar en base64:

.check {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M2 8l4 4 8-8" stroke="%2310b981" stroke-width="2" fill="none"/></svg>');
  background-repeat: no-repeat;
  background-size: 16px 16px;
  padding-left: 22px;
}

Dentro de un data: URI de SVG, el carácter # debe escribirse como %23; por eso el color aparece como %2310b981 en lugar de #10b981.

La estructura de un data URI es: data: + tipo MIME + ;base64 (si corresponde) + , + los datos.

VentajaCosto
Cero peticiones adicionales al servidorBase64 infla el tamaño alrededor de un 33 %
El documento es autocontenidoNo se puede cachear por separado
Útil para íconos diminutos y marcadoresIlegible en el código fuente
Evita el parpadeo inicial de íconosAumenta el peso del HTML o del CSS

La recomendación práctica: reservarlo para archivos de menos de un par de kilobytes.

Ejemplo integrador: la página del club

Un documento completo que reúne casi todo lo visto: portada con fondo compuesto, logotipo con ruta relativa, galería en rejilla con object-fit, imagen flotada con texto envolvente y carga diferida.

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Super Club Net — Galería</title>
    <style>
      :root {
        --fondo: #0b0f14;
        --superficie: #141b24;
        --texto: #e8edf3;
        --tenue: #93a4b8;
        --acento: #38bdf8;
      }

      * {
        box-sizing: border-box;
      }

      body {
        margin: 0;
        font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
        background-color: var(--fondo);
        color: var(--texto);
        line-height: 1.7;
      }

      img {
        display: block;
        max-width: 100%;
        height: auto;
      }

      .portada {
        min-height: 65vh;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        text-align: center;
        padding: 40px 24px;
        background-color: #101720;
        background-image:
          linear-gradient(to bottom, rgba(11, 15, 20, 0.25), rgba(11, 15, 20, 0.9)),
          url("imagenes/circuito.jpg");
        background-repeat: no-repeat, no-repeat;
        background-position: center, center 30%;
        background-size: cover, cover;
      }

      .portada img.logo {
        width: 96px;
        height: 96px;
        margin-bottom: 16px;
      }

      .portada h1 {
        font-size: clamp(2rem, 6vw, 3.5rem);
        margin: 0 0 8px;
      }

      .portada p {
        margin: 0;
        color: var(--tenue);
        max-width: 46ch;
      }

      main {
        max-width: 960px;
        margin: 0 auto;
        padding: 48px 24px;
      }

      section {
        margin-bottom: 56px;
        display: flow-root;
      }

      h2 {
        border-bottom: 2px solid var(--acento);
        padding-bottom: 8px;
      }

      .destacada {
        float: left;
        width: 42%;
        margin: 6px 24px 12px 0;
        border-radius: 10px;
      }

      .rejilla {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        gap: 14px;
      }

      .rejilla figure {
        margin: 0;
        background-color: var(--superficie);
        border-radius: 10px;
        overflow: hidden;
      }

      .rejilla img {
        width: 100%;
        height: 150px;
        object-fit: cover;
        object-position: center 40%;
      }

      .rejilla figcaption {
        padding: 10px 12px;
        font-size: 0.88rem;
        color: var(--tenue);
      }

      .cinta {
        min-height: 220px;
        border-radius: 12px;
        background-image: repeating-linear-gradient(
          45deg,
          rgba(56, 189, 248, 0.10) 0 14px,
          rgba(56, 189, 248, 0.02) 14px 28px
        );
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 24px;
        text-align: center;
        color: var(--tenue);
      }

      @media (max-width: 620px) {
        .destacada {
          float: none;
          width: 100%;
          margin: 0 0 16px 0;
        }
      }
    </style>
  </head>
  <body>
    <header class="portada">
      <img class="logo" src="imagenes/logo.svg" alt="" width="96" height="96">
      <h1>Super Club Net</h1>
      <p>Archivo fotográfico del circuito, temporada tras temporada.</p>
    </header>

    <main>
      <section>
        <h2>La curva peraltada</h2>
        <img
          class="destacada"
          src="imagenes/peralte.jpg"
          alt="Auto tomando la curva peraltada con el peralte inclinado hacia el interior"
          width="900"
          height="600"
        >
        <p>
          El peralte de esta curva permite mantener velocidad sin depender por
          completo del agarre lateral de los neumáticos. Es el punto donde más
          diferencias se generan durante la vuelta rápida y, por lo mismo, el
          lugar favorito de los fotógrafos.
        </p>
        <p>
          La imagen está flotada a la izquierda y el texto la envuelve. En
          pantallas angostas la media query cancela el flotado y la imagen pasa
          a ocupar todo el ancho, porque envolver texto alrededor de una imagen
          en un teléfono deja columnas de dos o tres palabras.
        </p>
      </section>

      <section>
        <h2>Galería de la temporada</h2>
        <div class="rejilla">
          <figure>
            <img src="imagenes/g1.jpg" alt="Largada con los autos alineados en la grilla"
                 width="600" height="400" loading="lazy" decoding="async">
            <figcaption>Largada</figcaption>
          </figure>
          <figure>
            <img src="imagenes/g2.jpg" alt="Detención en boxes con el equipo cambiando neumáticos"
                 width="600" height="400" loading="lazy" decoding="async">
            <figcaption>Boxes</figcaption>
          </figure>
          <figure>
            <img src="imagenes/g3.jpg" alt="Vista nocturna del circuito con las luces encendidas"
                 width="600" height="400" loading="lazy" decoding="async">
            <figcaption>Nocturna</figcaption>
          </figure>
          <figure>
            <img src="imagenes/g4.jpg" alt="Público en la tribuna principal ondeando banderas"
                 width="600" height="400" loading="lazy" decoding="async">
            <figcaption>Tribuna</figcaption>
          </figure>
        </div>
      </section>

      <section>
        <h2>Fondo generado con CSS</h2>
        <div class="cinta">
          <p>Estas rayas diagonales no son un archivo: las dibuja repeating-linear-gradient.</p>
        </div>
      </section>
    </main>
  </body>
</html>

Nota que el logotipo lleva alt="". El nombre del club ya está en el <h1> justo debajo, así que repetirlo en el texto alternativo haría que un lector de pantalla lo anunciara dos veces seguidas.

Errores comunes

ErrorCausaSolución
La imagen no aparece y sale el ícono rotoLa ruta en src no coincide con la ubicación real del archivoAbrir la pestaña de red de las herramientas del navegador, ver la URL exacta que se pidió y compararla con el árbol de carpetas
Funciona en tu máquina pero no al publicarDiferencia de mayúsculas: Logo.PNG frente a logo.pngLos servidores Linux distinguen mayúsculas; usar siempre nombres en minúsculas y sin espacios
El fondo no carga desde el CSS externoLa ruta en url() se resolvió contra la carpeta del .css, no del HTMLAjustar con ../ o usar una ruta absoluta que empiece con /
float: center no centra nadaEse valor no existe en la especificación de floatUsar display: block con margin-inline: auto, o text-align: center en el contenedor
El contenedor no crece con la imagen flotada dentroLos elementos flotados salen del flujo y no aportan altura al padreAñadir display: flow-root al contenedor, o un elemento con clear: both al final
La imagen se ve estirada o achatadaSe fijaron width y height con una proporción distinta a la originalUsar object-fit: cover o fijar solo una dimensión y dejar la otra en auto
Hay una franja de píxeles bajo la imagen<img> es un elemento en línea y se apoya en la línea base del textoAñadir display: block o vertical-align: middle
La página salta mientras cargaEl navegador no reservó espacio porque no conocía el tamañoDeclarar width y height en el HTML y height: auto en CSS
El texto queda pegado a la imagen flotadaEl flotado no aplica separación por sí mismoAgregar margin del lado por donde corre el texto
El logotipo se ve borroso en pantallas de alta densidadSe sirve un archivo con menos píxeles reales de los que la pantalla dibujaUsar SVG para logotipos e íconos, o srcset con versiones de mayor resolución
La foto pesa varios megabytesSe subió el archivo original de la cámara sin procesarRedimensionar a las dimensiones de uso y convertir a WebP o AVIF
Un lector de pantalla lee el nombre del archivoFalta el atributo altEscribir una descripción, o alt="" si la imagen es decorativa
Las imágenes de fondo no salen al imprimirMuchos navegadores omiten los fondos en la impresiónSi el contenido debe imprimirse, usar <img> en lugar de background-image
El background corto borró el attachment que había puesto antesLa forma abreviada reinicia todas las propiedades no mencionadasIncluir todos los valores en la abreviatura o usar propiedades individuales
background: center cover no aplica el tamañoFalta la barra que separa posición de tamañoEscribir center / cover
El SVG del data: URI no se veEl # del color rompe la URLReemplazar # por %23 dentro del data URI

Herramientas del navegador para depurar imágenes

Cuando algo no aparece, tres pestañas de las herramientas de desarrollo resuelven casi todo:

  1. Red (Network): filtra por imágenes y muestra la URL exacta que el navegador pidió, el código de estado y el peso. Un 404 confirma que la ruta está mal; un archivo de 4 MB confirma que hay que optimizar.
  2. Elementos (Elements): al seleccionar el <img> muestra sus dimensiones renderizadas y las dimensiones intrínsecas del archivo. Si el archivo mide 3000 píxeles y se muestra a 300, sobran datos descargados.
  3. Consola: registra los errores de carga de recursos.

También se puede detectar por código cuando una imagen falla:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <title>Detectar imágenes rotas</title>
  </head>
  <body>
    <img id="foto" src="imagenes/no-existe.jpg" alt="Fotografía del circuito" width="600" height="400">
    <p id="aviso"></p>

    <script>
      const foto = document.getElementById("foto");
      const aviso = document.getElementById("aviso");

      foto.addEventListener("error", function () {
        aviso.textContent = "No se pudo cargar: " + foto.getAttribute("src");
        foto.src = "imagenes/reemplazo.png";
      });

      foto.addEventListener("load", function () {
        aviso.textContent =
          "Cargada. Tamaño real: " +
          foto.naturalWidth + " por " + foto.naturalHeight + " píxeles.";
      });
    </script>
  </body>
</html>

Las propiedades naturalWidth y naturalHeight entregan las dimensiones reales del archivo, mientras que width y height (leídas desde JavaScript) entregan las dimensiones con las que se está mostrando. Comparar ambas es la forma más directa de descubrir imágenes sobredimensionadas. El evento error solo se dispara una vez por asignación de src; si la imagen de reemplazo también falla, el manejador se ejecutará de nuevo, así que conviene evitar un reemplazo que pueda entrar en bucle.

Buenas prácticas de rendimiento

PrácticaEfecto
Servir la imagen a las dimensiones reales de usoEvita descargar píxeles que nunca se ven
Convertir a WebP o AVIF con respaldoReduce entre un 25 % y un 50 % el peso
Usar SVG para logotipos, íconos y diagramasArchivos diminutos y nitidez en cualquier pantalla
Declarar width y height en el HTMLElimina el salto de contenido durante la carga
loading="lazy" fuera del área visible inicialAhorra descargas que quizá nunca se necesiten
No aplicar lazy a la imagen principalEvita retrasar justo lo que el usuario ya está viendo
Degradados y patrones con CSS en vez de archivosCero peticiones y escalado perfecto
Nombres de archivo en minúsculas, sin espacios ni tildesEvita fallos al publicar en servidores Linux
Un background-color de respaldo bajo cada fondoMantiene legible el texto mientras la imagen carga

Ejercicios propuestos

  1. Ficha de producto. Crea una página con una imagen de producto de 800 por 800 píxeles. Declara width y height en el HTML, aplica max-width: 100% y height: auto en CSS, y escribe un alt que describa el producto para alguien que no puede verlo. Verifica en la pestaña de red que la imagen se descarga una sola vez.

  2. Comparador de object-fit. Toma una fotografía apaisada y muéstrala cinco veces dentro de cajas cuadradas de 240 por 240 píxeles, aplicando cada uno de los cinco valores de object-fit. Añade un <figcaption> que explique lo que ocurre en cada caso.

  3. Artículo con imagen flotada. Escribe un artículo de al menos cuatro párrafos con una imagen flotada a la izquierda. Usa display: flow-root en el contenedor y comprueba que el borde inferior del contenedor queda por debajo de la imagen. Luego agrega una media query que cancele el flotado bajo los 600 píxeles de ancho.

  4. Portada con fondo compuesto. Construye un encabezado de altura 70vh con dos capas de fondo: un degradado oscuro encima y una fotografía debajo. Ajusta background-position para que el punto de interés de la foto quede visible tanto en pantalla ancha como angosta.

  5. Rutas cruzadas. Reproduce la estructura de carpetas del diagrama de este capítulo con archivos reales. Desde blog/articulo.html, muestra el logotipo que está en la carpeta imagenes/ de la raíz usando primero una ruta relativa y después una absoluta. Comprueba que ambas funcionan al servir el sitio y observa qué pasa al abrir el archivo con doble clic.

  6. La trampa del CSS externo. Mueve todos los estilos del ejercicio 4 a css/estilos.css sin cambiar la ruta del url(). Observa cómo el fondo desaparece, revisa la URL fallida en la pestaña de red y corrígela. Escribe en un comentario por qué la ruta anterior dejó de funcionar.

  7. Galería adaptable. Arma una galería de ocho imágenes con grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)), object-fit: cover y loading="lazy" en todas menos las dos primeras. Redimensiona la ventana y observa cómo cambia el número de columnas sin escribir media queries.

  8. Tres formatos, un mismo dibujo. Guarda un mismo logotipo en PNG, en WebP y en SVG. Anota el peso de cada archivo, muéstralos lado a lado a 400 píxeles de ancho y luego a 40 píxeles, y describe qué diferencias de nitidez aparecen.

  9. Ícono embebido. Crea un data: URI con un SVG sencillo (un círculo o una marca de verificación) y úsalo como background-image de un botón. Recuerda codificar el # de los colores como %23.

  10. Auditoría de una página propia. Toma cualquier página que ya hayas hecho en este curso y revisa cada imagen: ¿tiene alt?, ¿tiene width y height?, ¿el archivo pesa lo razonable?, ¿el formato es el adecuado para su contenido? Corrige lo que falte y anota el peso total antes y después.

Lo que viene

Ya podemos incrustar imágenes, elegir su formato, ubicarlas en la página, usarlas como fondo y apuntar correctamente a sus archivos. Ese último punto —la resolución de rutas— no era exclusivo de las imágenes: es el mismo mecanismo que gobierna hojas de estilo, scripts, videos y, sobre todo, enlaces.

En el capítulo 6 vamos a desarmar ese mecanismo pieza por pieza: qué es una URI y en qué se diferencia de una URL, cuáles son las partes de una dirección web (esquema, host, puerto, ruta, cadena de consulta y fragmento), cómo funcionan los enlaces internos hacia anclas de la misma página, cómo enlazar a correo o a teléfono, y qué hacen los atributos target y rel cuando abrimos un enlace en otra pestaña. El elemento <a> es el que convirtió a la web en una red, y le vamos a dedicar el capítulo completo.