Structure de base▲
Nous pourrions aborder la réalisation de sphères en CSS de deux manières différentes.
La première consiste à créer une sphère 3D en utilisant beaucoup d'éléments. En voici de beaux exemples. L'inconvénient potentiel est que cela oblige le navigateur à afficher plusieurs éléments, pouvant avoir un impact sur les performances. Ces exemples laissent apparaître un lissage imparfait alors qu'une sphère lissée devrait nécessiter plusieurs éléments.
Nous essaierons une seconde approche en utilisant les dégradés en CSS (dégradé linéaire : linear-gradient et dégradé radial : radial-gradient) pour ajouter des ombrages et créer des effets 3D sur un élément unique.
Démo et code source▲
Tous les exemples de cet article peuvent être consultés sur mon compte Codepen ou grâce aux liens fournis après chaque exemple.
Forme de base▲
Avant de rentrer dans le vif du sujet nous allons créer une forme initiale de sphère dont le code HTML est :
Nous utiliserons ici l'élément figure, sachant que d'autres éléments peuvent être employés. L'élément figure est utilisé en HTML5 pour représenter une image ou un diagramme faisant partie du contenu et pouvant être supprimé sans altérer le sens de ce contenu.
Pour créer un cercle à partir de l'élément figure, nous définissons une largeur et une hauteur ainsi qu'un border-radius de 50%. Toute valeur supérieure à 50% donnera un résultat complètement arrondi.
.circle
{
display:
block
;
background:
black
;
border-radius:
50%
;
height:
300px
;
width:
300px
;
margin:
0
;
}
Et un cercle apparaît.
Maintenant que nous avons un cercle de base, nous pouvons commencer à y appliquer un style pour le transformer en quelque chose de plus sphérique.
Technique d'ombrage▲
Le principe de base consiste à ajouter un dégradé radial, légèrement en haut à gauche du centre du cercle.
Nous pouvons le faire en utilisant le code CSS suivant :
.circle
{
display:
block
;
background:
black
;
border-radius:
50%
;
height:
300px
;
width:
300px
;
margin:
0
;
background:
-webkit-radial-gradient(100px
100px
,
circle
,
#
5cabff
,
#
000
);
background:
-moz-radial-gradient(100px
100px
,
circle
,
#
5cabff
,
#
000
);
background:
radial-gradient(100px
100px
,
circle
,
#
5cabff
,
#
000
);
}
Vous devriez obtenir ce résultat :
Le dégradé radial▲
La propriété radial-gradient prend les valeurs suivantes : la première est la position (center par défaut) pour le départ du dégradé, ensuite la forme du dégradé est spécifiée (valeur : cercle ou ellipse), finalement une série de couleurs est définie. Vous pouvez définir plus de deux couleurs, mais il devient alors nécessaire d'inclure une distance entre chacune d'entre elles afin que la fonction (radial-gradient) sache à quel moment elle peut mélanger chaque couleur avec la suivante.
Dans l'exemple ci-dessus, seulement deux couleurs sont définies. Le navigateur suppose alors que la première est de 0% et la suivante de 100% de sorte qu'il affichera un dégradé entre ces deux couleurs. Si nous voulons des dégradés supplémentaires, nous pouvons définir des distances en pixel ou pourcentage, comme nous le verrons plus loin.
Nous avons donc un résultat se rapprochant d'une sphère en 3D. Même s'il semble correct nous allons tenter d'y apporter des améliorations.
Ombres et 3D▲
En fonction du choix de dégradé à appliquer, vous pouvez créer différents aspects de sphères. Dans un premier temps nous allons définir un environnement pour y placer notre sphère.
Dans le code HTML nous ajoutons quelques éléments supplémentaires :
<
section
class=
"
stage
"
>
<
figure
class=
"
ball
"
>
<
span
class=
"
shadow
"
>
<
/
span>
<
/
figure>
<
/
section>
L'élément « ball », placé dans l'élément « stage » (section), inclut un élément span qui sera utile pour créer une ombre. L'élément « stage » est utile lorsque nous voulons définir une perspective et positionner l'ombre afin de donner un effet 3D.
Appliquez quelques styles à l'élément « stage » et positionnez une ombre pour créer une scène :
.stage {
width:
300px
;
height:
300px
;
display:
inline-block;
margin:
20px
;
-webkit-perspective:
1200px
;
-webkit-perspective-origin:
50%
50%
;
}
.ball .shadow {
position:
absolute
;
width:
100%
;
height:
100%
;
background:
-webkit-radial-gradient(50
%
50
%
,
circle
,
rgba
(
0
,
0
,
0
,
0
.
4
), rgba(0
,
0
,
0
,
0
.
1
) 40%
, rgba(0
,
0
,
0
,
0
) 50%
);
-webkit-transform:
rotateX(90deg
) translateZ(-
150px
);
z-index:
-1;
}
Notez que je n'inclus que la perspective avec le préfixe -webkit dans le code CSS. Les exemples ci-dessous contiennent tous les préfixes CSS. Dans l'exemple ci-dessus une perspective d'une valeur de 1200 pixels est créée sur l'élément « stage ». La propriété perspective détermine le point de fuite dans une scène 3D.
L'ombre de la sphère est alors placée en lui définissant un dégradé radial, dégradé positionné par la propriété transform. La propriété CSS transform permet de manipuler dans l'espace 3D un élément HTML qui pourra subir des translations (translate), rotations (rotate), mises à l'échelle (scale) ou être inclinées (skew) selon les valeurs définies. L'ombre subit une rotation de 90 degrés sur l'axe des abscisses et descend de 150 pixels vers le bas pour apparaître à la base de la sphère.
Dès lors que nous avons défini à perspective une valeur pour le conteneur « stage », nous obtenons une vue du dessus qui nous permet de voir une forme ovale cintrée.
Le résultat devient meilleur. Dans le chapitre suivant nous ajouterons plus d'ombres à l'élément « ball ».
Ombres multiples▲
Dans la réalité, vous trouverez très rarement des objets éclairés sous un seul angle. Les surfaces réfléchissent la lumière sur d'autres surfaces et il en résulte une variété de sources de lumière mélangées entre elles. Pour créer un effet plus réaliste nous allons considérer qu'il y a deux sources de lumière en utilisant des pseudo-éléments afin d'ajouter deux dégradés.
.ball {
display:
inline-block;
width:
100%
;
height:
100%
;
margin:
0
;
border-radius:
50%
;
position:
relative
;
background:
-webkit-radial-gradient(50
%
120
%
,
circle
cover
,
#
81e8f6
,
#
76deef
10
%
,
#
055194
80
%
,
#
062745
100
%
);
);
}
.ball:
before {
content:
"";
position:
absolute
;
top
:
1%
;
left:
5%
;
width:
90%
;
height:
90%
;
border-radius:
50%
;
background:
-webkit-radial-gradient(50
%
0px
,
circle
,
#
ffffff
,
rgba
(
255
,
255
,
255
,
0
) 58%
);
-webkit-filter:
blur(5px
);
z-index:
2
;
}
Comme d'habitude je n'inclus que la version -webkit pour référence. Nous obtenons deux dégradés légèrement plus complexes.
Le premier dégradé est un subtil effet d'éclairage par le bas qui est appliqué à l'élément « ball ». Le centre du dégradé est positionné à 50% de la largeur et 120% de la hauteur. Le centre du dégradé se trouve ainsi placé en-dehors de la surface de la sphère. Le but étant de ne pas visualiser les contours de la couleur du dégradé (pouvant paraître brutale), adoucissant ainsi le dégradé.
Le deuxième dégradé (plus prononcé) est un éclairage, placé au-dessus. Il est défini à 90% de la largeur et 90% de la hauteur de la sphère. Le dégradé est centré au sommet de sorte qu'il diminue à partir de la moitié de la hauteur de la sphère.
Le pseudo-élément ::before est utilisé ici plutôt que de créer un nouvel élément qui contiendrait l'ombrage.
Dans la mesure où ce dégradé (plus prononcé) a des contours accentués on peut grâce à la propriété blur créer un effet plus doux. A noter que cette propriété, fort utile, n'est valable, pour l'instant, que sur Chrome et Safari et doit être préfixée (-webkit-).
Les deux dégradés combinés produisent un résultat plus agréable :
Effet de brillance▲
Jusqu'ici les effets créés sont plutôt doux. Nous allons ajouter maintenant des effets de brillance et créer quelque chose se rapprochant d'une boule de billard.
Pour y parvenir nous créerons un éclairage atténué par le bas, comme précédemment, mais nous ajusterons l'éclairage provenant du haut pour qu'il soit plus petit avec des contours plus prononcés. Nous aurons besoin d'utiliser deux pseudo-éléments pour définir la couleur de la sphère, un éclairage par le bas et une réflexion.
.ball {
display:
inline-block;
width:
100%
;
height:
100%
;
margin:
0
;
border-radius:
50%
;
position:
relative
;
background:
-webkit-radial-gradient(50
%
120
%
,
circle
cover
,
#
323232
,
#
0a0a0a
80
%
,
#
000000
100
%
);
}
.ball:
before {
content:
"";
position:
absolute
;
background:
-webkit-radial-gradient(50
%
120
%
,
circle
cover
,
rgba
(
255
,
255
,
255
,
0
.
5
), rgba(255
,
255
,
255
,
0
) 70%
);
border-radius:
50%
;
bottom
:
2
.5%
;
left:
5%
;
opacity:
0
.6
;
height:
100%
;
width:
90%
;
-webkit-filter:
blur(5px
);
z-index:
2
;
}
.ball:
after {
content:
"";
width:
100%
;
height:
100%
;
position:
absolute
;
top
:
5%
;
left:
10%
;
border-radius:
50%
;
background:
-webkit-radial-gradient(50
%
50
%
,
circle
cover
,
rgba
(
255
,
255
,
255
,
0
.
8
), rgba(255
,
255
,
255
,
0
.
8
) 14%
, rgba(255
,
255
,
255
,
0
) 24%
);
-webkit-transform:
translateX(-
80px
) translateY(-
90px
) skewX(-
20deg
);
-webkit-filter:
blur(10px
);
}
Nous avons, ici, appliqué un subtil dégradé avec la couleur initiale sur la sphère. Le pseudo-élément ::before permet de définir un éclairage plus prononcé qui démarre, une nouvelle fois, de la base de la sphère et crée l'effet d'un éclairage réfléchi par le sol.
Nous avons ajouté un nouveau pseudo-élément ::after permettant de créer un autre dégradé radial. Ce dégradé démarre avec une opacité de 0% sur la couleur blanche et s'estompe jusqu'à une transparence de 24%. On obtient un effet blanc brillant auquel on applique la propriété transform afin de donner l'impression de réflexion sur un objet en 3D.
La propriété transform déplace le reflet de 80 pixels vers la gauche et 90 pixels vers le haut avec une inclinaison (skew). La valeur skew rétrécit le cercle (de dégradé) selon l'axe des abscisses afin de rendre le reflet plus réaliste sur la boule brillante.
Boule de billard N°8▲
Voici les étapes pour ajouter le numéro 8 à notre boule de billard.
Nous créons pour cela un élément supplémentaire qui contiendra le 8, de même que nous définissons les styles correspondants.
<
section
class=
"
stage
"
>
<
figure
class=
"
ball
"
>
<
span
class=
"
shadow
"
>
<
/
span>
<
span
class=
"
eight
"
>
<
/
span>
<
/
figure>
<
/
section>
.ball .eight {
width:
110px
;
height:
110px
;
margin:
30%
;
background:
white
;
border-radius:
50%
;
-webkit-transform:
translateX(68px
) translateY(-
60px
) skewX(15deg
) skewY(2deg
);
position:
absolute
;
}
.ball .eight:
before {
content:
"8
";
display:
block
;
position:
absolute
;
text-align:
center
;
height:
80px
;
width:
100px
;
left:
50px
;
margin-left:
-40px
;
top
:
44px
;
margin-top:
-40px
;
color:
black
;
font-family:
Arial;
font-size:
90px
;
line-height:
104px
;
}
Le border-radius défini à 100% est de nouveau utilisé pour créer un cercle qui est positionné en haut à droite grâce à la propriété transform (translate). Plutôt que de placer le numéro 8 dans le contenu, un pseudo-élément ::before est créé afin de le générer en CSS et de lui attribuer les mêmes transformations que le cercle blanc (contour du 8).
On obtient donc une boule de billard numérotée brillante :
Œil en mouvement▲
Une des grandes fonctionnalités de la propriété CSS transform consiste à créer des animations. Avec la règle CSS @keyframes nous pouvons définir une série de transformations dans une animation et l'appliquer à un élément. Pour montrer cela, je vais créer et animer un œil.
La première étape consiste à modifier les couleurs définies précédemment dans notre boule de billard. Après quelques réglages on aura l'apparence d'un œil. Voici d'abord le code HTML :
<
section
class=
"
stage
"
>
<
figure
class=
"
ball
"
>
<
span
class=
"
shadow
"
>
<
/
span>
<
span
class=
"
iris
"
>
<
/
span>
<
/
figure>
<
/
section>
La majeure partie du code CSS est similaire à la boule de billard, excepté pour le traitement de l'iris et de la pupille :
.iris {
width:
40%
;
height:
40%
;
margin:
30%
;
border-radius:
50%
;
background:
-webkit-radial-gradient(50
%
50
%
,
circle
cover
,
#
208ab4
0
%
,
#
6fbfff
30
%
,
#
4381b2
100
%
);
-webkit-transform:
translateX(68px
) translateY(-
60px
) skewX(15deg
) skewY(2deg
);
position:
absolute
;
-webkit-animation:
move-eye-skew 5s
ease-out infinite;
}
.iris:
before {
content:
"";
display:
block
;
position:
absolute
;
width:
37
.5%
;
height:
37
.5%
;
border-radius:
50%
;
top
:
31
.25%
;
left:
31
.25%
;
background:
black
;
}
.iris:
after {
content:
"";
display:
block
;
position:
absolute
;
width:
31
.25%
;
height:
31
.25%
;
border-radius:
50%
;
top
:
18
.75%
;
left:
18
.75%
;
background:
rgba(255
,
255
,
255
,
0
.
2
);
}
Un dégradé bleu détermine la couleur de l'iris, la pupille et un reflet sur cette dernière sont créés à l'aide de pseudo-éléments. Une animation est ajoutée sur l'iris au format suivant :
animation:
animation-name 5s
ease-out infinite;
Dans ce cas nous appliquerons une animation nommée « animation-name », définie pour durer 5 secondes, avec un nombre de répétitions infinies et une valeur « ease-out » pour l'effet de timing. La valeur ease-out permet de ralentir l'animation lorsqu'elle se termine afin d'obtenir un effet plus réaliste.
Sans l'animation décrite nous obtenons un œil particulièrement statique.
Déterminons les keyframes pour créer le mouvement de l'œil.
@-webkit-keyframes move-eye-skew {
0%
{
-webkit-transform:
none
;
}
20%
{
-webkit-transform:
translateX(-
68px
) translateY(30px
) skewX(15deg
) skewY(-
10deg
) scale(0
.
95
);
}
25%
, 44%
{
-webkit-transform:
none
;
}
50%
, 60%
{
-webkit-transform:
translateX(68px
) translateY(-
40px
) skewX(5deg
) skewY(2deg
) scaleX(0
.
95
);
}
66%
, 100%
{
-webkit-transform:
none
;
}
}
La règle CSS @keyframes peut paraître délicate à mettre en œuvre au premier abord. Il faut décrire les états de l'élément au cours des étapes (choisies) de l'animation, chaque état étant défini par un pourcentage. Dans ce cas l'animation de l'iris démarrera sans transformation. A 20% (deuxième état) une transformation est appliquée afin de créer un déplacement et une inclinaison vers la gauche. L'espace entre le premier état (0%) et le deuxième (20%) est automatiquement calculé par le navigateur afin de créer une transition douce.
Le processus s'exécute tout au long des 5 états pour donner une animation d'une durée (spécifiée par animation-delay) de 5 secondes.
La version -webkit préfixée est intégrée ici, mais vous pourriez aussi bien vouloir créer des versions avec moz, ms et sans préfixe.
Bulle bondissante▲
En utilisant une combinaison d'ombrages et d'animations nous pouvons produire toutes sortes d'effets, comme la réalisation d'une bulle qui rebondit.
Cette création est similaire à l'exemple précédent (œil en mouvement) sachant que nous utiliserons plus de transparence pour la couleur principale ainsi que deux pseudo-éléments pour les reflets.
L'animation utilisera la fonction scale (mise à l'échelle) pour créer une déformation de l'ensemble de la bulle lors du rebond.
@-webkit-keyframes bubble-anim {
0%
{
-webkit-transform:
scale(1
);
}
20%
{
-webkit-transform:
scaleY(0
.
95
) scaleX(1
.
05
);
}
48%
{
-webkit-transform:
scaleY(1
.
1
) scaleX(0
.
9
);
}
68%
{
-webkit-transform:
scaleY(0
.
98
) scaleX(1
.
02
);
}
80%
{
-webkit-transform:
scaleY(1
.
02
) scaleX(0
.
98
);
}
97%
, 100%
{
-webkit-transform:
scale(1
);
}
}
L'animation est appliquée à la totalité de la bulle et ses pseudo-éléments.
Utilisation d'images▲
Jusqu'ici nous avons créé des sphères sans utiliser d'images. Appliquer des images en arrière-plan permet d'ajouter plus de détails tout en profitant de l'avantage que nous apporte la création d'ombres en CSS par l'intermédiaire des pseudo-éléments. Voici par exemple une texture de balle de tennis sans effets d'ombre.
En ajoutant des dégradés par l'intermédiaire des CSS nous créons une illusion de profondeur :
Globe terrestre animé▲
Les animations peuvent aussi être appliquées sur la position d'une image placée en arrière-plan. Par ce moyen nous pouvons réaliser un globe terrestre en rotation.
L'image utilisée à été rétrécie au sommet et en bas pour être utilisée en arrière-plan :
Avec un complément composé d'ombrage et d'animation, un globe style 3D peut être créé. Voici le résultat en action : Globe terrestre 1 en ligne. L'exemple n'est pas affiché directement sur cette page parce que les performances sur cet exemple sont assez médiocres, ce qui a entrainé un emballement de mon ventilateur sur mon portable.
Note: Un grand merci à Sidoruk Sergey (@Sidoruk_SV) pour avoir mis à niveau ce globe. C'est du beau boulot. (NdT : voir cet exemple : Globe terrestre 2 en ligne).
Ressources▲
Quelques bonnes infos concernant le dégradé radial au cas où vous aimeriez en savoir plus.
A la recherche de plus d'exemples 3D ? Jetez un coup d'œil sur Zelda - Un lien vers les CSS ou le Portail CSS pour plus d'inspiration.
Retours▲
Tous les exemples mentionnés peuvent être retrouvés via mon compte Codepen. Un grand merci à Chris et l'équipe pour avoir fait en sorte que ce soit une fantastique ressource.
Si vous avez des questions concernant l'article, contactez moi par mail ou sur Twitter.
Remerciements▲
Nous tenons à remercier Donovan Hutchinson pour nous avoir autorisé à traduire cet article dont vous retrouverez l'original ici : http://hop.ie/blog/balls/.
Remerciements à rodolphebrd pour la traduction de cet article, a ced pour sa relecture orthographique et à 12monkeys et Bovino pour leur relecture complète et minutieuse.