Hay un número creciente de funciones “personalizadas” en la plataforma web. Tenemos propiedades personalizadas (--my-property
), elementos personalizados (<my-element>
), y eventos personalizados (new CustomEvent('myEvent')
). En un momento, incluso podríamos obtener consultas de medios personalizadas (@media (--my-media)
).
¡Pero eso no es todo! Es posible que te lo hayas perdido porque no se mencionó en el artículo “Novedades en Chrome 90” de Google (para ser justos, el Shadow DOM declarativo se robó el espectáculo en esta versión), pero Chrome acaba de agregar soporte para otra característica “personalizada”: personalizada pseudo-clases de estado (:--my-state
).
Estados integrados
Antes de hablar sobre los estados personalizados, echemos un vistazo rápido a los estados integrados que se definen para los elementos HTML integrados. El módulo de selectores de CSS y la sección “Pseudoclases” del estándar HTML especifican una serie de pseudoclases que se pueden usar para hacer coincidir elementos en diferentes estados. Las siguientes pseudoclases son ampliamente compatibles con los navegadores actuales:
Acción del usuario | |
---|---|
:hover |
el cursor del ratón se desplaza sobre el elemento |
:active |
el elemento está siendo activado por el usuario |
:focus |
el elemento tiene el foco |
:focus-within |
el elemento tiene o contiene el foco |
Ubicación | |
:visited |
el enlace ha sido visitado por el usuario |
:target |
el elemento está dirigido por el fragmento de la URL de la página |
Aporte | |
:disabled |
el elemento de formulario está deshabilitado |
:placeholder-shown |
el elemento de entrada muestra texto de marcador de posición |
:checked |
la casilla de verificación o el botón de radio está seleccionado |
:invalid |
el valor del elemento del formulario no es válido |
:out-of-range |
el valor del elemento de entrada es fuera del rango especificado |
:-webkit-autofill |
el elemento de entrada ha sido autocompletado por el navegador |
Otro | |
:defined |
el elemento personalizado ha sido registrado |
Nota: Por razones de brevedad, se han omitido algunas pseudoclases y algunas descripciones no mencionan todos los casos de uso posibles.
Estados personalizados
Al igual que los elementos incorporados, los elementos personalizados pueden tener diferentes estados. Una página web que utiliza un elemento personalizado puede querer diseñar estos estados. El elemento personalizado podría exponer sus estados a través de clases CSS (class
atributo) en su elemento host, pero eso se considera un antipatrón.
Chrome ahora admite una API para agregar estados internos a elementos personalizados. Estos estados personalizados se exponen a la página exterior a través de pseudoclases de estado personalizado. Por ejemplo, una página que utiliza un <live-score>
elemento puede declarar estilos para la costumbre de ese elemento --loading
Expresar.
live-score {
/* default styles for this element */
}
live-score:--loading {
/* styles for when new content is loading */
}
Agreguemos un --checked
estado a un <labeled-checkbox>
elemento
La especificación Custom State Pseudo Class contiene un ejemplo de código completo, que usaré para explicar la API. La parte de JavaScript de esta función se encuentra en la definición de clase del elemento personalizado. En el constructor, se crea un objeto de “elementos internos” para el elemento personalizado. Luego, los estados personalizados se pueden configurar y desactivar en el interno states
objeto.
Tenga en cuenta que el ElementInternals
La API garantiza que los estados personalizados sean de solo lectura para el exterior. En otras palabras, la página exterior no puede modificar los estados internos del elemento personalizado.
class LabeledCheckbox extends HTMLElement {
constructor() {
super();
// 1. instantiate the element’s “internals”
this._internals = this.attachInternals();
// (other code)
}
// 2. toggle a custom state
set checked(flag) {
if (flag) {
this._internals.states.add("--checked");
} else {
this._internals.states.delete("--checked");
}
}
// (other code)
}
La página web ahora puede diseñar los estados internos del elemento personalizado a través de pseudoclases personalizadas del mismo nombre. En nuestro ejemplo, el --checked
el estado está expuesto a través de la :--checked
pseudo-clase.
labeled-checkbox {
/* styles for the default state */
}
labeled-checkbox:--checked {
/* styles for the --checked state */
}
Prueba la demo en Chrome
Esta característica no es (todavía) un estándar
Los proveedores de navegadores han estado debatiendo durante los últimos tres años cómo exponer los estados internos de los elementos personalizados a través de pseudoclases personalizadas. La especificación de pseudoclase de estado personalizado de Google sigue siendo un “borrador no oficial” alojado por WICG. La función se sometió a una revisión de diseño en el W3C TAG y se entregó al Grupo de trabajo de CSS. En la discusión sobre la “intención de envío” de Chrome, Mounir Lamouri escribió lo siguiente:
Parece que esta característica tiene un buen soporte. Parece que puede ser difícil para los desarrolladores web beneficiarse de él mientras no se distribuya ampliamente, pero es de esperar que Firefox y Safari lo sigan y lo implementen también. Alguien tiene que implementarlo primero, y dado que no hay cambios incompatibles con versiones anteriores previsibles, parece seguro ir primero.
Ahora toca esperar las implementaciones en Firefox y Safari. Los errores del navegador se han archivado (Mozilla #1588763 y WebKit #215911) pero aún no han recibido mucha atención.