Vamos a crear un efecto de imagen emergente con ruta de clip SVG | Programar Plus

Hace unas semanas, me topé con este genial efecto pop-out de Mikael Ainalem. Muestra el clip-path: path() en CSS, que acaba de obtener el soporte adecuado en la mayoría de los navegadores modernos. Quería investigarlo yo mismo para tener una mejor idea de cómo funciona. Pero en el proceso, encontré algunos problemas con clip-path: path(); y terminé encontrando un enfoque alternativo que quería explicar contigo en este artículo.

Si no has usado clip-path o no está familiarizado con él, básicamente nos permite especificar una región de visualización para un elemento en función de una ruta de recorte y ocultar partes del elemento que quedan fuera de la ruta de recorte.

Un rectángulo con un patrón pastel, más una forma de estrella sin relleno con un borde negro, equivale a una forma de estrella con un patrón de fondo pastel.Puede pensar que la estrella es un cortador de galletas, el elemento es la masa para galletas y el resultado es una galleta en forma de estrella.

Posibles valores para clip-path incluir circle , ellipse y polygon que limitan el caso de uso a solo esas formas específicas. Aquí es donde el nuevo path entra el valor: nos permite usar una ruta SVG más flexible para crear varias rutas de recorte que van más allá de las formas básicas.

Tomemos lo que sabemos sobre clip-path y empezar a trabajar en el efecto de desplazamiento. La idea básica de es hacer que la imagen de primer plano de una persona parezca sobresalir del fondo colorido y aumente de tamaño cuando se desplaza el elemento. Un detalle importante es cómo la animación de la imagen de primer plano (ampliar y mover hacia arriba) parece ser independiente de la animación de la imagen de fondo (ampliar únicamente).

Este efecto se ve genial, pero hay algunos problemas con el path valor. Para empezar, si bien mencionamos que el soporte generalmente es bueno, no es excelente y ronda el 82% de cobertura en el momento de escribir este artículo. Por lo tanto, tenga en cuenta que la compatibilidad con dispositivos móviles actualmente se limita a Chrome y Safari.

Además del soporte, el problema más grande y extraño con path es eso actualmente solo funciona con valores de píxeles, lo que significa que no responde. Por ejemplo, digamos que hacemos zoom en la página. Desde el principio, la forma de la ruta comienza a cortar las cosas.

Esto limita severamente el número de casos de uso para clip-path: path(), ya que solo se puede utilizar en elementos de tamaño fijo. El diseño web receptivo ha sido un estándar ampliamente aceptado durante muchos años, por lo que es extraño ver una nueva propiedad CSS que no sigue el principio y usa exclusivamente unidades de píxeles.

Lo que vamos a hacer es volver a crear este efecto utilizando técnicas CSS estándar ampliamente admitidas para que no solo funcione, sino que también responda realmente.

la parte complicada

Queremos cualquier cosa que desborde el clip-path ser visible solo en la parte superior de la imagen. No podemos usar un CSS estándar overflow propiedad ya que afecta tanto a la parte superior como a la inferior.

Foto de una mujer joven contra un patrón floral pastel recortada en forma de círculo.Utilizando overflow-y: hidden, la parte inferior se ve bien, pero la imagen está recortada en la parte superior donde debería verse el desbordamiento.

Entonces, ¿cuáles son nuestras opciones además de overflow y clip-path? Bueno, usemos <clipPath> en el propio SVG. <clipPath> es una propiedad SVG, que es diferente a la recién lanzada y que no responde clip-path: path.

SVG <clipPath> elemento

SVG <clipPath> y <path> los elementos se adaptan al sistema de coordenadas del elemento SVG, por lo que responden desde el primer momento. A medida que se escala el elemento SVG, también se escala su sistema de coordenadas y mantiene sus proporciones en función de las diversas propiedades que cubren una amplia gama de posibles casos de uso. Como beneficio adicional, usar clip-path en CSS en SVG tiene un 95 % de compatibilidad con el navegador, lo que representa un aumento del 13 % en comparación con clip-path: path.

Comencemos configurando nuestro elemento SVG. He usado Inkscape para crear el marcado SVG básico y las rutas de recorte, solo para que me sea más fácil. Una vez que hice eso, actualicé el marcado agregando mis propios atributos de clase.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 100 120" class="image">
  <defs>
    <clipPath id="maskImage" clipPathUnits="userSpaceOnUse">
      <path d="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." />
    </clipPath>
    <clipPath id="maskBackground" clipPathUnits="userSpaceOnUse">
      <path d="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." />
    </clipPath>
  </defs>
  <g clip-path="url(#maskImage)" transform="translate(0 -7)">
    <!-- Background image -->
    <image clip-path="url(#maskBackground)" width="120" height="120" x="70" y="38" href="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." transform="translate(-90 -31)" />
    <!-- Foreground image -->
    <image width="120" height="144" x="-15" y="0" fill="none" class="image__foreground" href="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." />
  </g>
</svg>

Un círculo verde brillante con una forma roja brillante saliendo de la parte superior, como si hubiera otra forma detrás del círculo verde.SVG <clipPath> elementos creados en Inkscape. El elemento verde representa un trazado de recorte que se aplicará a la imagen de fondo. El rojo es un trazado de recorte que se aplicará tanto a la imagen de fondo como a la de primer plano.

Este marcado se puede reutilizar fácilmente para otras imágenes de fondo y de primer plano. Solo necesitamos reemplazar la URL en el href atributo dentro image elementos.

Ahora podemos trabajar en la animación flotante en CSS. Podemos arreglárnoslas con transformaciones y transiciones, asegurándonos de que el primer plano esté bien centrado, luego escalando y moviendo cosas cuando se lleva a cabo el desplazamiento.

.image {
  transform: scale(0.9, 0.9);
  transition: transform 0.2s ease-in;
}

.image__foreground {
  transform-origin: 50% 50%;
  transform: translateY(4px) scale(1, 1);
  transition: transform 0.2s ease-in;
}

.image:hover {
  transform: scale(1, 1);
}

.image:hover .image__foreground {
  transform: translateY(-7px) scale(1.05, 1.05);
}

Aquí está el resultado del código HTML y CSS anterior. Intente cambiar el tamaño de la pantalla y cambie las dimensiones del elemento SVG para ver cómo el efecto se escala con el tamaño de la pantalla.

¡Esto se ve genial! Sin embargo, no hemos terminado. Todavía tenemos que solucionar algunos problemas que tenemos ahora que hemos cambiado el marcado de un elemento de imagen HTML a un elemento SVG.

SEO y accesibilidad

Los rastreadores de búsqueda no indexarán los elementos SVG en línea. Si los elementos SVG son una parte importante del contenido, el SEO de su página podría verse afectado porque esas imágenes probablemente no se recogerán.

Necesitaremos marcas adicionales que utilicen un <img> elemento que está oculto con CSS. Las imágenes declaradas de esta manera son recogidas automáticamente por los rastreadores y podemos proporcionar enlaces a esas imágenes en un mapa del sitio de imágenes para asegurarnos de que los rastreadores logren encontrarlas. estamos usando loading="lazy" lo que permite que el navegador decida si se debe aplazar la carga de la imagen.

Envolveremos ambos elementos en un <figure> elemento para que el marcado refleje la relación entre esas dos imágenes y las agrupe:

<figure>
  <!-- SVG element -->
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 100 120" class="image">
     <!-- ... -->
  </svg>
  <!-- Fallback image -->
  <img src="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." alt="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." loading="lazy" class="fallback-image" />
</figure>

También debemos abordar algunos problemas de accesibilidad para este efecto. Más específicamente, debemos realizar mejoras para los usuarios que prefieren navegar por la web sin animaciones y los usuarios que navegan por la web usando lectores de pantalla.

Hacer que los elementos SVG sean accesibles requiere mucho marcado adicional. Además, si queremos eliminar las transiciones, tendríamos que anular algunas propiedades de CSS que pueden causar problemas si las especificidades de nuestro selector no son consistentes. Afortunadamente, nuestra imagen regular recién agregada tiene excelentes funciones de accesibilidad incorporadas y puede servir fácilmente como reemplazo para los usuarios que navegan por la web sin animaciones.

<figure>
  <!-- Animated SVG element -->
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 100 120" class="image" aria-hidden="true">
    <!-- ... -->
  </svg>

  <!-- Fallback SEO & a11y image -->
  <img src="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." alt="https://css-tricks.com/lets-create-an-image-pop-out-effect-with-svg-clip-path/..." loading="lazy" class="fallback-image" />
</figure>

Necesitamos ocultar el elemento SVG de los dispositivos de asistencia, agregando aria-hidden="true", y necesitamos actualizar nuestro CSS para incluir el prefers-reduced-motion consulta de medios Inclusive, ocultamos la imagen alternativa para los usuarios sin la preferencia de movimiento reducida, mientras que la mantenemos disponible para dispositivos de asistencia como lectores de pantalla.

@media (prefers-reduced-motion: no-preference) {
.fallback-image {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
  } 
}

@media (prefers-reduced-motion) {
  .image {
    display: none;
  }
}

Aquí está el resultado después de las mejoras:

Tenga en cuenta que estas mejoras no cambiarán la apariencia y el comportamiento del efecto para los usuarios que no tienen la prefers-reduced-motion conjunto de preferencias o que no utilizan lectores de pantalla.

Eso es un envoltorio

Los desarrolladores estaban entusiasmados con path opción para clip-path Atributo CSS y nuevas posibilidades de estilo, pero a muchos les disgustó descubrir que estos valores solo admiten valores de píxel. Eso no solo significa que la función no responde, sino que limita severamente la cantidad de casos de uso en los que nos gustaría usarla.

Convertimos un interesante efecto de desplazamiento emergente de imagen que utiliza clip-path: path en un elemento SVG que utiliza la capacidad de respuesta del <clipPath> Elemento SVG para lograr lo mismo. Pero al hacerlo, introdujimos algunos problemas de SEO y accesibilidad, que logramos solucionar con un poco de marcado adicional y una imagen alternativa.

¡Gracias por tomarse el tiempo de leer este artículo! Avíseme si este enfoque le dio una idea sobre cómo implementar sus propios efectos y si tiene alguna sugerencia sobre cómo abordar este efecto de una manera diferente.