Una necesidad bastante común en un sitio web, es la de estilar o dar estilo a las barras de desplazamiento del navegador (o de una de las secciones o partes de la página) para que estén más acorde con el diseño del sitio, ya que las barras de progreso por defecto del sistema muchas veces no encajan con el «look and feel» del sitio web.
Para ello, tenemos una serie de propiedades interesantes que veremos a continuación, y que son las que deberían utilizarse en primer lugar.
Dar estilo a las barras de progreso
Para dar estilo a las barras de progreso tenemos las siguientes propiedades oficiales:
Propiedad | Descripción |
---|---|
scrollbar-width | Le da un tamaño a la barra de desplazamiento. Los valores soportados son auto , thin y none . |
scrollbar-gutter | Reserva espacio (evita desplazamientos inesperados al mostrar/ocultar la barra). |
scrollbar-color | Le da color a la barra de desplazamiento. Primer parámetro a la barra y segundo al fondo. |
Veamos un ejemplo de estas propiedades aplicadas a una sección de texto:
.container {
width: 350px;
height: 75px;
background: #111;
padding: 1rem;
border: 4px solid black;
color: #fff;
overflow-y: scroll;
scrollbar-color: deeppink #222;
scrollbar-width: thin;
}
<div class="container">
<p>Esto es un ejemplo donde va a aparecer una barra de desplazamiento, para que podamos ver como se le puede dar estilo personalizado.</p>
</div>
Analicemos ahora detalladamente cada una de estas propiedades.
La propiedad scrollbar-width
La propiedad scrollbar-width
nos permite indicar el tamaño de nuestra barra de desplazamiento. Tiene varios valores posibles que podemos utilizar:
Valor | Descripción |
---|---|
auto | Por defecto, los navegadores utilizan este valor y establecen el ancho genérico. |
thin | Establece una barra de scroll más delgada y pequeña. |
none | La oculta. No muestra ninguna barra de scroll. |
Más adelante veremos más formas no estándar de personalizar las barras de desplazamiento, pero las que estamos viendo actualmente son maneras estándar (compatibles con todos los navegadores).
La propiedad scrollbar-gutter
La palabra gutter
hace referencia a un «canal», espacio o hueco que se puede configurar a la hora de crear barras de desplazamiento. Esto es especialmente interesante en situaciones donde la barra de desplazamiento aparece o desaparece dependiendo del contenido o la posición de la web, causando que el contenido sea inestable y se desplace o se mueva de forma irregular.
Los valores de esta propiedad son los siguientes:
Valor | Descripción |
---|---|
auto | La scrollbar ocupa espacio cuando overflow está en auto o scroll y el contenido se desborda. |
stable | La scrollbar ocupa espacio siempre (incluso con overflow: hidden ). Ideal para evitar diseños inestables. |
both-edges | Reserva espacio también en el borde opuesto a la scrollbar. Ideal para diseños simétricos. |
La última opción, both-edges
, realmente es un valor que se puede añadir a las anteriores para indicar esa característica.
Veamos algunos ejemplos:
.element-1 {
scrollbar-color: deeppink indigo;
scrollbar-width: thin;
scrollbar-gutter: auto;
}
.element-2 {
scrollbar-color: deeppink indigo;
scrollbar-width: thin;
scrollbar-gutter: stable both-edges;
}
La propiedad scrollbar-color
Por último, la propiedad scrollbar-color
nos permite personalizar el color de la barra de desplazamiento. Dispone de dos parámetros, donde el primero es el color de la barra de desplazamiento y el segundo es el color del fondo de la barra de desplazamiento.
.container {
scrollbar-color: deeppink black;
scrollbar-width: auto;
scrollbar-gutter: stable;
}
Estilar barras de progreso (legacy)
Lo que hemos visto anteriormente es la forma oficial para estilar una barra de desplazamiento. Sin embargo, en muchas situaciones nos puede parecer insuficiente, ya que necesitamos mayor personalización.
Existen mecanismos de personalización más avanzados que explicaremos a continuación, sin embargo, el gran problema de estos mecanismos es que están desarrollados por y para el motor webkit
(Safari), y por extensión blink
(Chrome y Edge), pero al no ser estandares, no funcionan ni planean funcionar en servo
(Firefox).
El punto bueno, es que son mucho más personalizables (y complejos) que las propiedades anteriores. Si aún así te interesa utilizarlos, veamos una explicación.
Para utilizar estos mecanismos de personalización debemos utilizar unos pseudoelementos propios de los navegadores basados en webkit
o blink
. Estos pseudoelementos se escriben prefijados de ::-webkit-
y funcionan de una forma particular.
Cuidado al utilizar los pseudoelementos
::-webkit-
, no puedes usarlos con Nesting ni unirlos a otros fragmentos de código. Deben ser individuales ya que el navegador los procesa de forma aislada.
Scrollbar con ::-webkit-scrollbar
Comencemos con el pseudoelemento ::-webkit-scrollbar
, que nos permite dar estilo a la barra de desplazamiento en conjunto. Antes de comenzar, examina el código de .container
y observa que estamos cambiando el tamaño del elemento e indicando un overflow-y: scroll
para forzar a que haya barra de desplazamiento en el eje Y (vertical).
Una vez hecho esto, podemos utilizar nuestra pseudoclase con el elemento que queramos, o con body
si queremos aplicarlo a la barra de desplazamiento global del navegador:
.container {
width: 300px;
max-height: 50px;
border: 1px solid #222;
font-size: 1.5rem;
color: #fff;
background: #000;
padding: 2rem;
overflow-y: scroll;
}
.container::-webkit-scrollbar {
width: var(--width, 15px);
background: indigo;
}
<div class="container">
<p>Esto es un ejemplo donde va a aparecer una barra de desplazamiento, para que podamos ver como se le puede dar estilo personalizado.</p>
</div>
<input name="width" type="range" value="10" min="1" max="35" /><output>10px</output>
const container = document.querySelector(".container");
const inputWidth = document.querySelector("input[name=width]");
const update = (variable, input) => {
container.style.setProperty(variable, `${input.value}px`);
input.nextElementSibling.textContent = input.value + "px";
}
inputWidth.addEventListener("input", () => update("--width", inputWidth));
Observa que aquí lo único que hacemos es cambiar el color de fondo de la barra de desplazamiento y el tamaño de ancho de la misma. Sin embargo, no contiene nada porque aún no falta estilar las demás partes, que veremos a continuación.
El fondo con ::-webkit-scrollbar-track
Con el pseudoelemento ::-webkit-scrollbar-track
podemos cambiar el fondo por donde se desplaza la barra de desplazamiento. Ten en cuenta que existe tanto un track
como un track-piece
, donde este último es una región más interna por donde se puede mover la barra de desplazamiento:
.container::-webkit-scrollbar-track {
background: #444;
}
.container::-webkit-scrollbar-track-piece {
background: #555;
}
Normalmente, con utilizar track
nos basta, pero si quieres ver bien la diferencia añade un margin: 10px
a cada elemento y verás rápidamente la porción que ocupa cada uno.
La barra con ::-webkit-scrollbar-thumb
Además, también tenemos el pseudoelemento ::-webkit-scrollbar-thumb
que aplica estilos a la barra de desplazamiento propiamente dicha. Probablemente, es el elemento más importante de los que hemos visto:
.container::-webkit-scrollbar-thumb {
background: yellowgreen;
}
.container::-webkit-scrollbar-thumb:hover { background: green; }
.container::-webkit-scrollbar-thumb:active { background: deeppink; }
Observa que podemos usar :hover
para cambiar estilo cuando mueves el ratón por encima (o :active
para cuando pulsas). Vamos a añadir el código que hemos visto hasta ahora al ejemplo inicial anterior:
.container {
width: 300px;
max-height: 50px;
border: 1px solid #222;
font-size: 1.5rem;
color: #fff;
background: #000;
padding: 2rem;
overflow-y: scroll;
}
.container::-webkit-scrollbar {
width: var(--width, 15px);
background: #333;
}
.container::-webkit-scrollbar-track {
background: #444;
}
.container::-webkit-scrollbar-thumb {
background: yellowgreen;
}
.container::-webkit-scrollbar-thumb:hover { background: lawngreen; }
.container::-webkit-scrollbar-thumb:active { background: deeppink; }
<div class="container">
<p>Esto es un ejemplo donde va a aparecer una barra de desplazamiento, para que podamos ver como se le puede dar estilo personalizado.</p>
</div>
Si lo quisieras podrías añadir otras propiedades interesantes. Por ejemplo, un
border-radius: 10px
althumb
para hacer que la barra de desplazamiento esté redondeada. Recuerda que no todas las propiedades CSS funcionan en este pseudoelemento.
Los botones con ::-webkit-scrollbar-button
Observa que hasta ahora puedes mover la barra de desplazamiento tanto arrastrando el thumb
como pulsando en las zonas vacías del track
. Sin embargo, es posible que quieras añadir los clásico botones de desplazamiento, si te parece más intuitivo.
Esto se hace con el pseudoelemento ::-webkit-scrollbar-button
, que se puede configurar bastante:
.container::-webkit-scrollbar-button {
background: #222;
}
Si añades este fragmento de código, verás que aparecen a los extremos unos cuadraditos que son los botones de las barras de desplazamiento. Sin embargo, por defecto aparecen sin icono, ni nada en su interior. Vamos a ponerle solución.
Modificadores para los botones
Existen varios modificadores para nuestros botones, que podemos utilizar en ::-webkit-scrollbar-button
:
Modificador | Descripción |
---|---|
:single-button | Aplica estilos si es una barra con botones individuales a los extremos (lo más habitual). |
:double-button | Aplica estilos si es una barra con botones dobles. |
:no-button | Aplica estilos sólo si es una barra sin botones, por lo que afecta al track-piece . |
:horizontal | Aplica estilos sólo si es una barra de desplazamiento horizontal. |
:vertical | Aplica estilos sólo si es una barra de desplazamiento vertical. |
:increment | Aplica estilos sólo si es un botón de incremento. |
:decrement | Aplica estilos sólo si es un botón de decremento. |
Ten en cuenta que estos modificadores se añaden al final y son acumulables, por lo que puedes usar varios. Veamos un ejemplo donde además, utilizamos background
para añadir un icono SVG para las flechas. En este caso lo hacemos con svg
inline, pero se puede perfectamente hacer con un fichero externo .svg
:
.container::-webkit-scrollbar-button:single-button:vertical:decrement {
background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 150 150' xmlns='http://www.w3.org/2000/svg' fill='white'><polygon points='50,0 0,50 100,50'/></svg>");
background-repeat: no-repeat;
background-position: 2px 5px;
}
.container::-webkit-scrollbar-button:single-button:vertical:decrement:hover {
background-color: red;
}
.container::-webkit-scrollbar-button:single-button:vertical:increment {
background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 150 150' xmlns='http://www.w3.org/2000/svg' fill='white'><polygon points='0,0 100,0 50,50'/></svg>");
background-repeat: no-repeat;
background-position: 2px 6px;
}
.container::-webkit-scrollbar-button:single-button:vertical:increment:hover {
background-color: red;
}
En lugar de :increment
o :decrement
también podemos utilizar :start
o :end
, que puede ser más intuitivo en el caso de necesitarlo.
El redimensionador con ::-webkit-resizer
En algún caso podríamos necesitar tener un redimensionador. Para ello, en el CSS del elemento se suele indicar la propiedad resize``con los valores
both,
horizontalo
vertical`. Si lo hacemos, veremos que en una esquina nos aparece un redimensionador.
.container::-webkit-resizer {
background: green;
}
Este redimensionador se puede estilar utilizando el pseudoelemento ::-webkit-resizer
. Veámoslo en funcionamiento con todo lo anterior que hemos aprendido en este artículo:
.container {
width: 300px;
max-height: 50px;
border: 1px solid #222;
font-size: 1.5rem;
color: #fff;
background: #000;
padding: 2rem;
overflow-y: scroll;
resize: both;
}
.container::-webkit-scrollbar {
width: var(--width, 15px);
background: #333;
}
.container::-webkit-scrollbar-track {
background: #444;
}
.container::-webkit-scrollbar-thumb {
background: yellowgreen;
}
.container::-webkit-scrollbar-thumb:hover { background: lawngreen; }
.container::-webkit-scrollbar-thumb:active { background: deeppink; }
.container::-webkit-resizer {
background: linear-gradient(-45deg, gold 50%, black 50%);
}
.container::-webkit-scrollbar-button:single-button:vertical:decrement {
background-image: url("down.svg");
background-repeat: no-repeat;
background-position: 2px 5px;
}
.container::-webkit-scrollbar-button:single-button:vertical:decrement:hover {
background-color: red;
}
.container::-webkit-scrollbar-button:single-button:vertical:increment {
background-image: url("up.svg");
background-repeat: no-repeat;
background-position: 2px 6px;
}
.container::-webkit-scrollbar-button:single-button:vertical:increment:hover {
background-color: red;
}
<div class="container">
<p>Esto es un ejemplo donde va a aparecer una barra de desplazamiento, para que podamos ver como se le puede dar estilo personalizado.</p>
</div>
Mejora progresiva
Recuerda que las propiedades iniciales que vimos son las propiedades estándar y las que deberíamos utilizar en primer lugar. Luego, si queremos mayor personalización para los navegadores que lo soporten, podríamos añadir este mecanismo orientado a webkit
o blink
.
La mejor forma de realizar esto, es utilizar la regla @supports
, donde podemos definir como queremos utilizarlo:
.container {
/* Código CSS normal */
}
@supports (scrollbar-width: thin) {
.container {
/* Código CSS estándar de barras de desplazamiento */
}
}
@supports selector(::-webkit-scrollbar) {
/* Pseudoelementos de webkit */
}