---
title: "Pestañas desplazables en React — sin Material UI"
description: "Pestañas desplazables en React con scroll nativo: la pestaña activa se centra sola, las flechas aparecen solo cuando hacen falta, contenido de pestaña libre. Demo en vivo y código."
canonical: "https://react-horizontal-scrolling-menu.dev/es/scrollable-tabs"
image: "https://react-horizontal-scrolling-menu.dev/og.png"
---

# Pestañas de React que se desplazan como el navegador

Una barra de pestañas deja de caber en cuanto tu producto supera las seis pestañas. La solución no es una fuente más pequeña: es una barra que se desplaza. El desbordamiento lo gestiona el navegador, al hacer clic en una pestaña esta se centra y las flechas aparecen solo cuando hay a dónde ir.

Overview

Getting started

Visibility

Arrows

Drag to scroll

RTL

apiRef

Helpers

TypeScript

Testing

Changelog

FAQ

Haz clic en una pestaña cerca del borde: se desplaza sola hasta el centro.

[Edita este ejemplo en vivo en Storybook](https://asmyshlyaev177.github.io/react-horizontal-scrolling-menu/?path=/story/examples-centeronclick--center-on-click)

## El único comportamiento que importa: centrar al seleccionar

Una barra de pestañas desplazable vive o muere por lo que pasa al hacer clic en una pestaña del borde: debería deslizarse hasta el centro y revelar sus vecinas a ambos lados. Aquí es una sola llamada —`scrollToItem(el, 'smooth', 'center')`— conectada en el [ejemplo de centrar al hacer clic](https://react-horizontal-scrolling-menu.dev/es/examples/center-on-click.md). Restaurar la pestaña activa al montar es la misma llamada con `'auto'`, mostrada en [guardar y restaurar posición](https://react-horizontal-scrolling-menu.dev/es/examples/save-restore-position.md).

Las flechas vienen de los mismos datos de visibilidad: `useLeftArrowVisible` es falso solo mientras la primera pestaña está fuera de pantalla, así que la flecha izquierda se renderiza justo cuando es útil. Sin código de medición propio, sin observadores de resize propios.

## Si te estás quedando corto con las pestañas desplazables de MUI

Las pestañas `variant="scrollable"` de Material UI son la respuesta correcta dentro del sistema de diseño de Material, hasta que tus "pestañas" dejan de ser pestañas. MUI suelda la barra a la semántica de Tabs: un par `value`/`onChange`, paneles de pestaña y botones de scroll que MUI oculta en móvil por defecto. En el momento en que tu fila contiene chips, tarjetas, avatares o contenido mixto, o necesita arrastre para desplazar, o necesita saber qué elementos están visibles, estás luchando contra el componente en lugar de usarlo.

Esta librería es la capa de debajo: una fila con scroll y seguimiento de visibilidad, sin opinión sobre qué es una "pestaña". Tu pestaña es cualquier componente con un `itemId`: dale estilo con Tailwind, con el `styled` propio de MUI o con CSS normal. El estado de selección sigue siendo tuyo, igual que la demo de arriba lo guarda en un único `useState`.

## La accesibilidad sale casi gratis: cuidado con dos huecos

Como la barra es un contenedor de scroll nativo, el foco de teclado, el orden de lectura del lector de pantalla y RTL vienen de la plataforma: mover el foco entre pestañas las desplaza a la vista sin escribir código, y [RTL](https://react-horizontal-scrolling-menu.dev/es/examples/rtl.md) no necesita configuración. Dos cosas siguen dependiendo de ti, igual que en cualquier UI de pestañas: elegir tu patrón ARIA (`role="tablist"` si de verdad cambian paneles, `aria-current` si las "pestañas" son navegación) y mantener la supresión de clic de la receta de [arrastre para desplazar](https://react-horizontal-scrolling-menu.dev/es/examples/mouse-drag.md) para que soltar un arrastre nunca active una pestaña.

## El patrón, en su forma mínima

Las pestañas son botones normales con un `itemId`; seleccionar una la centra. Esta es toda la idea: la demo de arriba añade estilos y arrastre.

ScrollTabs.tsx

```
function ScrollTabs({ tabs }: { tabs: string[] }) {
  const [active, setActive] = React.useState(tabs[0]);
  return (
    <ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
      {tabs.map((tab) => (
        <Tab itemId={tab} key={tab} label={tab}
          active={tab === active} onSelect={() => setActive(tab)} />
      ))}
    </ScrollMenu>
  );
}

function Tab({ itemId, label, active, onSelect }: TabProps) {
  const api = React.useContext<publicApiType>(VisibilityContext);
  return (
    <button
      aria-current={active}
      onClick={(ev) => {
        onSelect();
        // The behavior that makes tabs feel native: selecting an
        // edge tab glides it to the center of the strip.
        api.scrollToItem(ev.currentTarget, 'smooth', 'center');
      }}
    >
      {label}
    </button>
  );
}
```

## O instálalo como componente shadcn

El elemento del registro [scroll-tabs](https://react-horizontal-scrolling-menu.dev/r/scroll-tabs.json) distribuye este patrón basado en datos —pasa `tabs`, `value`, `onValueChange`— como componente editable en tu `components/ui/`:

shadcn

```
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/scroll-tabs.json
```

## Ejemplos relacionados

-   [Centrar el elemento clicadoscrollToItem con inline: center — el patrón de pestañas desplazables.](https://react-horizontal-scrolling-menu.dev/es/examples/center-on-click.md)
-   [Guardar y restaurar la posición de desplazamientoMantén el desplazamiento entre desmontajes y recargas de página.](https://react-horizontal-scrolling-menu.dev/es/examples/save-restore-position.md)
-   [Arrastrar para desplazarse con el ratónArrastre con el ratón que sigue dejando funcionar los clics.](https://react-horizontal-scrolling-menu.dev/es/examples/mouse-drag.md)

[Todos los ejemplos (21)](https://react-horizontal-scrolling-menu.dev/es/examples.md)

---

More examples: <https://react-horizontal-scrolling-menu.dev/examples.md>
Library summary for LLMs: <https://react-horizontal-scrolling-menu.dev/llms.txt>
