La propriété background-clip: text
n’étant pas standard et non reconnue au sein des navigateurs non WebKit, je vous propose un petit snippet pour profiter de cette propriété, dans la quasi majorité des navigateurs du marché.
Pour simuler cet effet, nous utilisons les filtres SVG appliqués depuis CSS sur du contenu HTML. Le code SVG du filtre est très simple :
<filter id="filter">
<!-- faking background-clip:text -->
<feImage xlink:href="grass-texture.jpg" width="450" height="450" />
<feTile />
<feComposite in2="SourceGraphic" operator="in" />
</filter>
Et il suffit donc de le référencer depuis CSS :
.element {
filter: url('#filter');
}
Voici en détails ce que fait le filtre :
- La primitive
<feImage>
extrait les pixels d’une image - La primitive
<feTile>
se charge de créer une mosaïque recouvrant l’intégralité de la source graphique sur laquelle le filtre s’applique (en se basant sur les pixels récupérés de l’image) - Enfin, la primitive
<feComposite>
réalise l’étape de compositing entre la mosaïque créée (attributin
implicite) et la source graphique d’origine (attributin2
). Cette étape est réalisée avec l’opérateurin
.
Pour profiter d’un support maximal, tout en prenant en compte l’amélioration progressive, l’appel à ce filtre peut être fait au sein de la règle CSS @supports
.
.element {
color: green; /* fallback */
}
/* si -webkit-background-clip: text et @supports sont supportés */
@supports (-webkit-background-clip: text) {
.element {
/* applique un background par défaut + clip:text */
background: url('grass-texture.jpg');
-webkit-background-clip: text;
/* pour surcharger color */
-webkit-text-fill-color: transparent;
}
}
/* si -webkit-background-clip: text n'est pas supporté, mais que @supports l'est :) */
@supports not (-webkit-background-clip: text) {
.element {
filter: url('#filter'); /* applique le filtre */
}
}
Le support final est donc effectif pour Firefox 22+, Chrome 28+, Opera 15+ comme le montre ce support sur CanIUse. Le fallback servira donc principalement pour Safari et IE.
Pour améliorer le rendu avec Safari (où background-clip: text
existe également), il est possible d’inverser le test du @supports
. Attention, la dégradation gracieuse risque de ne plus être maintenue. Votre code pourrait ressembler à cela pour un support Firefox 22+, Chrome, Safari, Opera :
.element {
/* applique un background par défaut + clip:text */
background: url('grass-texture.jpg');
-webkit-background-clip: text;
/* pour surcharger color */
-webkit-text-fill-color: transparent;
}
/* si -webkit-background-clip: text n'est pas supporté, mais que @supports l'est :) */
@supports not (-webkit-background-clip: text) {
.element {
background: none; /* override background */
filter: url('#filter'); /* applique le filtre */
}
}
Pour IE, vous pouvez éventuellement passez par du full SVG. Regardez du coté de RaphaëlJS ou de Snap.svg
Retrouvez également le second snippet utilisant les filtres SVG : « Ombre interne sur du texte »
:)