En muchas webs se suele ver el uso de ‘position:fixed’ para mantener visible un elemento en todo momento aunque se haga scroll en la página. Por ejemplo, podemos ver este efecto en la web de Privalia, donde el menú de navegación permanece siempre a la vista. El problema de ‘position:fixed’ es que la mayor parte de las veces necesita la ayuda de JavaScript para que podamos lograr el efecto que generalmente deseamos. En el ejemplo de Privalia, el elemento con ‘position:fixed’ se mantiene fijado al viweport pero respecto a un elemento padre para no pisar la cabecera o el pie de la página, algo que hay que hacer mediante JavaScript.
Es por ello, que creo que sería interesante plantear un cambio en la especificación, de forma que ‘position:fixed’ adquiera posición y dimensiones relativas al elemento parent inmediato con ‘position:relative’ manteniendo la posición dentro del área del viewport.
En el siguiente ejemplo, vemos el funcionamiento normal de ‘position:fixed’ sin el apoyo de JavaScript, en el que el elemento con ‘position:fixed’ se muestra siempre en la misma posición respecto al viewport al mover los scrolls del ejemplo. En este ejemplo la parte relevante del código es únicamente el CSS del elemento fijado.
1 2 3 4 5 |
.fixed{ position: fixed; top:100px; width: 80px } |
Los dos problemas de este CSS, respecto al problema que se plantea, es que tanto la posición top como la dimensión width son relativas al viewport y no a un elemento parent, por lo que no podemos conseguir un efecto de un elemento fixed respecto al elemento parent. El elemento siempre están en la misma posición respecto al viewport y no podemos hacer más interacción al respecto sobre él.
En el siguiente ejemplo, hemos usado JavaScript para conseguir el efecto que deseaba sobre el elemento con ‘position:fixed’. El elemento se mantiene visible dentro del viewport pero dentro del área del elemento parent. De forma que si el elemento parent sale del viewport el elemento con ‘position:fixed’ también sale con él. Podemos comparar el comportamiento de ambos ejemplos moviendo los scrolls vertical y horizontal. En muchos casos nos solemos olvidar del scroll horizontal, como en el caso de Privalia. Además de la posición, hay que tener en cuenta el ancho del elemento con ‘position:fixed’ cuando el parent tiene un ancho en porcentajes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
$(document).ready(function(){ var top,bottom, y, page; var left = $('.tofix').offset().left; tofixwidth(); $(window).scroll(function (event) { // what the y position of the scroll is controlArticlePositions(); // whether that's below the form if (y >= top && y<=bottom && y > page) { $('.tofix').addClass('fixed'); //control horizontal scroll tofixl = left-x; $('.tofix').css('left', tofixl); } else { $('.tofix').removeClass('fixed'); } }); $(window).resize(function() { tofixwidth(); }); function controlArticlePositions(){ page = $('.page').offset().top; pageb = $('.tofix').height(); top = $('.tofix').offset().top; bottom = page + $('.page').height() - pageb; y = $(window).scrollTop(); x = $(window).scrollLeft(); } function tofixwidth(){ $('.tofix').css('width', ''); var sidebarW = $('.tofix').closest('.sidebar').css('width'); $('.tofix').css('width', sidebarW); } }); |