Casos de éxito de :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

El CSS siempre se caracterizó por no tener una forma de seleccionar directamente un elemento superior en función de sus elementos secundarios. Esta fue una de las principales solicitudes de los desarrolladores durante muchos años. El selector :has(), que ahora es compatible con todos los navegadores principales, resuelve este problema. Antes de :has(), solías encadenar selectores largos o agregar clases para los hooks de diseño. Ahora puedes aplicar estilos en función de la relación de un elemento con sus descendientes. Obtén más información sobre el :has() selector en CSS Wrapped 2023 y 5 fragmentos de CSS que todo desarrollador de frontend debe conocer.

Aunque este selector parece pequeño, puede habilitar una gran cantidad de casos de uso. En este artículo, se muestran algunos casos de uso que las empresas de comercio electrónico desbloquearon con el selector :has().

Consulta la serie completa de la que forma parte este artículo, en la que se explica cómo las empresas de comercio electrónico mejoraron su sitio web con nuevas funciones de CSS y de IU.

Policybazaar

Con el :has() selector, pudimos eliminar la validación basada en JavaScript de la selección del usuario y reemplazarla por una solución de CSS que funciona sin problemas para nosotros con la misma experiencia que antes.—Aman Soni, líder técnico de Policybazaar

El equipo de inversión de Policybazaar aplicó de forma inteligente el selector :has() para proporcionar una indicación visual clara a los usuarios que comparan planes. En la siguiente imagen, se muestran dos tipos de planes en la IU de comparación (amarillo y azul). Cada plan solo se puede comparar con su propio tipo. :has()Cuando un usuario selecciona un tipo de plan, no se puede seleccionar el otro tipo de plan.

Implementación de :has() para aplicar estilo al elemento superior y a sus elementos secundarios para crear una funcionalidad de selección vinculada a la categoría.

Código

:has() te da acceso a los elementos superiores y sus elementos secundarios. El siguiente código verifica si un contenedor superior tiene establecida una clase .disabled-group. Si es así, la tarjeta aparece atenuada y se impide que el botón "Agregar" reaccione a los clics estableciendo pointer-events en none.

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

El equipo de salud de Policybazaar implementó un caso de uso ligeramente diferente. Tienen un cuestionario intercalado para el usuario y usan :has() para verificar el estado de la casilla de verificación de la pregunta y ver si se respondió. Si es así, se aplica una animación para pasar a la siguiente pregunta.

health.policybazaar.com/

Código

En el ejemplo de comparación de planes, se usó :has() para verificar la presencia de una clase. También puedes verificar el estado de un elemento de entrada, como una casilla de verificación, con :has(input:checked). En la imagen que muestra el cuestionario, cada pregunta en el banner morado es una casilla de verificación. Policybazaar verifica si se respondió la pregunta con :has(input:checked) y, si es así, activa una animación con animation: quesSlideOut 0.3s 0.3s linear forwards para pasar a la siguiente pregunta. Mira cómo funciona en el siguiente código.

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Tokopedia

Tokopedia usó :has() para crear una imagen superpuesta si la miniatura del producto contiene un video. Si la miniatura del producto contiene una clase .playIcon, se agrega una superposición de CSS. Aquí, el selector :has() se usa junto con el selector de anidación & dentro de la clase general .thumbnailWrapper, que se aplica a todas las miniaturas. Esto crea un CSS más modular y legible.

Captura de pantalla de la página de Tokopedia antes y después de usar el selector has.
Antes y después de usar :has().

Código

En el siguiente código, se usan los selectores y combinadores de CSS (& y >) y la anidación con :has() para aplicar estilo a la miniatura. Para los navegadores no compatibles, se usa la regla de clase CSS adicional normal como resguardo. También se usa la regla @supports selector(:has(*)) para verificar la compatibilidad del navegador. Por lo tanto, la experiencia general es la misma en todas las versiones del navegador.

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

Aspectos que debes tener en cuenta cuando usas :has()

Combina :has() con otros selectores para crear una condición más compleja. Consulta algunos ejemplos en has() el selector de familia.

Recursos:

Explora los otros artículos de esta serie en los que se explica cómo las empresas de comercio electrónico se beneficiaron del uso de nuevas funciones de CSS y de IU, como las animaciones controladas por el desplazamiento, las transiciones de vista, las ventanas emergentes y las consultas de contenedores.