Démos

Toutes les démos

<>

Couverture du livre CSS3 Le design web moderne

Livre CSS3

Le design web moderne

Plus d'infos sur le site officiel

En vente sur Amazon, FNAC, Dunod

Suivre

Actualités du site CSS3Create

Actualités sur CSS et le web en général

Reflection en CSS sur une image

Créer un reflet avec element() et -webkit-box-reflect

Création: avril 2013Modifié:

San Francisco, CA

Vue du Golden Gate Bridge de San Francisco
Contenu
Full CSS Pas de JavaScript
Navigateurs
Firefox Safari Chrome Opera
Partagez
Facebook Twitter

Votez

32 votes3.73

Découverte de la fonction element(), de la propriété -webkit-box-reflect et des masques CSS et SVG pour créer un reflet en pur CSS.

Le code de base HTML et CSS

Le principe ici est de créer un reflet en n’utilisant qu’un seul élément HTML. Le code est donc très extrêmement simple, une image et un texte contenus dans un bloc <div>.

<div id="div-element">
   <p>San Francisco, CA</p>
   <img src="image.jpg" alt="Texte alternatif">
</div>

Et avec un peu de CSS pour faire beau :

div{
   position: relative;
   width: 300px;
   height: 215px;
   margin: 50px auto 150px;
}
p{
   font: 1.2em sans-serif;
   position: absolute;
   right: 0; bottom: 20px;
   margin: 0; padding: 10px;
   background: rgba(0,0,0,.3);
   color: white;
}

Un reflet, version standardisée

Les spécifications CSS sont vastes. Au sein de ces multiples modules existe une fonction qui peut être utilisée pour réaliser des reflets, c’est la fonction element(). Cette fonction permet de créer une image dynamique d’un élément du DOM (en référençant son identifiant).

Bien qu’en cours de standardisation, cette fonction est déjà présente au sein de Firefox 4+ (préfixée). Nous l’utilisons donc ici. Pour cela, ajoutons un pseudo-élément ::after, lequel reçoit en arrière-plan l’image générée avec element().

div::after{
   content: '';
   position: absolute; left: 0; top: 100%;
   width: inherit; height: inherit;
   background: -moz-element(#div-element);
}
Note : Vous pouvez lire cet article pour comprendre la cascade CSS et l’utilisation de inherit

La fonction element() crée une image dynamique, mais en aucun cas un reflet. C’est à nous ensuite de peaufiner le résultat pour obtenir ce que l’on souhaite réellement. Dans notre cas, il nous faut réaliser un effet miroir puis masquer l’image de manière progressive. Utilisons d’abord une transformation CSS pour réaliser une symétrie :

div::after{
   ...
   transform: scaleY(-1);
}

Ensuite, utilisons les masques CSS pour cacher progressivement notre contenu. Dans ce premier cas (compatible avec Firefox uniquement), il nous faut passer par un masque SVG et le référencer en CSS, car Firefox ne supporte pas encore les masques Full CSS.

Voici donc le SVG utilisé :

<svg height="0">
   <mask id="mask1">
       <rect width="100%" height="215" fill="url(#gr)"/>
       <linearGradient x1="0" y1="0" x2="0" y2="1" id="gr">
           <stop offset="50%" stop-color="black" />
           <stop offset="100%" stop-color="white" />
       </linearGradient>
   </mask>
</svg>

Et l’appel via CSS :

div::after{
   ...
   mask: url('#mask1');
}

Notre SVG est composé ici d’un élément <mask>, lequel contient un élément <rect>. Cet élément <rect> est rempli avec un <linearGradient> allant du noir au blanc. Ce SVG peut être inclus directement dans le document HTML5 ou dans un fichier SVG séparé.

Il existe deux types de masques SVG :

  • Les masques de luminance, identiques à un masque de fusion dans Photoshop
  • Les masques de transparence (alpha), identiques à un masque d’écrêtage dans Photoshop.

Les masques SVG sont par défaut des masques de luminance : le blanc rend visible et le noir masque. Il est possible de modifier le type avec la propriété mask-type: luminance | alpha (Firefox 23+ actuellement)

Terminons notre reflet en baissant l’opacité générale du pseudo-élément :

div::after{
   ...
   opacity: .3;
}

Un reflet, version WebKit (non standard)

Les navigateurs basés sur WebKit n’implémentent pas encore la fonction element(). Néanmoins, il existe une propriété CSS non standard qui permet de réaliser un reflet, c’est -webkit-box-reflect. Elle s’utilise de la façon suivante :

  • Un mot-clé pour la position du reflet : below, above, left ou right (dessous, dessus, droite ou gauche)
  • Une distance pour décaler le reflet
  • Un dégradé CSS qui sera utilisé comme masque de transparence.

Il nous suffit donc d’ajouter cette propriété à notre CSS pour rendre notre reflet compatible avec tous les navigateurs WebKit (depuis 2008) :

div{
   ...
   -webkit-box-reflect: below 0 linear-gradient(transparent 50%, rgba(0,0,0,.3));
}

Attention, cette propriété ne sera jamais standardisée car son utilisation est limitée à cet effet. La fonction element() doit être préférée.

De plus, l’utilisation d’un dégradé linéaire CSS ne fonctionne pas sous Android inférieur à 3 avec -webkit-box-reflect. Une image transparente doit alors être utilisée.

Et les autres navigateurs ?

Les autres navigateurs, comme IE ou Opera, ont plus ou moins le support des masques SVG (sur du contenu SVG). Ce qui bloque pour cette démo est donc l’impossibilité de répéter dynamiquement un élément de la page. Une duplication du contenu est donc à prévoir dans le cas de la mise en place de ces techniques pour un support multi-navigateurs.

Le nouvel Opera, basé sur Blink (et donc Chromium) reconnait -webkit-box-reflect.

Vous avez déjà mis en place ces techniques ? Vous comptez le faire bientôt ? Parlez-en sur le forum !

Envie d'une nouvelle démo?

Un p'tit mot...

#1par Jackou, le 12 mai 2013

La propriété -webkit-box-reflect est vraiment très pratique. Dommage qu’elle ne soit pas un standard. Par contre si on essaie d’animer (avec jquery par exemple) un élément doté de cette propriété, le reflet n’est visible qu’au début et à la fin de l’animation mais pas pendant. Mais je peux me tromper.
(J’ai découvert votre site il y a peu et je ne m’en lasse pas. Bravo !)

#2par Alex, le 10 juin 2013

Bonjour,

je voulais vous remercier pour ce tuto, mais je n’arrive pas au bout. Tout se passe pour le mieux, jusqu’au moment ou j’essaie d’actualiser ma page pour voir le reflet crée en CSS, sauf qu’il n’apparait pas du tout.

J’utilise Dreamweaver et Safari...

J’ai tester en allant jusqu’au bout au cas ou il y est besoin de tout, et... non, le reflet n’apparait jamais, même en faisant du copier/coller de votre code et en prenant biensur une image de mon ordi.

De l’aide, une idée peut être ? Merci ;)

#3par stefde3, le 16 juin 2013

Bonjour,
Merci pour tous ces tutos et le temps prit à les faire et à les mettre en ligne. Je vous tire mon chapeau.
Un question me brûle les lèvres cependant...

N’aurait il pas été plus pratique de mettre un téléchargement de chacun des applications plutôt que de nous obliger à aller chercher le code source de vos pages ?
Si ce site à un but lucratif, j’ai peur que les débutants n’aillent pas chercher le css avec un "click droit" de la souris et donc tout le monde ne pourra pas en bénéficier.
C’était juste une idée au passage mais l’important est que vos tutos m’ont sauvé la vie ^^

#4par css3create, le 20 juin 2013

@stefde3 : Un but lucratif ? Non pas du tout ! Il n’y aucune pub sur le site, aucun lien partenaire, rien qui ne me fasse gagner de l’argent. (Hormis la mise en avant de mon bouquin sur CSS3 :) )

#5par jino, le 16 août 2013

juste savoir où insérer le lien svg dans la div contenant mon image reflèter ou quelque part d’autres

#6par Guillaume Ransinan, le 29 octobre 2013

Sans doute une confusion sur le sens de lucratif. Peut etre la personne voulait dire éducatif, pédagogique, didactique... Quelque chose dans ce goût...


modération à priori

Ce forum est modéré à priori : votre contribution n'apparaîtra qu'après avoir été validée par un administrateur du site.

Un message, un commentaire ?
    Qui êtes-vous ? (optionnel)
  • (Pour créer des paragraphes, laissez simplement des lignes vides.)