Mais lorsque Kitty Giraudel a lancé son CSS brain teaser.[1]
Les spécifications actuelles
Ne connaissant que de très loin cette propriété, il a fallu me mettre à jour. clip-path
, à l’instar de clip
, sert à délimiter la zone d’affichage d’un contenu. Je m’oriente vers les spécifications pour compléter cet embryon de culture — et là, c’est le drame :
- La spécification de la propriété
clip-path
au sein du module CSS masking, encore à l’état de brouillon; - Qui nous renvoie aux formes basiques en SVG;
- Tout cela en se référant sans arrêt à l’élément SVG
ClipPath
; - De fil en aiguille, citons également le module Masking de la spécification SVG — et notamment la section sur les Clipping paths.
On peut d’ores et déjà noter une différence remarquable entre les états de ces deux spécifications : l’une est en brouillon, l’autre en recommandation. La spécification SVG est extrêmement aboutie et claire, les ressources ne manquent pas.[2]
En revanche le module CSS est obscur. Il existe un lien étroit entre les deux spécifications, car le brouillon du module CSS Masking s’appuie énormément sur la spécification SVG — et qu’en SVG il existe l’attribut clip-path
. Ça génère des incompréhensions qui ne vont pas faciliter la prise en main de cette propriété.
Pour éclaircir un peu tout ça — et vous épargner la lecture des spécifications — vous devriez pouvoir écrire ceci pour utiliser une forme basique :
.clip {
clip-path: circle( 50%, 50%, 5em );
}
Mais ceci devrait fonctionner également — en appelant un élément SVG :
.clip {
clip-path: url(#circle);
}
Les origines
Il faut sonder un peu les origines de ce module CSS pour en comprendre l’obscurité. Bien que déjà en cours d’élaboration dans le cadre technique du SVG, la possibilité de masquer des éléments en CSS existait depuis CSS 2.1 grâce à la propriété clip
, désormais dépréciée.[3]
Cette propriété n’a jamais réellement trouvé son public, car elle a deux inconvénients majeurs :
- L’élément masqué doit être en position absolue;
- Le masque ne peut être que rectangulaire, et son placement est contre-intuitif.
Embêtant. Constatant les progrès possibles de cette fonctionnalité en CSS, c’est le navigateur Safari qui a ouvert les hostilités en 2008 avec les propriétés -webkit-mask-…
supportées dès Safari 4. Cette technique a rencontré un franc succès car elle permet d’utiliser une image comme masque. Malheureusement cette propriété n’était supportée que par le moteur de rendu Webkit.[4]
Là, j’ai vu poindre le problème : la spécification CSS en cours d’élaboration mélange joyeusement les clips issus de SVG et la proposition de Safari.[5]
Des ressources dissonantes
Il est fort peu probable que personne avant moi ne s’y soit intéressé. Et en effet, quatre ressources principales sont indispensables pour appréhender clip-path
:
- CSS Masking sur HTML5Rocks;
- L’article dédié sur Web Platform Docs;
- Un tutoriel avancé sur The Nitty Gritty;
- L’article de l’Avent par Vincent De Oliveira sur 24 jours de web;
Comme vous vous en apercevrez en les lisant, le contenu est disparate. La compatibilité navigateur est abordée différemment.[6]
À l’instar de la spécification qui intègre les clips et les masques, ces ressources présentent les deux techniques. Dommage car deux articles distincts auraient été bien plus clairs !
Un bilan mitigé
Après avoir compulsé maladivement les spécifications, articles, tutoriaux et autres exemples pendant quelques jours, j’ai abouti à un exemple ressemblant à ceci :
/**
* 1. Définition d’une forme rectangulaire de repli pour les navigateurs ne supportant pas clip-path;
* 2. Création d’une forme SVG basique, circulaire;
* 3. Appel d’un fichier SVG contenant un élément clipPath.
*/
.clip {
clip: rect( 7em, 30em, 17em, 20em ); /* 1 */
-webkit-clip-path: circle( 50%, 50%, 5em ); /* 2 */
clip-path: url(#circle); /* 3 */
}
Évidemment, cela implique un balisage précis côté HTML :
<p class="clip">
♬ Tout, tout, tout : vous saurez tout sur le clip-path ♬
</p>
<svg width="200" height="200">
<defs>
<clipPath id="circle">
<circle cx="50%" cy="50%" r="80" />
</clipPath>
</defs>
</svg>
Ainsi je tente de vous livrer un état des lieux aussi complet que possible.[7]
- Chrome 23, Safari 6.1 et Opéra 15 supportent
clip-path
sous toutes ses formes — incluant la définition de formes SVG basiques dans le CSS; - Firefox 4 supporte
clip-path
si on référence un élément SVGclipPath
— ce qui implique d’ajouter un fichier SVG — en revanche vous serez obligés de définir des positions en unités absolues comme lepx
pour positionner votre clip si vous souhaitez éviter les bugs, et c’est bien dommage; - Opéra 7, Chrome 14, IE8 à 11 et Safari 1 se replient sur
clip
; - Une note sur IE9 à 11 : ces navigateurs supportent
clip-path
si on référence un élément SVGclipPath
, à condition d’appliquer le clip sur un élément SVG. Il est envisageable d’intégrer la zone à clipper dans un élémentForeignObject
au sein d’un SVG, mais ça devient trop tordu à mon goût; - Un mot sur IE4 à 7 : surpris vous êtes ? Ne le soyez pas, clip est reconnu sur IE4 à 7 (et même Netscape 4). Le hic, ce sont les pseudo-éléments que j’emploie dans mon exemple; ainsi en ajoutant un élément dédié dans le DOM, vous devriez pouvoir supporter IE4 facilement 😀 .
Une solution correcte
Malgré le support disparate et le funambulisme nécessaire pour aboutir à un résultat viable, j’ai trouvé clip-path
extrêmement intéressant — et notamment grâce à la dégradation possible à l’aide de clip
sur de très vieux navigateurs et de façon simplissime.
Ce repli implique de perdre les formes personnalisées au profit d’un rectangle « simple », ce qui fut considéré comme acceptable lors de l’avènement de border-radius
par exemple. Et je suppose que dans la plupart des cas, cette solution reste acceptable.
Vous trouverez donc ma solution au casse-tête proposé par Kitty sur CodePen, détaillée, commentée, agrémentée de diverses précisions — en Anglais.
Tout retour sera le bienvenu 🙂 .
Mise à jour
Moins d’une semaine avant la publication de mon article, le brouillon du W3C concernant la notation des formes basiques a évolué. Je cite Vincent De Oliveira, qui a partagé l’information avec moi :
Par contre, la notation des basic-shapes ont (encore) changées récemment! 😛 dev.w3.org
Ô joie. Merci à Vincent en tout cas !
Papa, Maman : j’aime les casses-têtes. ↩︎
Un petit « cocorico » s’impose pour féliciter Jérémie Patonnier, qui a grandement contribué à la documentation sur le Mozilla Developper Network notamment. ↩︎
La propriété est dépréciée mais très bien supportée, et le W3C indique que les agents utilisateurs (navigateurs web) doivent la supporter malgré sa déprécation. ↩︎
Je ne compte pas traiter du marronnier de « la guerre des navigateurs » ni du syndrome « Webkit only ». ↩︎
Fabriqué par Apple® en Californie. ↩︎
La palme revient à HTML5Rocks qui détaille Chrome et Firefox, et oublie les autres. ↩︎
Je tiens à préciser que je n’ai aucune expertise en la matière : ce ne sont la que les conclusions trouvées par un intégrateur lambda. ↩︎
Merci pour l’article. Quoique pas tout jeune, il a le mérite d’être assez clair, contrairement à ce que j’ai précédemment trouvé sur le net.