Creación de mapas animados en los que se puede hacer clic con la pseudoclase relacional :has()

Creación de mapas animados en los que se puede hacer clic con la pseudoclase relacional :has() |  consejos CSS

CSS :has() la pseudo clase se implementa en muchos navegadores con Cromo y Safari ya lo apoya totalmente. A menudo se le llama "selector principal", ya que podemos seleccionar el estilo de un elemento principal de un selector secundario, pero hay mucho más que :has() puede ayudarnos a resolver. Una de esas cosas es reinventar la plantilla de mapa en la que se puede hacer clic que a muchos de nosotros nos gusta usar de vez en cuando.

 

veremos como :has() puede ayudarnos a administrar mapas vinculados, pero primero…

qué es :has() pseudoclase?

Ya hay un montón de excelentes publicaciones flotando que hacen un gran trabajo al explicar qué :has() es y para qué sirve, pero todavía es lo suficientemente nuevo como para que también debamos decir algunas palabras al respecto aquí.

:has() es una pseudoclase relacional que forma parte del borrador de trabajo W3C Selectors Level 4. Para eso están los paréntesis: hacer coincidir elementos que están relacionados con, o, más exactamente, contienen, ciertos elementos secundarios.

/* Matches an article element that contains an image element */
article:has(img) { }

/* Matches an article element with an image contained immediately within it */
article:has(> img) { }

Entonces puede ver por qué podríamos querer llamarlo selector "principal". Pero también podemos combinarlo con otras pseudoclases funcionales para ser más precisos. Digamos que queremos diseñar artículos que no no contienen imágenes. Podemos combinar los poderes relacionales de :has() con los poderes de negación de :not() para hacer esto:

/* Matches an article without images  */
article:not(:has(img)) { }

Pero eso es solo el comienzo de cómo podemos combinar los poderes para hacer más con :has(). Antes de pasar específicamente a resolver el enigma de los mapas en los que se puede hacer clic, veamos algunas formas en que actualmente los abordamos sin usar :has().

Cómo manejamos actualmente los mapas en los que se puede hacer clic

Hay tres enfoques principales sobre cómo las personas crean un mapa en el que se puede hacer clic en estos días y para comprender completamente el poder de esta pseudoclase, es bueno tener un poco de síntesis.

Este enfoque es algo que se usa con bastante frecuencia. Nunca uso este enfoque, pero creé una demostración rápida para demostrarlo:

Hay muchas preocupaciones aquí, especialmente cuando se trata de accesibilidad. Cuando los usuarios navegan por su sitio web utilizando la función de rotor, escuchan el texto completo en su interior. <a> elemento: el título, el texto y el enlace. Alguien podría no querer sentarse a través de todo. Podemos hacerlo mejor. Desde HTML5 podemos anidar elementos de bloque dentro de un <a> elemento. Pero nunca se siente bien para mí, sobre todo por esta razón.

Ventajas:

  • Rápido de implementar
  • semánticamente correcto

Los inconvenientes:

  • Problemas de accesibilidad
  • Texto no seleccionable
  • Muchos problemas para sobrescribir los estilos que usaste en tus enlaces predeterminados

El método JavaScript

Usando JavaScript podemos adjuntar un enlace a nuestro mapa en lugar de escribirlo en el marcado. Encontré esta excelente demostración de CodePen de costdev que también hizo que el texto del mapa se pudiera seleccionar en el proceso:

Este enfoque tiene muchas ventajas. Nuestros enlaces son accesibles en foco e incluso podemos seleccionar texto. Pero hay algunas desventajas cuando se trata de estilo. Si queremos animar estos mapas, por ejemplo, debemos agregar :hover estilos en nuestro principal .card envoltorio en lugar del enlace en sí. Tampoco nos beneficiaríamos de las animaciones cuando los enlaces se enfocan desde la pestaña del teclado.

Ventajas:

  • Se puede hacer perfectamente accesible
  • Posibilidad de seleccionar texto

Los inconvenientes:

  • Requiere JavaScript
  • No se puede hacer clic derecho (aunque esto se puede solucionar con algunos scripts más)
  • Requerirá una gran cantidad de estilo en el mapa en sí, lo que no funcionaría al modificar el enlace.

los ::after enfoque selector

Este método requiere que establezcamos el mapa con un posicionamiento relativo y luego establezcamos un posicionamiento absoluto en el enlace. ::after pseudoselector de un enlace. Esto no requiere JavaScript y es bastante fácil de implementar:

Aquí hay algunos inconvenientes, especialmente cuando se trata de seleccionar texto. A menos que proporcione un índice z más alto en el cuerpo de su tarjeta, no podrá seleccionar texto, pero si lo hace, tenga en cuenta que hacer clic en el texto no activará su enlace. Depende de usted si desea o no texto seleccionable. Creo que esto puede ser un problema de UX, pero depende del caso de uso. El texto sigue siendo accesible para los lectores de pantalla, pero mi principal problema con el método es la falta de posibilidades de animación.

Ventajas:

  • Fácil de implementar
  • Enlace accesible sin texto inflado
  • Funciona en hover y focus

Los inconvenientes:

  • El texto no es seleccionable
  • Solo puede animar el enlace porque ese es el elemento sobre el que se desplaza.

Un nuevo enfoque: usar ::after con :has()

Ahora que hemos establecido los enfoques existentes para los mapas en los que se puede hacer clic, quiero mostrar cómo la introducción :has() a la mezcla resuelve la mayoría de estas deficiencias.

De hecho, vamos a basar este enfoque en el último que vimos usando ::after en el elemento de enlace. En realidad podemos usar :has() allí para superar las limitaciones de animación de este enfoque.

Comencemos con el marcado:

<article>
  <figure>
    <img src="https://css-tricks.com/creating-animated-clickable-cards-with-the-has-relational-pseudo-class/cat.webp" alt="Fluffy gray and white tabby kitten snuggled up in a ball." />
  </figure>
  <div clas="article-body">
    <h2>Some Heading</h2>
    <p>Curabitur convallis ac quam vitae laoreet. Nulla mauris ante, euismod sed lacus sit amet, congue bibendum eros. Etiam mattis lobortis porta. Vestibulum ultrices iaculis enim imperdiet egestas.</p>
    <a href="#">
      Read more
       <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
         <path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
       </svg>
    </a>
  </div>
</article>

Voy a mantener las cosas lo más simples posible apuntando a elementos en el CSS en lugar de clases.

Para esta demostración, agregaremos un zoom y una sombra de imagen al mapa al pasar el mouse, animaremos el enlace con una flecha que aparece y cambiaremos el color del texto del enlace. Para facilitar esto, agregaremos algunas propiedades personalizadas en nuestro mapa. Aquí está el estilo básico:

/* The card element */
article {
  --img-scale: 1.001;
  --title-color: black;
  --link-icon-translate: -20px;
  --link-icon-opacity: 0;

  position: relative;
  border-radius: 16px;
  box-shadow: none;
  background: #fff;
  transform-origin: center;
  transition: all 0.4s ease-in-out;
  overflow: hidden;
}
/* The link's ::after pseudo */
article a::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  cursor: pointer;
}

¡Excelente! Agregamos una escala inicial para la imagen (--img-scale: 1.001), el color inicial del encabezado de la tarjeta (--title-color: black) y algunas propiedades más que usaremos para sacar nuestra flecha del enlace. También hemos definido un estado vacío del box-shadow declaración para animarla más tarde. Esto configura lo que necesitamos para el mapa en el que se puede hacer clic en este momento, así que agreguemos algunos reinicios y estilo al agregar estas propiedades personalizadas a los elementos que queremos animar:

article h2 {
  margin: 0 0 18px 0;
  font-family: "Bebas Neue", cursive;
  font-size: 1.9rem;
  letter-spacing: 0.06em;
  color: var(--title-color);
  transition: color 0.3s ease-out;
}
article figure {
  margin: 0;
  padding: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
article img {
  max-width: 100%;
  transform-origin: center;
  transform: scale(var(--img-scale));
  transition: transform 0.4s ease-in-out;
}
article a {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: #28666e;
}
article a:focus {
  outline: 1px dotted #28666e;
}
article a .icon {
  min-width: 24px;
  width: 24px;
  height: 24px;
  margin-left: 5px;
  transform: translateX(var(--link-icon-translate));
  opacity: var(--link-icon-opacity);
  transition: all 0.3s;
}

.article-body {
  padding: 24px;
}

Seamos amables con la gente y también agreguemos una clase de lector de pantalla oculta detrás del enlace:

.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

Nuestro menú empieza a verse bonito. Es hora de agregarle algo de magia. Con el :has() pseudo clase, ahora podemos verificar si nuestro enlace está sobrevolado o apuntado, luego actualice nuestras propiedades personalizadas y agregue un box-shadow. Con esta pequeña pieza de CSS, nuestro mapa realmente cobra vida:

/* Matches an article element that contains a hover or focus state */
article:has(:hover, :focus) {
  --img-scale: 1.1;
  --title-color: #28666e;
  --link-icon-translate: 0;
  --link-icon-opacity: 1;

  box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
}

¿Ves lo que hay ahí arriba? Ahora tenemos los estilos actualizados si no importa cual el elemento secundario del mapa está sobre o apuntado. Y aunque el elemento de enlace es lo único que puede contener el estado de enfoque o desplazamiento en el ::after enfoque de mapa en el que se puede hacer clic, podemos usarlo para hacer coincidir el elemento principal y aplicar las transiciones.

Y ahí tienes. Solo otro poderoso caso de uso para el :has() selector. No solo podemos hacer coincidir un elemento padre declarando otros elementos como argumentos, sino que también podemos usar nicks para hacer coincidir y diseñar a los padres.

Ventajas:

  • Accesible
  • Animable
  • No se requiere JavaScript
  • Usos :hover en el elemento correcto

Los inconvenientes:

  • El texto no es fácilmente seleccionable.
  • El soporte del navegador está limitado a Chrome y Safari (compatible con Firefox detrás de una bandera).

Aquí hay una demostración usando esta técnica. Es posible que observe un envoltorio adicional alrededor del mapa, pero solo soy yo jugando con las solicitudes de contenedores, que es solo una de esas otras cosas fantásticas que se implementan en todos los principales navegadores.

¿Tienes otros ejemplos que quieras compartir? Cualquier otra solución o idea es más que bienvenida en la sección de comentarios.

Si quieres conocer otros artículos parecidos a Creación de mapas animados en los que se puede hacer clic con la pseudoclase relacional :has() 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