0Apoyar

Scroll snap en CSS

Explora cómo encaja un área de scroll en posiciones predecibles. Cambia el eje, la intensidad, la alineación de bloque e inline y los espacios del snapport y de cada destino.

Leer la guía

Preguntar a la IA

Scroll snap en CSS

Respuesta generada con openai/gpt-5.4-nano. La IA puede cometer errores. Revisa siempre el resultado.

Arrastra, usa la rueda o enfoca las tarjetas con el teclado para comprobar cada posición de snap.

Línea discontinua: snapport reducido por scroll-paddingLínea de puntos: área ampliada por scroll-margin

01

Snapport

El contenedor define los ejes de ajuste.

02

Intensidad

Mandatory y proximity cambian la atracción.

03

Padding

La región visible óptima se desplaza hacia dentro.

04

Eje bloque

El primer valor controla el eje de bloque.

05

Destino

Cada tarjeta crea su propia área de snap.

06

Eje inline

El segundo valor controla el eje inline.

07

Margin

El área de snap crece fuera del borde.

08

Parada

Always puede impedir saltarse un destino.

09

Teclado

Enfoca una tarjeta para llevarla a la vista.

HTML
<div class="snapport" aria-label="Área interactiva de scroll snap en CSS" tabindex="0">
  <article
    class="snap-item"
    style="--item-color: #ffb38a"
    tabindex="0"
  >
    <span>01</span>
    <h2>Snapport</h2>
    <p>El contenedor define los ejes de ajuste.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #72d6c9"
    tabindex="0"
  >
    <span>02</span>
    <h2>Intensidad</h2>
    <p>Mandatory y proximity cambian la atracción.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #b6a8ff"
    tabindex="0"
  >
    <span>03</span>
    <h2>Padding</h2>
    <p>La región visible óptima se desplaza hacia dentro.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #ffd166"
    tabindex="0"
  >
    <span>04</span>
    <h2>Eje bloque</h2>
    <p>El primer valor controla el eje de bloque.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #f7a6c4"
    tabindex="0"
  >
    <span>05</span>
    <h2>Destino</h2>
    <p>Cada tarjeta crea su propia área de snap.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #8ecae6"
    tabindex="0"
  >
    <span>06</span>
    <h2>Eje inline</h2>
    <p>El segundo valor controla el eje inline.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #a7df9b"
    tabindex="0"
  >
    <span>07</span>
    <h2>Margin</h2>
    <p>El área de snap crece fuera del borde.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #f6bd60"
    tabindex="0"
  >
    <span>08</span>
    <h2>Parada</h2>
    <p>Always puede impedir saltarse un destino.</p>
  </article>
  <article
    class="snap-item"
    style="--item-color: #c7a6ff"
    tabindex="0"
  >
    <span>09</span>
    <h2>Teclado</h2>
    <p>Enfoca una tarjeta para llevarla a la vista.</p>
  </article>
</div>
Tailwind CSS
Algunas clases con valores arbitrarios pueden sustituirse por clases nativas, según el valor y la configuración de Tailwind CSS.
<div class="grid grid-cols-[repeat(3,72%)] auto-rows-[72%] gap-6 inline-[min(100%,36rem)] block-96 m-0 p-0 overflow-auto overscroll-contain snap-both snap-mandatory scroll-p-[32px]" aria-label="Área interactiva de scroll snap en CSS" tabindex="0">
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#ffb38a_72%,#172033)] bg-[#ffb38a]"
    tabindex="0"
  >
    <span>01</span>
    <h2>Snapport</h2>
    <p>El contenedor define los ejes de ajuste.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#72d6c9_72%,#172033)] bg-[#72d6c9]"
    tabindex="0"
  >
    <span>02</span>
    <h2>Intensidad</h2>
    <p>Mandatory y proximity cambian la atracción.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#b6a8ff_72%,#172033)] bg-[#b6a8ff]"
    tabindex="0"
  >
    <span>03</span>
    <h2>Padding</h2>
    <p>La región visible óptima se desplaza hacia dentro.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#ffd166_72%,#172033)] bg-[#ffd166]"
    tabindex="0"
  >
    <span>04</span>
    <h2>Eje bloque</h2>
    <p>El primer valor controla el eje de bloque.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#f7a6c4_72%,#172033)] bg-[#f7a6c4]"
    tabindex="0"
  >
    <span>05</span>
    <h2>Destino</h2>
    <p>Cada tarjeta crea su propia área de snap.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#8ecae6_72%,#172033)] bg-[#8ecae6]"
    tabindex="0"
  >
    <span>06</span>
    <h2>Eje inline</h2>
    <p>El segundo valor controla el eje inline.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#a7df9b_72%,#172033)] bg-[#a7df9b]"
    tabindex="0"
  >
    <span>07</span>
    <h2>Margin</h2>
    <p>El área de snap crece fuera del borde.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#f6bd60_72%,#172033)] bg-[#f6bd60]"
    tabindex="0"
  >
    <span>08</span>
    <h2>Parada</h2>
    <p>Always puede impedir saltarse un destino.</p>
  </article>
  <article
    class="box-border grid content-end gap-2 p-[clamp(20px,4vw,32px)] border rounded-2xl text-[#172033] scroll-m-[12px] snap-center snap-normal *:m-0 [&_h2]:text-[clamp(1.75rem,1rem_+_3vw,3rem)] [&>span]:font-extrabold focus-visible:outline-4 focus-visible:outline-[#172033] focus-visible:-outline-offset-8 border-[color-mix(in_oklch,#c7a6ff_72%,#172033)] bg-[#c7a6ff]"
    tabindex="0"
  >
    <span>09</span>
    <h2>Teclado</h2>
    <p>Enfoca una tarjeta para llevarla a la vista.</p>
  </article>
</div>
CSS
.snapport {
  display: grid;
  grid-template-columns: repeat(3, 72%);
  grid-auto-rows: 72%;
  gap: 1.5rem;
  inline-size: min(100%, 36rem);
  block-size: 24rem;
  margin: 0;
  padding: 0;
  overflow: auto;
  overscroll-behavior: contain;
  scroll-snap-type: both mandatory;
  scroll-padding: 32px;
}

.snap-item {
  box-sizing: border-box;
  display: grid;
  align-content: end;
  gap: 0.5rem;
  padding: clamp(20px, 4vw, 32px);
  border: 1px solid color-mix(in oklch, var(--item-color) 72%, #172033);
  border-radius: 1rem;
  background: var(--item-color);
  color: #172033;
  scroll-margin: 12px;
  scroll-snap-align: center;
  scroll-snap-stop: normal;
}

.snap-item > * {
  margin: 0;
}

.snap-item h2 {
  font-size: clamp(1.75rem, 1rem + 3vw, 3rem);
}

.snap-item > span {
  font-weight: 800;
}

.snap-item:focus-visible {
  outline: 4px solid #172033;
  outline-offset: -8px;
}

Guía educativa de scroll-snap

Dar ritmo al scroll sin perder el control

Scroll snap ayuda a que una galería, lista de tarjetas o secuencia de secciones termine de desplazarse en posiciones útiles. Aprende a separar el área de scroll de sus destinos y a elegir un ajuste que conserve la lectura y la navegación.

Volver al playground

Modelo mental

El navegador alinea el área de un destino con una región del contenedor. El layout sigue siendo responsabilidad de Flexbox, Grid o el flujo normal.

Dos regiones que se alineanEsquema estático, sin proporciones exactas. Los bordes y números identifican cada pieza; las recetas de abajo permiten probar el ajuste nativo.
  1. 1 · ScrollportLa ventana visible del contenedor que tiene overflow.
  2. 2 · SnapportLa región de alineación dentro del scrollport, delimitada por scroll-padding.
  3. 3 · Caja del destinoLa caja de borde del elemento que participa con scroll-snap-align.
  4. 4 · Área de snapLa región del destino después de ampliarla con scroll-margin; el contorno de puntos representa esa ampliación.

Primero necesitas overflow real. Una fila de tarjetas puede usar display: flex, elementos que no se encojan y overflow: auto. scroll-snap-type se aplica a ese contenedor; no crea el layout, una barra de scroll ni contenido desbordado por sí solo.

Cada destino aporta una posición mediante scroll-snap-align. El valor inicial none no aporta ninguna. Los destinos se asocian al ancestro de scroll pertinente más cercano: poner la propiedad en un wrapper exterior no configura un scroller interior.

Elegir el tipo de ajuste

La intensidad depende de lo que se necesita leer, no solo del efecto visual.

proximity

Útil para tarjetas y lectura continua. El navegador puede ajustar cuando terminas cerca de un destino y permite detenerte entre posiciones. La distancia que considera cercana depende del navegador y del gesto; no hay un umbral de píxeles que puedas configurar.

mandatory

Útil para una secuencia con destinos claros y contenido controlado. Al terminar el scroll, el contenedor debe quedar en una posición válida si existe alguna. Revisa alturas variables, zoom y teclado antes de aplicarlo a contenido de lectura.

Un destino mayor que el snapport no es automáticamente ilegible: la especificación permite recorrer su interior mientras cubre esa región. Los problemas aparecen con contenido fuera de las áreas de snap, alturas rígidas o posiciones que no encajan con la lectura. Para artículos largos, empieza con proximity y prueba que puedes alcanzar principio, centro y final con texto ampliado.

scroll-snap-stop: normal permite atravesar destinos en un desplazamiento; always impide pasar de largo por una posición durante operaciones que recorren posiciones intermedias. No cambia proximity por mandatory ni obliga a detenerse en cada destino cuando saltas directamente a una posición, por ejemplo con un enlace.

Ejes, alineación y espacios

El eje de desplazamiento, la posición de ajuste y el espacio visual son decisiones diferentes.

x e y son ejes físicos; inline y block siguen el modo de escritura. En horizontal-tb, inline corresponde al horizontal y block al vertical. both permite ajuste en los dos ejes y requiere un escenario con scroll en ellos; no convierte una fila en una cuadrícula.

start, center y end alinean el inicio, centro o final del área del destino con el snapport. Un valor de scroll-snap-align se aplica a ambos ejes. Con dos valores, el primero es block y el segundo inline: none start crea una posición solo en inline, no significa «x e y».

scroll-padding pertenece al contenedor y reduce su región de alineación. scroll-margin pertenece al destino y amplía su área de snap. Ninguno ocupa espacio en el layout: padding, margin y gap siguen siendo necesarios para separar visualmente las cajas.

Reservar espacio para una cabecera

Fragmento para una lista vertical con overflow real: 4rem reservan el espacio de la cabecera y 0.5rem añaden separación al destino. Ajusta la reserva al tamaño real de la cabecera, también con zoom.

Reservar espacio para una cabecera
CSS
.reading-list {
  overflow: auto;
  scroll-snap-type: block proximity;
  scroll-padding-block-start: 4rem;

  > article {
    scroll-snap-align: start;
    scroll-margin-block-start: 0.5rem;
  }
}

En un ajuste start, esas distancias se combinan para separar el destino del borde. Los límites del scroll siguen contando: la primera o última tarjeta puede no alcanzar la alineación ideal. scroll-padding no añade recorrido vacío al principio o al final; añade espacio de layout si el diseño lo necesita.

Una lista horizontal reutilizable

Dos listas con las mismas tarjetas y medidas permiten comparar la intensidad. Cambia solo mandatory por proximity en el CSS.

Las tarjetas conservan enlaces HTML reales y dejan asomar la siguiente. Cada lista tiene nombre accesible, foco propio y barra nativa, y funciona sin JavaScript. El CSS muestra valores explícitos de color, radio y espaciado; light-dark() conserva ambos temas con color-scheme. Puedes adaptar esos valores a tu proyecto.

Lectura con proximity

01 Barras de scroll

Mantén visible que hay más contenido y conserva una forma directa de desplazarse.

Abrir el lab
02 Espacio del contenedor

Reserva la región donde un destino debe quedar visible al alinearse.

Abrir el lab
03 Carrusel CSS

Añade navegación explícita cuando la secuencia necesita botones o marcadores.

Abrir el lab
Desplaza la lista horizontalmente con la barra o el gesto del dispositivo. Con foco en la región, prueba las flechas; Tab recorre sus enlaces. Cerca de un destino puede ajustarse, pero no tiene que hacerlo en cada parada.
Lectura con proximity
<div class="snap-guide-proximity" role="region" aria-label="Lista de labs con ajuste proximity" tabindex="0">
  <article>
    <span>01</span>
    <strong>Barras de scroll</strong>
    <p>Mantén visible que hay más contenido y conserva una forma directa de desplazarse.</p>
    <a href="/css/scroll/scrollbar/">Abrir el lab</a>
  </article>
  <article>
    <span>02</span>
    <strong>Espacio del contenedor</strong>
    <p>Reserva la región donde un destino debe quedar visible al alinearse.</p>
    <a href="/css/scroll/scroll-padding/">Abrir el lab</a>
  </article>
  <article>
    <span>03</span>
    <strong>Carrusel CSS</strong>
    <p>Añade navegación explícita cuando la secuencia necesita botones o marcadores.</p>
    <a href="/css/scroll/css-carousel/">Abrir el lab</a>
  </article>
</div>
:root {
  color-scheme: light dark;
}

.snap-guide-proximity {
  display: flex;
  gap: 1rem;
  min-inline-size: 0;
  padding: 1rem;
  overflow: auto;
  scroll-snap-type: inline proximity;
  scroll-padding-inline: 1.5rem;
  border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
  border-radius: 16px;
  corner-shape: squircle;
  background: light-dark(oklch(0.98 0.005 95), oklch(0.16 0.02 260));
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));

  > article {
    box-sizing: border-box;
    flex: 0 0 82%;
    min-inline-size: 0;
    display: grid;
    align-content: start;
    gap: 0.5rem;
    padding: 1rem;
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;
    background: light-dark(color-mix(in oklch, oklch(0.95 0.008 95) 98%, white), color-mix(in oklch, oklch(0.22 0.024 260) 86%, black));
    overflow-wrap: anywhere;
    scroll-snap-align: start;
    scroll-snap-stop: normal;
    scroll-margin-inline: 0.5rem;

    > * {
      margin: 0;
    }

    > span,
    > strong {
      font-weight: 800;
    }
  }

  a {
    color: light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  &:focus-visible,
  a:focus-visible {
    outline: 3px dashed light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    outline-offset: -3px;
  }
}

La misma lista con mandatory

01 Barras de scroll

Mantén visible que hay más contenido y conserva una forma directa de desplazarse.

Abrir el lab
02 Espacio del contenedor

Reserva la región donde un destino debe quedar visible al alinearse.

Abrir el lab
03 Carrusel CSS

Añade navegación explícita cuando la secuencia necesita botones o marcadores.

Abrir el lab
Repite el recorrido: al terminar se elige una posición válida. La tarjeta final está limitada por el extremo del scroll. El movimiento y la posición elegida pueden variar según el navegador y la entrada.
La misma lista con mandatory
<div class="snap-guide-mandatory" role="region" aria-label="Lista de labs con ajuste mandatory" tabindex="0">
  <article>
    <span>01</span>
    <strong>Barras de scroll</strong>
    <p>Mantén visible que hay más contenido y conserva una forma directa de desplazarse.</p>
    <a href="/css/scroll/scrollbar/">Abrir el lab</a>
  </article>
  <article>
    <span>02</span>
    <strong>Espacio del contenedor</strong>
    <p>Reserva la región donde un destino debe quedar visible al alinearse.</p>
    <a href="/css/scroll/scroll-padding/">Abrir el lab</a>
  </article>
  <article>
    <span>03</span>
    <strong>Carrusel CSS</strong>
    <p>Añade navegación explícita cuando la secuencia necesita botones o marcadores.</p>
    <a href="/css/scroll/css-carousel/">Abrir el lab</a>
  </article>
</div>
:root {
  color-scheme: light dark;
}

.snap-guide-mandatory {
  display: flex;
  gap: 1rem;
  min-inline-size: 0;
  padding: 1rem;
  overflow: auto;
  scroll-snap-type: inline mandatory;
  scroll-padding-inline: 1.5rem;
  border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
  border-radius: 16px;
  corner-shape: squircle;
  background: light-dark(oklch(0.98 0.005 95), oklch(0.16 0.02 260));
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));

  > article {
    box-sizing: border-box;
    flex: 0 0 82%;
    min-inline-size: 0;
    display: grid;
    align-content: start;
    gap: 0.5rem;
    padding: 1rem;
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;
    background: light-dark(color-mix(in oklch, oklch(0.95 0.008 95) 98%, white), color-mix(in oklch, oklch(0.22 0.024 260) 86%, black));
    overflow-wrap: anywhere;
    scroll-snap-align: start;
    scroll-snap-stop: normal;
    scroll-margin-inline: 0.5rem;

    > * {
      margin: 0;
    }

    > span,
    > strong {
      font-weight: 800;
    }
  }

  a {
    color: light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  &:focus-visible,
  a:focus-visible {
    outline: 3px dashed light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    outline-offset: -3px;
  }
}

No ocultes contenido ni canceles el comportamiento nativo de los enlaces para conseguir snap. Prueba teclado, tacto y rueda por separado; comprueba que el foco permanece visible. Evita autoplay y scroll suave innecesario; si añades animación, respeta prefers-reduced-motion.

Errores frecuentes

Diagnostica primero el contenedor y después los destinos. Un ajuste declarado puede no tener ningún recorrido al que aplicarse.

Declaro snap, pero nada se desplaza

Resultado esperado
Hay recorrido y se pueden alcanzar todas las tarjetas.
Causa
El contenido cabe o los elementos flex se encogen; overflow por sí solo no obliga a desbordar.
Solución
Comprueba scrollWidth frente a clientWidth (o la altura). Define un tamaño de contenedor y tarjetas que produzcan overflow; en una fila, evita que se encojan con flex: 0 0 ….

El contenedor se mueve sin ajustar

Resultado esperado
Los elementos aportan posiciones en el eje activo.
Causa
Falta scroll-snap-align, vale none o las propiedades están en un contenedor diferente del que se desplaza.
Solución
Configura scroll-snap-type en el scroller real y scroll-snap-align en sus destinos. No confundas la ausencia de ajuste lejano con un fallo de proximity.

El ajuste ocurre en el eje equivocado

Resultado esperado
La posición sigue el modo de escritura y la dirección del recorrido.
Causa
Se mezclan x/y con inline/block o se leen los dos valores de scroll-snap-align como horizontal/vertical.
Solución
Comprueba writing-mode y el eje con overflow. Recuerda el orden block inline; usa inline o block cuando la dirección lógica deba seguir el texto.

La cabecera tapa el destino

Resultado esperado
El título y su foco quedan visibles al desplazarse.
Causa
Se cambió padding o margin de layout, pero no la región de alineación que queda bajo la cabecera.
Solución
Reserva la cabecera con scroll-padding-block-start en el contenedor real. Usa scroll-margin-block-start para separación extra por destino; verifica la medida con texto ampliado.

always no se detiene en todas las tarjetas

Resultado esperado
No se atraviesa una posición durante un recorrido al que se aplica esa restricción.
Causa
Se espera que scroll-snap-stop: always controle también un salto directo a un destino o la intensidad proximity.
Solución
Prueba un gesto que atraviese posiciones, no solo enlaces o saltos a coordenadas. Elige la intensidad con scroll-snap-type y reserva always para cuando frenar el recorrido aporte valor.

Soporte y compatibilidad

Separa el ajuste básico de las APIs que permiten construir navegación y observar sus cambios.

Las propiedades básicas scroll-snap-type, scroll-snap-align, scroll-snap-stop, scroll-padding y scroll-margin están ampliamente disponibles según MDN. Ese estado no garantiza la misma física, distancia de proximity o posición final en cada navegador.

Si se ignoran las declaraciones de snap, las recetas mantienen scroll normal y enlaces utilizables. No necesitan un polyfill para acceder al contenido. La preview muestra la implementación de tu navegador, no una certificación entre motores.

Scroll snap aporta posiciones; un carrusel añade navegación y estado. No genera botones, marcadores ni anuncios accesibles. El soporte de scroll buttons, scroll markers, eventos de snap o consultas de estado debe revisarse por separado; aquí no se usan esas piezas.