El truco de archivos adjuntos de fondo fijo | Programar Plus

¿Qué opciones tiene si desea que el fondo del cuerpo esté en una posición fija donde permanezca en el desplazamiento? background-attachment: fixed en CSS, en el mejor de los casos, no funciona bien en los navegadores móviles y, en el peor de los casos, ni siquiera es compatible con los navegadores móviles más utilizados. Puede deshacerse de esta idea por completo y dejar que el fondo se desplace en pantallas pequeñas mediante consultas de medios.

O evitarlo con una pequeña solución. Supongo que podríamos llamarlo un “truco”, ya que es una solución en el código que posiblemente no deberíamos tener que hacer en absoluto.

La cuestión

Antes de mostrarle la solución, examinemos el problema. Podemos verlo observando dos enfoques diferentes de los fondos CSS:

  1. un fondo con un degradado lineal
  2. un fondo usando una imagen

Gradiente lineal

Quiero mantener el degradado de fondo en una posición fija en el desplazamiento, así que apliquemos un estilo CSS básico al cuerpo que hace exactamente eso:

body {
  background: linear-gradient(335deg, rgba(255,140,107,1) 0%, rgba(255,228,168,1) 100%);
  background-attachment: fixed;
  background-position: center;
  background-repeat: no-repeat;
  height: 100vh;
}

Estos son los resultados en Chrome y Firefox, ambos en Android, respectivamente:

Chrome Android Firefox Android

El degradado simplemente se desplaza junto con otro contenido y luego retrocede. No sé exactamente por qué es eso, tal vez cuando la pestaña URL sube o desaparece en el desplazamiento y el navegador tiene dificultades para volver a renderizar el degradado en tiempo real. Esa es mi mejor suposición, ya que solo parece suceder en navegadores móviles.

Si se pregunta sobre iOS Safari, no lo he probado personalmente en iOS, pero el problema también está ahí. Algunos ya han informado del problema y parece comportarse de manera similar.

Imagen de fondo

Este problema con las imágenes no es diferente.

body {
  background: url(../assets/test_pic.jpg);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
  height: 100vh;
}

La sección gris en la parte superior solo indica la presencia de una barra de URL real en Chrome Android.

Otra cosa interesante a tener en cuenta es que cuando background-attachment: fixed se aplica, la altura se ignora incluso si la especificamos explícitamente. Eso es porque background-attachment calcula una posición de fondo fija en relación con la ventana gráfica.

Incluso si decimos que el cuerpo es 100vh, background-attachment: fixed no está exactamente de acuerdo con él. ¡Extraño! Quizás la razón es que background-attachment: fixed se basa en la ventana gráfica más pequeña posible, mientras que los elementos dependen de la ventana gráfica más grande posible. David Bokan explica:

Longitudes definidas en unidades de ventana gráfica (es decir, vh) no cambiará de tamaño en respuesta a que la barra de URL se muestre u oculte. En lugar de, vh las unidades se ajustarán a la altura de la ventana gráfica como si la barra de URL estuviera siempre oculta. Es decir, vh las unidades se ajustarán a la “ventana gráfica más grande posible”. Esto significa 100vh será mayor que la altura visible cuando se muestre la barra de URL.

Los problemas están bien documentados en caniuse:

  • Firefox no parece admitir el valor local cuando se aplica en un elemento de área de texto.
  • Chrome tiene un problema que ocurre al usar el will-change propiedad en un selector que también tiene background-attachment: fixed definido. Hace que la imagen se corte y gane espacios en blanco a su alrededor.
  • iOS tiene un problema para evitar background-attachment: fixed de ser usado con background-size: cover.

Vamos a arreglarlo

Llámelo un truco temporal, por así decirlo. Es posible que algunos de ustedes ya lo hayan probado. Cualquiera que sea el caso, soluciona el gradiente lineal y los problemas de la imagen de fondo que acabamos de ver.

Entonces, como saben, nos estamos metiendo en problemas con el background-attachment: fixed property y, como habrás adivinado, lo estamos eliminando de nuestro código. Si se trata de la ventana gráfica más pequeña posible, entonces tal vez deberíamos trabajar con un elemento que busque la ventana gráfica más grande posible y la ubique en su lugar.

Entonces, estamos creando dos elementos separados, uno para el background-gradient y otro para el resto del contenido. Nosotros reemplazamos background-attachment: fixed con position: fixed.

<div class="bg"></div>
<div class="content">
  <!-- content -->
</div>
.bg {
  background: linear-gradient(335deg, rgba(255,140,107,1) 0%, rgba(255,228,168,1) 100%);
  background-repeat: no-repeat;
  background-position: center;
  height: 100vh;
  width: 100vw;
  position: fixed;
  /* z-index usage is up to you.. although there is no need of using it because the default stack context will work. */
  z-index: -1; // this is optional
}

Ahora, envuelva el resto del contenido, excepto el elemento que contiene la imagen de fondo, dentro de un contenedor principal.

.content{
  position: absolute;
  margin-top: 5rem;
  left: 50%; 
  transform: translateX(-50%);
  width: 80%;
}

¡Éxito!

Chrome Android Firefox Android

Podemos usar el mismo truco con imágenes de fondo y funciona bien. Sin embargo, obtienes algún tipo de desplazamiento de fondo cuando la barra de URL se oculta, pero el parche blanco ya no está allí.

.img {    
  background: url('../assets/test_pic.jpg');
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: fixed;
  height: 100vh;
  width: 100vw;
}

.content {
  position: absolute;
  left: 50%; 
  margin-top: 5rem;
  transform: translateX(-50%);
  width: 80%;
}

Chrome Android Firefox Android

Aquí están mis conclusiones

Un elemento de posición fija con una altura establecida en 100% se comporta como el elemento con background-attachment: fixed propiedad, que es claramente evidente en el ejemplo siguiente. Simplemente observe la barra más a la derecha (color púrpura) en el video.

El sitio web que se está probando se tomó de este artículo.

Aunque, David Bokan en su artículo afirma que:

Eso es un position: fixed El elemento cuyo bloque contenedor es el ICB cambiará de tamaño en respuesta a la barra de URL que se muestra u oculta. Por ejemplo, si su altura es 100% siempre llenará exactamente la altura visible, se muestre o no la barra de URL. Similarmente para vh longitudes, también cambiarán de tamaño para coincidir con la altura visible teniendo en cuenta la posición de la barra de URL.

Si tomamos en cuenta la última oración, ese no parece ser el caso aquí. Los elementos que tienen un posicionamiento fijo y una altura de 100vh no cambian su altura tanto si se muestra la barra de URL como si no. De hecho, la altura está de acuerdo con la altura de la “ventana gráfica más grande posible”. Esto es evidente en el ejemplo siguiente. Solo observe la barra de color azul claro en el video.

El sitio web que se está probando se tomó de este artículo.

Entonces, parece que, cuando se trabaja con un contenedor de 100vh, background-attachment: fixed considera la altura de ventana gráfica más pequeña posible, mientras que los elementos en general consideran la altura de ventana gráfica más grande posible.

Por ejemplo, background-attachment: fixed simplemente deja de funcionar cuando es necesario volver a pintar, como cuando la barra de direcciones de un navegador móvil desaparece al desplazarse. El navegador ajusta el fondo de acuerdo con la ventana gráfica más grande posible (que ahora es, de hecho, la ventana gráfica más pequeña posible ya que la barra de URL está oculta) y el navegador no es lo suficientemente eficiente como para volver a pintar sobre la marcha, lo que da como resultado un retraso importante.

Nuestro truco aborda esto haciendo que el fondo sea un elemento en lugar de, bueno, un fondo real. Le damos al elemento que contiene el contenido una posición absoluta para apilarlo encima del elemento que contiene la imagen, luego aplicamos una posición fija en este último. ¡Oye, funciona!

Tenga en cuenta que la altura de la ventana gráfica se calcula excluyendo la barra de navegación en la parte inferior (si está presente). Aquí hay una comparación entre la presencia y la ausencia de la barra de navegación en la parte inferior en Chrome Android.

¿Hay alguna desventaja? ¡Quizás! Estamos usando un general <div> en lugar de un real <img> etiqueta, por lo que no diría que el marcado es semántico. Y eso puede generar problemas de accesibilidad. Si está trabajando con una imagen que agrega significado o contexto al contenido, entonces una <img> es el camino correcto a seguir, utilizando un adecuado alt descripción para lectores de pantalla.

Pero si vamos por el camino correcto <img> ruta, luego estamos de regreso donde comenzamos. Además, si tiene una barra de navegación en la parte inferior que también se oculta automáticamente, no puedo evitarlo. Si el truco no funciona, entonces quizás JavaScript pueda venir al rescate.

(Visited 5 times, 1 visits today)