Hacking position: fixed & overflow: hidden 5.6.15
Cómo lograr que en un momento dado la declaración position: fixed
tome como referente a su padre y no el viewport y cómo hacer para que el hijo de un elemento con overflow: hidden
no se recorte al sobrepasar sus límites.
Hacking position: fixed & overflow: hidden
A modo de introducción un repaso: la declaración position: fixed
a la hora de ubicarse hace que el elemento deje de tener como referente a su padre o cualquier otro ancestro y que sea la ventana del navegador o el viewport.
Por otra parte, la propiedad overflow
es la que gestiona el qué hacer con la parte del contenido que sobresale (desborda) su caja padre. Y en caso de que su valor sea hidden
la ocultará y no será ni visible ni accesible la parte que sobresalga.
La cuestión entoces es si es posible alterar el resultado sin cambiar los valores fixed
y hidden
.
Hacking position: fixed
Tengamos un elemento con la siguiente regla Css y position: fixed
entre sus declaraciones.
article {
background: #fff;
width: 150px;
height: 120px;
position: fixed;
right: 0;
bottom: 0;
}
Según ella el article
debería pasar de su padre (div
con fondo "tomato") y colocarse en la esquina inferior derecha de la ventana del navegador o del viewport del dispositivo. Es lo que esperarías. Sin embargo mira el pen inferior:
See the Pen Hacking position: fixed by Kseso (@Kseso) on CodePen.
Cuando hablamos en este blog de las transformaciones Css mencionaba que el navegador está obligado a crear un espacio o contexto abstracto donde llevarlas a cabo sin interferir con otros elementos no afectados por ellas (más info en Cómo funciona la propiedad will-change).
Un efecto derivado de este contexto en el que se realizan las transformaciones es el que hace posible el efecto del Parallax puro Css debido al desplazamiento asíncrono de elementos derivado del uso de la propiedad perspective
y transform: translate3d()
.
Ahora vuelve a la demo anterior y observa de nuevo su Css. Verás que el div
con fondo de color "tomato" ha creado este espacio debido a la declaración transform: translate(0,0)
Y otro de los efectos "secundarios" de ella es que para el valor fixed
su referente ya no es el espacio en el que se representa (dibuja) la web (el vieport o ventana). Esta referencia ha sido reemplazada por el elemento que crea ese "espacio o capa" en el que se realiza la transformación.
Observa que para que sea más notorio este hecho el div
no tiene declarado ningún valor a la propiedad position
con lo que es el inicial: static
En unas pruebas rápidas he observado que para "hackear" el valor fixed
sirven cualquiera de las siguientes declaraciones Css. Todas generan la nueva referencia.
transform: translate(0,0);
transform: translate3d(0,0,0);
will-change: transform;
overflow: hidden hackeado
Es conocido que la declaración overflow: hidden
no admite excepciones una vez declarada. Afecta a todo el contenido o se anula para todos.
Ahora tengamos un elemento con overflow: hidden
y que por tanto no permite ver lo que sobrepasa sus límites: recorta todo aquello que vaya más allá de su 'padding'. Sin embargo hay contenido dentro de él otro elemento que sí queremos que lo haga (vete tú a saber el porqué, la razón no importa).
Para lograr romper el recorte de overflow: hidden
de la parte que sobresale necesitamos crear una estructura con 3 contenedores:
<padre>
<hijo>
<nieto></nieto>
</hijo>
</padre>
Contenedores que son necesarios para que cada uno cumpla con lo siguiente:
padre
crea el contexto de desarrollo de la transformación Css.hijo
es el que impide el desborde conoverflow: hidden
nieto
es un elemento que pese al 'overflow' anterior queremos sobresale al declararleposition: fixed
.
See the Pen Hacking overflow: hidden; by Kseso (@Kseso) on CodePen.
Y si me preguntas por alguna utilidad eso ya corre de tu cuenta encontrarla. No querrás que hoy ponga yo todo ;-) =P
Kseso
the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso
Good Read! Eager to try it out.
ResponderEliminar