Skip to content

Scroll Area

Nuevo

El componente hp-scroll-area es un primitivo que reemplaza los scrollbars nativos del navegador con scrollbars personalizados y accesibles. Implementa el patrón WAI-ARIA role="scrollbar" con soporte completo de teclado.

Instalación

bash
pnpm add @headless-primitives/scroll-area
bash
npm install @headless-primitives/scroll-area
bash
yarn add @headless-primitives/scroll-area
bash
bun add @headless-primitives/scroll-area

Anatomía

html
<hp-scroll-area>
  <hp-scroll-area-viewport>
    <hp-scroll-area-content>
      <!-- contenido scrollable -->
    </hp-scroll-area-content>
  </hp-scroll-area-viewport>
  <hp-scroll-area-scrollbar orientation="vertical">
    <hp-scroll-area-thumb></hp-scroll-area-thumb>
  </hp-scroll-area-scrollbar>
  <hp-scroll-area-scrollbar orientation="horizontal">
    <hp-scroll-area-thumb></hp-scroll-area-thumb>
  </hp-scroll-area-scrollbar>
  <hp-scroll-area-corner></hp-scroll-area-corner>
</hp-scroll-area>

Demostración

Sin estilos (solo base.css)

Línea 1

Línea 2

Línea 3

Línea 4

Línea 5

Línea 6

Con estilos personalizados

Elemento 1 — Scroll para ver más

Elemento 2

Elemento 3

Elemento 4

Elemento 5

Elemento 6

Elemento 7

Elemento 8 — Fin del contenido

html
<hp-scroll-area class="scroll-area">
  <hp-scroll-area-viewport class="viewport">
    <hp-scroll-area-content>
      <!-- contenido -->
    </hp-scroll-area-content>
  </hp-scroll-area-viewport>
  <hp-scroll-area-scrollbar class="scrollbar" orientation="vertical">
    <hp-scroll-area-thumb class="thumb"></hp-scroll-area-thumb>
  </hp-scroll-area-scrollbar>
  <hp-scroll-area-scrollbar class="scrollbar" orientation="horizontal">
    <hp-scroll-area-thumb class="thumb"></hp-scroll-area-thumb>
  </hp-scroll-area-scrollbar>
  <hp-scroll-area-corner class="corner"></hp-scroll-area-corner>
</hp-scroll-area>
css
hp-scroll-area,
hp-scroll-area-viewport,
hp-scroll-area-content,
hp-scroll-area-scrollbar,
hp-scroll-area-thumb,
hp-scroll-area-corner {
  display: block;
}

.scroll-area {
  position: relative;
  overflow: hidden;
  width: 300px;
  height: 200px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.viewport {
  width: 100%;
  height: 100%;
  overflow: scroll;
  scrollbar-width: none;
}
.viewport::-webkit-scrollbar {
  display: none;
}

.scrollbar {
  position: absolute;
  padding: 2px;
  display: flex;
  opacity: 0;
  transition: opacity 0.2s;
}
.scroll-area:hover .scrollbar {
  opacity: 1;
}

.scrollbar[orientation="vertical"] {
  top: 0;
  right: 0;
  bottom: 0;
  width: 8px;
  flex-direction: column;
}

.scrollbar[orientation="horizontal"] {
  left: 0;
  right: 0;
  bottom: 0;
  height: 8px;
  flex-direction: row;
}

.thumb {
  flex: 1;
  background: #94a3b8;
  border-radius: 9999px;
  min-height: 20px;
  min-width: 20px;
  cursor: grab;
}
.thumb:hover {
  background: #64748b;
}

.corner {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 8px;
  height: 8px;
}

API Reference

hp-scroll-area

Contenedor raíz que agrupa todas las partes del scroll area.

Atributos

AtributoTipoPor defectoDescripción
orientation"vertical" | "horizontal" | "both""vertical"Orientación del scroll. Refleja en data-orientation.

Data attributes gestionados

AtributoDescripción
data-orientationRefleja el valor de orientation.
data-has-overflow-yPresente cuando el contenido es más alto que el viewport.
data-has-overflow-xPresente cuando el contenido es más ancho que el viewport.
data-overflow-y-startPresente cuando hay overflow por encima del scroll actual.
data-overflow-y-endPresente cuando hay overflow por debajo del scroll actual.
data-overflow-x-startPresente cuando hay overflow a la izquierda del scroll.
data-overflow-x-endPresente cuando hay overflow a la derecha del scroll.

hp-scroll-area-viewport

El contenedor scrollable real. Oculta los scrollbars nativos del navegador.

CSS Custom Properties expuestas

VariableDescripción
--scroll-area-overflow-y-startPíxeles de overflow por encima del scroll actual.
--scroll-area-overflow-y-endPíxeles de overflow por debajo del scroll actual.
--scroll-area-overflow-x-startPíxeles de overflow a la izquierda del scroll actual.
--scroll-area-overflow-x-endPíxeles de overflow a la derecha del scroll actual.

Eventos

EventoDetalleDescripción
hp-scroll{ scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth }Se dispara en cada evento de scroll.

hp-scroll-area-scrollbar

Scrollbar personalizado. Implementa role="scrollbar" con navegación por teclado completa.

Atributos

AtributoTipoPor defectoDescripción
orientation"vertical" | "horizontal""vertical"Orientación del scrollbar. Refleja en data-orientation y aria-orientation.

Atributos ARIA gestionados

  • role="scrollbar" — asignado automáticamente
  • aria-orientation — sincronizado con orientation
  • aria-controls — referencia al ID del viewport
  • aria-valuemin="0" — valor mínimo de scroll
  • aria-valuenow — posición actual de scroll en píxeles
  • aria-valuemax — máximo de scroll en píxeles

Data attributes gestionados

AtributoDescripción
data-state"visible" cuando hay overflow, "hidden" si no.
data-draggingPresente mientras el thumb está siendo arrastrado.
TeclaAcción
ArrowDown/UpScroll vertical en pasos de 40px
ArrowLeft/RightScroll horizontal en pasos de 40px
PageDown/UpScroll por altura/anchura del viewport
HomeIr al inicio del contenido
EndIr al final del contenido

hp-scroll-area-thumb

Indicador de posición dentro del scrollbar. Su tamaño y posición se calculan dinámicamente.

hp-scroll-area-corner

Esquina donde se intersectan los dos scrollbars. Solo visible cuando ambos están activos (data-state="visible").

Accesibilidad

hp-scroll-area implementa el patrón WAI-ARIA Scrollbar:

  • role="scrollbar" con aria-controls, aria-valuemin, aria-valuenow y aria-valuemax
  • Navegación completa por teclado (flechas, Page Up/Down, Home, End)
  • aria-hidden="true" en la esquina (elemento decorativo)
  • Los scrollbars son focusables (tabindex="0")

Lanzado bajo la MIT License.