position: sticky
es una nueva forma de posicionar elementos y es conceptualmente similar a position: fixed
. La diferencia es que un elemento con position: sticky
se comporta como position: relative
dentro de su elemento superior, hasta que se cumple un umbral de desplazamiento determinado en la ventana de visualización.
Casos de uso
Tomamos la siguiente cita de la propuesta original de Edward O'Connor para esta función:
Presentamos el posicionamiento fijo
Con solo agregar position: sticky
(con prefijo del proveedor), podemos indicarle a un elemento que sea position: relative
hasta que el usuario desplace el elemento (o su elemento superior) a 15 px de la parte superior:
.sticky {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 15px;
}
En top: 15px
, el elemento se fija.
Para ilustrar esta función en un entorno práctico, armé una DEMO que fija los títulos de los blogs mientras te desplazas.
Enfoque anterior: eventos de desplazamiento
Hasta ahora, para lograr el efecto fijo, los sitios configuraban objetos de escucha de eventos scroll
en JS. En realidad, también usamos esta técnica en los instructivos de html5rocks. En pantallas de menos de 1,200 px, la barra lateral del índice cambia a position: fixed
después de un cierto desplazamiento.
Esta es la forma (ahora antigua) de tener un encabezado que se adhiere a la parte superior del viewport cuando el usuario se desplaza hacia abajo y vuelve a su lugar cuando se desplaza hacia arriba:
<div class="header"></div>
<script>
var header = document.querySelector('.header');
var origOffsetY = header.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? header.classList.add('sticky') :
header.classList.remove('sticky');
}
document.addEventListener('scroll', onScroll);
</script>
Pruébala: http://output.jsbin.com/omanut/2/
Esto es bastante fácil, pero este modelo falla rápidamente si quieres hacerlo para muchos nodos DOM, por ejemplo, cada título <h1>
de un blog a medida que el usuario se desplaza.
Por qué JS no es ideal
En general, los controladores de desplazamiento nunca son una buena idea. Las personas tienden a hacer demasiado trabajo y se preguntan por qué su IU es inestable.
Otro aspecto que debes tener en cuenta es que cada vez más navegadores implementan el desplazamiento acelerado por hardware para mejorar el rendimiento. El problema con esto es que, cuando se usan controladores de desplazamiento de JS, los navegadores pueden volver a un modo más lento (de software). Ahora ya no se ejecuta en la GPU. En cambio, estamos de vuelta en la CPU. ¿El resultado? Los usuarios perciben más interrupciones cuando se desplazan por tu página.
Por lo tanto, tiene mucho sentido que esa función sea declarativa en CSS.
Asistencia
Lamentablemente, no hay una especificación para esto. Se propuso en www-style en junio y acaba de llegar a WebKit. Eso significa que no hay documentación adecuada a la que hacer referencia. Sin embargo, según este error, si se especifican left
y right
, left
prevalece. Del mismo modo, si se usan top
y bottom
al mismo tiempo, gana top
.
Actualmente, la compatibilidad es con Chrome 23.0.1247.0 y versiones posteriores (Canary actual) y WebKit nocturno.