Les ombres en CSS3 avec box-shadow
Ce tutoriel a pour but de détailler l'utilisation de la nouvelle propriété CSS3 box-shadow
. Cette puissante propriété permet des réaliser de très beaux effets de volume ou de creux tout en conservant un code d'un poids minimal pour la page, et sans utiliser la moindre image.
Avant de commencer
Afin d'exploiter les possibilités de la propriété CSS3 box-shadow
, nous allons tout d'abord créer un simple div
:
<div id="shadowbox"></div>
Avec les styles suivants :
#shadowbox {
width: 200px;
height: 100px;
}
Nous allons appliquer la propriété box-shadow
à cet élément. Cependant, afin de ne pas alourdir le code au fil de cet exemple, je n'utiliserai pas les préfixes propres à chaque navigateur, c'est à dire que les exemples seront écrits avec box-shadow
, et non pas -moz-box-shadow
, ni -webkit-shadow
. Ce qui signifie que si vous voulez tester ces propriétés dans un navigateur particulier, vous devrez les rajouter.
Sur ce point, il est important de préciser qu'il y a un ordre à respecter lorsque vous utilisez ces préfixes. Comme la finalité des navigateurs est d'implémenter ces propriétés sans préfixes, si vous souhaitez que votre design soit stable pour les années à venir, vous devez également ajouter la propriété non-préfixée à la suite des propriétés préfixées.
C'est à dire que toutes vos propriétés CSS3 doivent être écrites sous la forme :
-webkit-propriete-css3: valeur;
-moz-propriete-css3: valeur;
-o-propriete-css3: valeur;
propriete-css3: valeur;
Lorsque les propriétés CSS3 en questions seront parfaitement supportées, vous pourrez n'écrire que :
propriete-css3: valeur;
C'est donc sous cette forme que les exemples suivants seront écrits.
Les différents paramètres
Commençons tout d'abord par analyser les différents paramètres que l'on doit fournir à box-shadow afin qu'elle fonctionne correctement.
- Le décalage horizontal : Un nombre positif décalera l'ombre sur la droite par rapport à l'élément. Un nombre négatif décalera sur la gauche.
- Le décalage vertical : Un nombre positif décalera l'ombre vers le bas par rapport à l'élément. Un nombre négatif décalera vers le haut.
- Le rayon du flou : c'est la taille du dégradé sur les bords de votre ombre. Cette valeur est forcément positive. Si elle vaut 0, l'ombre sera nette et prendra la forme exacte de l'élément. Et plus le nombre sera grand et plus l'ombre sera floutée.
- Le rayon d'étendue : Un nombre positif agrandira l'ombre, un nombre négatif la rétractera, et enfin si il n'est pas spécifié ou vaut 0px, l'ombre aura la même taille que l'élément. Dans le cas d'une ombre intérieure, une valeur positive augmentera la taille de l'ombre, c'est à dire qu'elle se resserera sur le contenu de l'élément.
- La couleur peut être écrite de plusieurs façons. Pour une ombre sans transparence, le plus simple est d'utiliser l'habituelle notation RGB. Pour une ombre bleue on écrira donc
#00F
ou#0000FF
. Si l'on souhaite ajouter de la transparence on utiliser plutôt la notation RGBA comme ceci :rgba(0, 0, 255, 0.5)
. Les 3 premiers paramètres sont les couleurs RGB habituelles écrites en base 10 (de 0 à 255 donc), et le 4ème paramètre est l'opacité, qui prend des valeurs situées entre 0 et 1. Une opacité de 0 sera invisible tandis qu'une opacité valant 1 sera totalement opaque. - Enfin, il est possible d'ajouter le mot
inset
pour que l'ombre soit située à l'intérieur de l'élément et au premier plan, et non pas à l'extérieur et en arrière-plan. Cette valeur est donc utilisée pour créer un effet de creux à l'intérieur d'un élément. Notez qu'il est possible de placer leinset
aussi bien en premier qu'en dernier paramètre, les deux cas sont acceptés.
border-radius
Et oui ! La forme de l'ombre est calculée à partir de la forme de l'élément, donc si les coins de cet élément sont arrondis, l'ombre le sera également. Si cette particularité n'est pas très intéressante dans le cas des ombres extérieures (sans inset
), elle est en revanche essentielle dans le cas d'une ombre intérieure, afin que celle-ci épouse bien la forme de l'élément.
Ombres multiples
Il est possible d'appliquer plusieurs ombres sur un même élément. Pour cela il suffit de les séparer par des virgules. Par exemple :
box-shadow:
10px 10px 10px black inset,
10px 10px 10px black;
Le fait de pouvoir combiner différentes ombres permet de produire d'excellentes illusions de volume, comme nous allons le voir dans la prochaine partie.
Effet de volume
Un effet de volume se réalise avec 2 ombres :
- Une ombre intérieure claire sur le haut de l'élément
- Une ombre extérieure sombre sur le bas de l'élément
Il est également efficace d'utiliser une couleur différente pour l'intérieur de l'élément. Dans le cas de cet effet de volume, on veut que l'élément ressorte, et qu'il soit donc plus exposé à la lumière. Une couleur plus claire est donc plus appropriée.
Les ombres peuvent avoir un décalage horiontal, mais je préfère personnellement lorsqu'il n'y en a pas, ce qui correspond davantage à un design moderne épuré.
Voici le code qui permet de réaliser cet effet :
background-color: #777;
border-radius: 20px;
box-shadow:
0px 2px 2px 0px rgba(0, 0, 0, 0.5),
0px 2px 2px 0px rgba(255, 255, 255, 0.5) inset;
Effet de creux
Un effet de creux se réalise avec 2 ombres :
- Une ombre intérieure sombre sur le haut de l'élément
- Une ombre extérieure claire sur le bas de l'élément
Pour cet effet on utilisera pour l'intérieur de notre élément une couleur plus foncée, puisqu'en toute logique, un creux est moins exposé au soleil. Encore une fois je préfère ne pas utiliser de décalage horizontal.
Voici le code de cet effet :
background-color: #555;
border-radius: 20px;
box-shadow:
0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,
0px 2px 2px 0px rgba(255, 255, 255, 0.5);
Code complet de démonstration
Voici le code d'une page de démonstration montrant les effets de cet article.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
background-color: #666;
}
#main {
width: 900px;
margin: auto;
padding-top: 100px;
}
#shadowbox1 {
width: 200px;
height: 100px;
margin: 100px 100px 100px 200px;
float: left;
background-color: #777;
-moz-border-radius: 20px;
-moz-box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5),
0px 2px 2px 0px rgba(255, 255, 255, 0.5) inset;
-webkit-border-radius: 20px;
-webkit-box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5),
0px 2px 2px 0px rgba(255, 255, 255, 0.5) inset;
border-radius: 20px;
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5),
0px 2px 2px 0px rgba(255, 255, 255, 0.5) inset;
}
#shadowbox2 {
width: 200px;
height: 100px;
margin: 100px 100px 100px 500px;
background-color: #555;
-moz-border-radius: 20px;
-moz-box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,
0px 2px 2px 0px rgba(255, 255, 255, 0.5);
-webkit-border-radius: 20px;
-webkit-box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,
0px 2px 2px 0px rgba(255, 255, 255, 0.5);
border-radius: 20px;
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,
0px 2px 2px 0px rgba(255, 255, 255, 0.5);
}
</style>
</head>
<body>
<div id="main">
<div id="shadowbox1"></div>
<div id="shadowbox2"></div>
</div>
</body>
</html>