Fondos móviles como flotando

Fondos móviles |  Consejos CSS - Consejos CSS

 

A menudo pensamos en las imágenes de fondo como una textura o algo que proporciona contraste para el contenido legible; en otras palabras, no es realmente contenido. Si fuera contenido, probablemente estarías buscando un <img> en fin, accesibilidad y demás.

Pero hay ocasiones en que el posición O trepar de una imagen de fondo puede caer en algún lugar entre los polos de contenido y decoración. El contexto es el rey, ¿verdad? Si cambiamos la posición de la imagen de fondo, puede transmitir un poco más de contexto o experiencia.

¿Cómo? Veamos algunos ejemplos que he visto flotando.

 

Al principio, advierto que existe una línea muy fina en estas demostraciones entre las imágenes utilizadas como decoración y las imágenes utilizadas como contenido. La diferencia tiene implicaciones de accesibilidad cuando los fondos no se anuncian a los lectores de pantalla. Si su imagen realmente es una imagen, tal vez considere una <img> etiqueta con el vale alt texto. Y ya que estamos en el tema de la accesibilidad, es una buena idea considerar también las preferencias de movimiento del usuario.

¡Muestrame mas!

Chris Coyier tiene esta pequeña demostración agradable de hace varios años.

La demostración es muy útil en muchos sentidos, ya que es un enfoque ordenado para mostrar anuncios en el contenido. Tienes el argumento de venta y una imagen atractiva para complementarlo.

El gran límite para la mayoría de los anuncios, apostaría, es la cantidad limitada de bienes raíces. No sé si alguna vez ha tenido que colocar un anuncio en una página, pero yo sí y normalmente le pido al anunciante una imagen que cumpla con las dimensiones exactas en píxeles para que el elemento se ajuste al espacio.

Pero la demostración de Chris alivia el problema del espacio. Pase el cursor sobre la imagen y observe cómo se mueve y escala. El usuario realmente obtiene Más contexto para el producto que tendrían cuando la imagen estuviera en su posición original. Es un ganar-ganar, ¿verdad? El anunciante puede crear una imagen llamativa sin comprometer el contexto. Mientras tanto, el usuario obtiene un pequeño valor adicional de las partes recién reveladas de la imagen.

Si observa el marcado de la demostración, notará que es más o menos lo que esperaría. Aquí hay una versión abreviada:

<div class="ad-container">
  <a href="#" target="_blank" rel="noopener">
    <!-- Background image container  -->
    <div class="ad-image"></div>
  </a> 
  <div class="ad-content">
    <!-- Content -->
  </div>
</div>

Probablemente podríamos cuestionar un poco la semántica, pero ese no es el punto. Tenemos un contenedor con un enlace. <div> para la imagen de fondo y otra <div> para retener el contenido.

Cuando se trata de estilo, las piezas importantes están aquí:

.container {
  background-image: url("/path/to/some/image.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  height: 400px;
  width: 350px;
}

No está mal ¿no? Le damos dimensiones al contenedor y definimos una imagen de fondo en él que no se repite y se posiciona por su borde inferior izquierdo.

El verdadero truco es con JavaScript. Usaremos esto para obtener la posición del mouse y el desplazamiento del contenedor, luego convertiremos ese valor a una escala adecuada para establecer el background-position. Primero, escuchemos los movimientos del ratón sobre la .container elemento:

let container = document.querySelector(".container");
container.addEventListener("mousemove", function(e) {
    // Our function
  }
);

A partir de ahí podemos usar el contenedor. offsetX Y offsetY propiedades. Pero no usaremos estos valores directamente, porque el valor de la coordenada X es más pequeño de lo que necesitamos y la coordenada Y es más grande. Tendremos que jugar un poco para encontrar una constante que podamos usar como multiplicador.

Es un poco delicado, pero encontré que 1.32 Y 0.455 funciona perfectamente para las coordenadas X e Y, respectivamente. Multiplicamos las compensaciones por estos valores, agregamos un px la unidad en el resultado, luego aplicarlo a la background-position valores.

let container = document.querySelector(".container");
container.addEventListener("mousemove", function(e) {
    container.style.backgroundPositionX = -e.offsetX * 1.32 + "px";
    container.style.backgroundPositionY = -e.offsetY * 0.455 + "px";
  }
);

Finalmente, también podemos restablecer las posiciones de fondo a las originales si el usuario abandona el contenedor de imágenes.

container.addEventListener("mouseleave", function() {
    container.style.backgroundPosition = "0px 0px";
  }
);

Ya que estamos en CSS-Tricks, sugiero que podríamos haber hecho una versión mucho más barata de esto con una pequeña transición de desplazamiento en CSS estándar:

Pintar una imagen más grande

Sin duda, ha ido a una tienda de ropa en línea o lo que sea y se ha encontrado con la antigua función de zoom de desplazamiento.

Este modelo existe desde hace mucho tiempo (Dylan Winn-Brown compartió su enfoque en 2016), pero eso es solo un testimonio (con suerte) de lo útil que es. El usuario obtiene más contexto al hacer zoom y tiene una mejor idea de cómo coser un suéter o lo que tienes.

Hay dos elementos en esto: envase y el lupa. El contenedor es lo único que necesitamos en el marcado, ya que inyectaremos el elemento de lupa en la interacción del usuario. Así que aquí está nuestro HTML!

<div class="container"></div>

En el CSS crearemos width Y height variables para almacenar las dimensiones de la propia lupa. Entonces le daremos eso .containeruna forma y un background-image​:

​​:root {
​​  --magnifer-width: 85;
​​  --magnifer-height: 85;
​​}

.container {
  width: 500px;
  height: 400px;
  background-size: cover;
  background-image: url("/path/to/image.png");
  background-repeat: no-repeat;
  position: relative;
}

Hay algunas cosas que ya sabemos sobre la lupa incluso antes de que la veamos, y podemos definir estos estilos de antemano, especialmente las variables previamente definidas para el .maginifierEs width Y height:

.magnifier {
  position: absolute;
  width: calc(var(--magnifer-width) * 1px);
​​  height: calc(var(--magnifer-height) * 1px);
​​  border: 3px solid #000;
​​  cursor: none;
​​  background-image: url("/path/to/image.png");
​​  background-repeat: no-repeat;
}

Es un pequeño cuadrado absolutamente posicionado que utiliza el incluso archivo de imagen de fondo como .container. Tenga en cuenta que la función calc solo se usa aquí para convertir el valor sin unidades de la variable en píxeles. Siéntase libre de organizar esto como mejor le parezca para eliminar la repetición en su código.

Ahora pasemos al JavaScript que lo une todo. Primero necesitamos acceder a la variable CSS definida anteriormente. Lo usaremos en varios lugares más adelante. A continuación, necesitamos obtener la posición del mouse en el contenedor porque ese es el valor que usaremos para la posición de fondo de la lupa.

​​// Get the css variables
​​let root = window.getComputedStyle(document.documentElement);
​​let magnifier_width = root.getPropertyValue("--magnifer-width");
​​let magnifier_height = root.getPropertyValue("--magnifer-height");

let container = document.querySelector(".container");
let rect = container.getBoundingClientRect();
let x = (e.pageX - rect.left);
let y = (e.pageY - rect.top);

// Take page scrolling into account
x = x - window.pageXOffset;
y = y - window.pageYOffset;

Lo que necesitamos es básicamente un mousemove detector de eventos en el .container. Luego usaremos el event.pageX O event.pageY propiedad para obtener la coordenada X o Y del mouse. Pero para conseguir el exacto posición relativa del mouse en un elemento, debemos restar la posición del elemento principal de la posición del mouse que obtenemos del JavaScript anterior. Una forma "simple" de hacer esto es usar getBoundingClientRect()que devuelve el tamaño de un elemento y su posición relativa a la ventana.

Fíjate cómo considero el desplazamiento. Si hay desbordamiento, reste la ventana pageX Y pageY las compensaciones asegurarán que el efecto se ejecute como se esperaba.

Primero crearemos el div lupa. A continuación crearemos un mousemove y agréguelo al contenedor de imágenes. En esta función, le daremos a la lupa un atributo de clase. También calcularemos la posición del mouse y le daremos a la lupa los valores izquierdo y superior que calculamos anteriormente.

Sigamos adelante y construyamos magnifier cuando escuchamos un mousemove evento en el .container:

// create the magnifier
let magnifier = document.createElement("div");
container.append(magnifier);

Ahora debemos asegurarnos de que tenga un nombre de clase que podamos extender a CSS:

// run the function on `mousemove`
container.addEventListener("mousemove", (e) => {
  magnifier.setAttribute("class", "magnifier");
}

El video de ejemplo que mostré anteriormente coloca la lupa fuera del contenedor. Lo mantendremos simple y lo superpondremos sobre el contenedor mientras se mueve el mouse. Usaremos if para configurar la posición de la lupa solo si los valores X e Y son más grande O igual a cero, y menos que el ancho o la altura del contenedor. Esto debería mantenerlo dentro de los límites. Solo asegúrese de restar el ancho y la altura de la lupa de los valores X e Y.

// Run the function on mouse move.
container.addEventListener("mousemove", (e) => {
  magnifier.setAttribute("class", "magnifier");

  // Get mouse position
  let rect = container.getBoundingClientRect();
  let x = (e.pageX - rect.left);
  let y = (e.pageY - rect.top);
  
  // Take page scrolling into account
  x = x - window.pageXOffset;
  y = y - window.pageYOffset;

  // Prevent magnifier from exiting the container
  // Then set top and left values of magnifier
  if (x >= 0 && x <= container.clientWidth - magnifier_width) {
    magnifier.style.left = x + "px";
  }
  if (y >= 0 && y <= container.clientHeight - magnifier_height) {
    magnifier.style.top = y + "px";
  }
});

Por último, pero no menos importante... tenemos que jugar un poco con la imagen de fondo de la lupa. El beneficio es que el usuario obtiene una MAYOR vista de la imagen de fondo dependiendo de dónde se esté desplazando. Entonces, definamos una lupa que podamos usar para magnificar las cosas. A continuación, estableceremos variables para el ancho y el alto de la imagen de fondo para tener una base en la que basar esa escala, y estableceremos todos esos valores en el .magnifier estilos:

// Magnifier image configurations
let magnify = 2;
let imgWidth = 500;
let imgHeight = 400;

magnifier.style.backgroundSize = imgWidth * magnify + "px " + imgHeight * magnify + "px";

Tomemos las coordenadas X e Y de la imagen de la lupa y aplíquelas a la .magnifierel elemento background-position. Como antes con la posición de la lupa, necesitamos restar el ancho y el alto de la lupa de los valores X e Y usando variables CSS.

// the x and y positions of the magnifier image
let magnify_x = x * magnify + 15;
let magnify_y = y * magnify + 15;

// set backgroundPosition for magnifier if it is within image
if (
  x <= container.clientWidth - magnifier_width &&
  y <= container.clientHeight - magnifier_height
) {
  magnifier.style.backgroundPosition = -magnify_x + "px " + -magnify_y + "px";
}

¡Tada!

Hazlo cinemático

¿Has visto el efecto Ken Burns? Es algo clásico y atemporal donde una imagen es más grande que el contenedor en el que se encuentra, luego se desliza y escala lentamente como una babosa. Prácticamente todos los documentales del mundo parecen usarlo para imágenes fijas. Si tienes un Apple TV, definitivamente lo has visto en el protector de pantalla.

Hay infinidad de ejemplos en CodePen si quieres tener una mejor idea.

Verás que hay varias maneras de abordar esto. Algunos usan JavaScript. Otros son 100% CSS. Estoy seguro de que los enfoques de JavaScript son buenos para algunos casos de uso, pero si el objetivo es cambiar sutilmente el tamaño de la imagen, CSS está bien.

Podríamos animar un poco las cosas usando varios fondos en lugar de uno solo. O, mejor aún, si extendemos las reglas para usar elementos en lugar de imágenes de fondo, podemos aplicar la misma animación a todos los fondos y usar un toque de animation-delay para compensar el efecto.

¡Muchas maneras de hacerlo, por supuesto! Ciertamente se puede optimizar con variables Sass y/o CSS. Diablos, tal vez puedas lograrlo con solo uno <div> Si es así, ¡compártelo en los comentarios!

Bonificación: hazlo inmersivo

No sé si hay algo más genial que el bolígrafo "Feliz Halloween" de Sarah Drasner... ¡y eso es de 2016! Es un gran ejemplo de superponer fondos y moverlos a diferentes velocidades para crear una experiencia casi cinematográfica. ¡Maldita sea, eso es genial!

GSAP es el motor principal, pero imagino que podríamos crear una versión simplificada que simplemente traduzca cada capa de fondo de izquierda a derecha a diferentes velocidades. No tan genial, seguro, pero definitivamente la experiencia base. Asegúrese de que el inicio y el final de cada imagen de fondo sean coherentes para que se repitan sin problemas cuando se repita la animación.


¡Eso es todo por el momento! Lo suficientemente bueno como para que podamos usar fondos para algo más que textura y contraste. Estoy absolutamente seguro de que hay toneladas de otras interacciones inteligentes que podemos aplicar a los fondos. Temani Afif ha hecho exactamente eso con un montón de buenos efectos de desplazamiento para enlaces. ¿En qué piensas? ¡Compártelo conmigo en los comentarios!

Si quieres conocer otros artículos parecidos a Fondos móviles como flotando puedes visitar la categoría Estilo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Esta página web utiliza cookies para analizar de forma anónima y estadística el uso que haces de la web, mejorar los contenidos y tu experiencia de navegación. Para más información accede a la Política de Cookies . Ver mas