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 en el estándar:
Propiedad | Descripción |
---|---|
scrollbar-color | Le da color a la barra de desplazamiento. Primer parámetro a la barra y segundo al fondo. |
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). |
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>
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.
Valor | Descripción |
---|---|
auto | La barra de desplazamiento ocupa un margen cuando overflow está en auto o scroll y el contenido se desborda. |
stable | Dicho margen también está presente cuando overflow es hidden . Ideal para evitar cambios en el diseño. |
both-edges | Reserva espacio también en el borde opuesto a la barra de desplazamiento. Ideal para mantener diseño simétrico. |
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;
}
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 */
}