D’une manière ou d’une autre, il m’a échappé jusqu’à récemment que le CSS element()
La fonction est prise en charge dans Firefox. En fait, cela fait un bon moment (bien qu’il ait encore besoin d’un préfixe). “Qu’est-ce que la fonction element()?”, Je vous entends pleurer. C’est un moyen de rendre un élément HTML en tant que valeur d’image à utiliser dans notre CSS. L’exemple donné sur MDN utilise une image rendue sur un <canvas>
comme image de fond. C’est un cas d’utilisation plutôt cool, bien que l’API CSS Paint nous permette déjà de créer un worklet de peinture et de l’utiliser dans notre CSS – consultez ce tutoriel de Temani Afif. C’est peut-être l’une des raisons pour lesquelles la prise en charge des navigateurs semble avoir stagné ?
element() comme masque
Ce qui m’intéresse, c’est de pouvoir utiliser n’importe quel élément, en particulier comme masque pour un autre. Un exemple est un élément de texte, tel qu’un titre. Nous pouvons appliquer l’élément en tant que masque en référençant son ID :
img {
mask-image: -moz-element(#mask);
}
Ce qui est cool avec le masquage, c’est qu’il se comporte à peu près de la même manière qu’un arrière-plan. On peut appliquer des propriétés telles que mask-size
, mask-repeat
etc. pour obtenir l’effet souhaité.
Dans cette démo, j’utilise un titre (avec un dégradé appliqué) comme masque d’image.
Voir le Pen Masking one element with another par Michelle Barker (@michellebarker) sur CodePen.
Accessibilité
Il y a des problèmes évidents ici, notamment en ce qui concerne l’accessibilité. Quelle est la meilleure expérience pour quelqu’un qui utilise un lecteur d’écran ? Si le masque de texte est répété plusieurs fois, serait-il préférable d’avoir plusieurs éléments ? Ou préférable d’utiliser aria-hidden
pour masquer entièrement l’élément d’un lecteur d’écran et décrire l’effet résultant d’une autre manière (aria-label
ou aria-labelledby
, par exemple). Un <h1>
peut-être pas le bon choix ici, de toute façon. Les réponses à ces questions dépendront invariablement du contexte, différent d’un projet à l’autre.
L’autre problème est de masquer visuellement l’élément d’origine. Comme nous l’utilisons comme masque, nous ne voulons peut-être pas que l’original soit affiché. Vous avez peut-être l’habitude d’utiliser une classe utilitaire pour masquer visuellement des éléments, tout en vous assurant qu’ils peuvent toujours être lus par un logiciel de lecture d’écran :
.visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
(Scott O’Hara a plus d’informations à ce sujet et d’autres méthodes pour masquer le contenu.)
Cela ne fonctionnera pas dans ce cas, car cela rendra l’élément — et donc notre masque — invisible ! Dans la démo, j’ai opté pour le cacher hors écran :
h1 {
position: absolute;
left: -100%;
}
Animation
Un autre cas d’utilisation intéressant pourrait être l’utilisation d’un élément animé comme masque. Cependant, les performances sont assez médiocres, comme nous pouvons le voir sur cette démo. Mais c’est beaucoup mieux lorsqu’il est utilisé comme transition:
Voir le stylo masquant un élément avec un élément animé par Michelle Barker (@michellebarker) sur CodePen.
Avons-nous besoin de element() ?
Il convient de souligner que nous pouvons actuellement obtenir beaucoup de ces effets avec SVG. Mais en tant que personne qui n’aime rien de mieux que de bricoler avec CSS, j’aimerais voir un support généralisé pour element()
pour le codage créatif si rien d’autre, et il y a sans aucun doute de nombreux cas d’utilisation que je n’ai pas encore envisagés.
Vincent De Oliveira a une excellente rédaction d’un certain temps, y compris quelques exemples créatifs. Certaines des démos semblent être cassées dans les navigateurs modernes, mais il y a des vidéos, et c’est génial de s’inspirer de ce qui pourrait être possible.
Il y a actuellement plusieurs problèmes notés dans la spécification, mais ce serait formidable de voir certains d’entre eux être résolus et la spécification aller de l’avant.