Sphères

Avec la propriété CSS border-radius, nous pouvons faire des formes arrondies et des cercles. Ajoutons y quelques dégradés et elles sont devenues des sphères. Essayons ça, et ajoutons y un peu d’animation pour les rendre plus vivantes.

Flat Design

Il y a deux manières de faire des sphères en CSS.

La première, c’est de créer une sphère 3D en assemblant de multiples éléments. Il y a de magnifiques exemples à découvrir. Le côté négatif de la chose, c’est que cela nécessite que le navigateur affiche de nombreux éléments et cela peut impacter la performance du rendu. Elles ont également tendance à paraître un peu anguleuses car l’arrondi de la sphère nécessite plus d’éléments.

Au lieu de cela je vais essayer une deuxième approche, utilisant les dégradés CSS pour les ombres et avec un effet 3D sur un seul élément.

Démo et code cource

Tous les exemples ici mentionnés peuvent être retrouvés sur mon Codepen, ou en sélectionnant les liens "Éditer dans Codepen" dans chaque exemple plus loin.

Dans les exemples de code, j’ai laissé tombé les préfixes dédiés des navigateurs. Je vous recommande l’usage d’un outil genre Autoprefixer, ou d’ajouter les préfixes selon les besoins.

Forme de base

Avant d’ajouter les détails, nous créons la forme circulaire de base. Cela commence avec le HTML :

<figure class="circle"></figure>

Nous utilisons un élément figure ici, mais cela peut être n’importe quel élément. Figure est un élément HTML5 qui représente une image ou un diagramme qui peut être retiré du contenu sans en affecter le sens.

Pour créer un cercle à partir de cet élément figure, Je lui donne une largeur, une hauteur et un radian de 50% de la bordure. N’importe quoi au-delà de 50% résultera en un angle absolument rond.

.circle {
  display: block;
  background: black;
  border-radius: 50%;
  height: 300px;
  width: 300px;
  margin: 0;
}

Un cercle apparaît.

Maintenant que nous avons le cercle de base, nous pouvons le styler en quelques chose de plus sphérique.

Shading 101

La première chose que la plupart des tutoriels de sphères 3D font est d’ajouter un simple dégradé linéaire, allant du haut à gauche vers le centre du cercle.

Nous pouvons le faire avec ce code CSS:

.circle {
  display: block;
  background: black;
  border-radius: 50%;
  height: 300px;
  width: 300px;
  margin: 0;
  background: radial-gradient(circle at 100px 100px, #5cabff, #000);
}

Vous devriez obtenir quelque chose comme ça:

Dégradés linéaires

La propriété radial-gradient accepte plusieurs arguments. La première est la position centrale de départ du dégradé. Selon la syntaxe *forme* &agrave; *position*. Dans cet exemple, c’est un cercle avec une position de centre à 100 pixels de la gauche et à 100 pixels du haut.

Puis on spécifie un ensemble de couleurs. Vous pouvez donner plus de deux couleurs mais il faudra alors un différentiel de teinte suffisant pour que le dégradé soit harmonieux.

Dans cet exemple nous n’utilisons que deux couleurs. Cela permet au navigateur de passer du premier à 0% au suivant à 100%, et de dessiner le gradient entre les deux. Si nous voulions d’autres étapes de dégradé, nous devrions spécifier les distances en pixel ou pourcentage comme nous le verrons plus loin.

Nous avons donc quelque chose qui a une tête de 3D. C’est pas mal, mais essayons de faire plus sympa.

Ombres & 3D

Selon le type d’ombre que vous appliquerez sur la surface, vous pourrez créer différents aspects de sphères. D’abord mettons en place la scène où nous mettrons nos balles.

Le HTML que nous utilisons contient quelques éléments de plus.

<section class="stage">
  <figure class="ball"><span class="shadow"></span></figure>
</section>

L’élément "ball" se voit attribuer un span que nous allons utiliser pour créer une ombre et il est encadré d’une section de classe stage. La section de classe stage est utile pour donner un peu de perspective et pour positionner l’ombre, ce qui nous donnera un aspect plus 3D.

Appliquons quelques styles au stage et positionnons une ombre pour finir la scène.

.stage {
  width: 300px;
  height: 300px;
  display: inline-block;
  margin: 20px;
  perspective: 1200px;
  perspective-origin: 50% 50%;
}
.ball .shadow {
  position: absolute;
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.1) 40%, rgba(0, 0, 0, 0) 50%);
  transform: rotateX(90deg) translateZ(-150px);
  z-index: -1;
}

Remarquez que je ne mets pas les préfixes dans ces exemples CSS. Les exemples Codepen contiennent du CSS totalement préfixé. Au-dessus, j’ai réglé la section stage de manière à avoir une perspective de 1.200 pixels. La propriété perspective donne un point de fuite à la scène 3D.

L’ombre de la balle est alors placée en donnant un dégradé linéaire mais en la positionnant avec un transform. L’action transforms en CSS permet la rotation, la mise à l’échelle, le déplacement en ligne ou vectoriel de quelque chose dans un espace 3D. On applique une rotation de 90 degrés à l’ombre sur l’axe X avec un décalage vers le bas de la balle de 150 pixels.

Avec la perspective que nous avons donné au conteneur stage et en regardant vers le bas, nous pouvons le voir comme une forme ovale étirée.

Cela commence à être plus sympa maintenant. Ajoutons une ombre à la balle elle-même.

Ombres multiples

Dans le monde réel vous trouverez rarement des objets éclairés sous un seul angle. Les surfaces reflètent la lumière sur les autres surfaces et au final les différentes sources lumineuses se mélangent entre elles. Pour avoir un aspect de balle plus réaliste, nous allons faire comme s’il y avait deux sources lumineuses avec un pseudo-element pour avoir deux dégradés.

.ball {
  display: inline-block;
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 50%;
  position: relative;
  background: radial-gradient(circle at 50% 120%, #81e8f6, #76deef 10%, #055194 80%, #062745 100%);
}
.ball:before {
  content: "";
  position: absolute;
  top: 1%;
  left: 5%;
  width: 90%;
  height: 90%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 0px, #ffffff, rgba(255, 255, 255, 0) 58%);
  filter: blur(5px);
  z-index: 2;
}

Ici nous avons deux dégradés nettement plus évolués.

Le premier dégradé est un subtil souligné lumineux qui s’applique à l’élément ball. Le point de départ central du dégradé est positionné à mi-chemin et à 120% de la hauteur de la balle. Cela positionne le centre de la balle. C’est fait pour que la couleur de fin ne soit pas visible, ce qui permet un rendu de dégradé plus atténué.

Le deuxième dégradé est un éclaircissement, placé au sommet. Il est positionné à 90% de la largeur de la balle et à 90% de sa hauteur. Le dégradé est centré sur le haut si bien qu’il s’atténue à mi-chemin en descendant sur la balle.

Pour contenir l’ombre, j’ai utilisé le pseudo-élément before plutôt que d’en créer un autre.

Comme cet éclaircissement est un peu violent, j’utilise l’effet blur pour l’atténuer. Malheureusement il n’est présent que sur les navigateurs webkit (Chrome et Safari) mais il pourrait être utile plus tard sur les autres navigateurs.

Les deux gradients combinés réalisent un effet nettement plus sympa :

Brillant

En l’état l’effet est assez doux, ajoutons y un peu de brillance et créons quelque chose plus comme une boule de billard.

Pour y arriver nous allons utiliser une douce lumière en soulignement comme avant, mais en ajustant l’éclairage lumineux du sommet pour qu’il soit plus petit et étroit. Il nous faudra utiliser deux pseudo-sélecteurs pour contenir la couleur de la balle, une lumière en bas et une réflection.

.ball {
  display: inline-block;
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 50%;
  position: relative;
  background: radial-gradient(circle at 50% 120%, #323232, #0a0a0a 80%, #000000 100%);
}
.ball:before {
  content: "";
  position: absolute;
  background: radial-gradient(circle at 50% 120%, 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%;
  filter: blur(5px);
  z-index: 2;
}
.ball:after {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  top: 5%;
  left: 10%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8) 14%, rgba(255, 255, 255, 0) 24%);
  transform: translateX(-80px) translateY(-90px) skewX(-20deg);
  filter: blur(10px);
}

Ici nous avons la couleur originale à laquelle nous appliquons un dégradé sur la balle elle-même. Le pseudo-element before contient un surlignement plus lumineux qui là aussi commence à la base de la balle et crée l’effet de réflection de la lumière sur la surface.

Le pseudo-selecteur after est notre nouvel ajout. Il contient un dégradé circulaire qui part d’un blanc opaque au centre pour s’atténuer en transparent à environ 24% de la marque. Cela crée un effet de brillance blanc, mais pour qu’il donne le sentiment d’une réflection 3D, nous appliquons une transformation CSS.

La transformation déplace l’effet de brillance de 80 pixels à gauche et 90 en haut et pour donner un effet de déformation. L’effet de translation court le long du cercle sur l’axe X, de manière à ce qu’il soit comme celui que vous observiez sur une boule brillante.

La boule numéro 8

Pour faire une boule de billard, ajoutons une étape supplémentaire et ajoutons le numéro 8.

il nous faut un élément supplémentaire pour contenir le 8, ainsi que des styles pour le placer sur la boule.

<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%;
  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 bord arrondi à 100% est à nouveau utile pour créer le cercle, et ce cercle est positionné en haut à droite avec la propriété transform. Plutôt que de mettre le numéro 8 dans le contenu, j’utilise le pseudo-selecteur before pour ajouter du contenu via la CSS et ensuite faire la translation du numéro de manière comparable au cercle qui le contient.

Le résultat est une boule numéro 8 brillante.

Je garde un oeil sur vous

Un truc vraiment sympa avec les transformations CSS c’est que l’on peut faire des animations. Avec les keyframes CSS pour animations, vous pouvez décrire une série de transformations comme animation et l’appliquer à un élément. Pour vous montrer ça, je vais créer et animer un globe oculaire.

Pour la première étape je vais adapter les couleurs que j’avais utilisé sur l’exemple de la boule numéro 8. Quelques petits trucs et cela ressemble davantage à un oeil. En premier, le HTML : 

<section class="stage">
  <figure class="ball">
    <span class="shadow"></span>
    <span class="iris"></span>
  </figure>
</section>

Le gros de la CSS est comparable à la boule numéro 8, à l’exception de la pupille et de l’iris.

.iris {
  width: 40%;
  height: 40%;
  margin: 30%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, #208ab4 0%, #6fbfff 30%, #4381b2 100%);
  transform: translateX(68px) translateY(-60px) skewX(15deg) skewY(2deg);
  position: absolute;
  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 fait la partie coloré de l’iris et maintenant la pupille et le surlignement sont crées par des pseudo-élements. J’ai aussi ajouté une propriété d’animation sur l’élément de l’iris. Les animations sont attachées à un élément sous cette forme :

animation: animation-name 5s ease-out infinite;

Dans ce cas, nous appliquons une animation appelée "animation-name", qui durera 5 secondes, en boucle infinie et avec un effet d’atténuation de type "ease-out". Ease-out, c’est quand l’animation ralenti en arrivant à sa fin, créant un effet plus naturel.

Sans l’animation créée, nous avons un globe oculaire très statique.

Créons quelques keyframes pour décrire comment ce globe oculaire doit bouger.

@keyframes move-eye-skew {
  0% {
    transform: none;
  }
  20% {
    transform: translateX(-68px) translateY(30px) skewX(15deg) skewY(-10deg) scale(0.95);
  }
  25%, 44% {
    transform: none;
  }
  50%, 60% {
    transform: translateX(68px) translateY(-40px) skewX(5deg) skewY(2deg) scaleX(0.95);
  }
  66%, 100% {
    transform: none;
  }
}

Les keyframes d’animations en CSS peuvent sembler un peu compliqué eu premier abord. Ce que vous êtes en train de faire c’est de décrire l’état d’un élément dans une série de moments. Chaque état est attaché à un pourcentage. Dans ce cas l’iris commence sans aucune transformation. Puis, à 20%, une transformation s’applique qui va le bouger et en faire une translation vers la gauche. L’espace entre 0 et 20% est calculé automatiquement par le navigateur, il crée une transition douce entre les deux points.

cela se poursuit entre chaque keyframe et l’animation en entier dure 5 secondes comme spécifié avant.

N’oubliez pas de créez les versions préfixées et non préfixées moz, ms, o des animations keyframe car certains navigateurs auront besoin de ces préfixes.

Bulles

En utilisant une combinaison d’ombres et d’animation, il est possible de faire de nombreux effets variés et intéressants. Et pourquoi pas quelques bulles?

Faire des bulles est assez similaire à avant, plus de transparence sur la couleur principale et deux pseudo-elements pour la brillance.

L’animation utilise la transformation scale pour faire varier les bulles.

@keyframes bubble-anim {
  0% {
    transform: scale(1);
  }
  20% {
    transform: scaleY(0.95) scaleX(1.05);
  }
  48% {
    transform: scaleY(1.1) scaleX(0.9);
  }
  68% {
    transform: scaleY(0.98) scaleX(1.02);
  }
  80% {
    transform: scaleY(1.02) scaleX(0.98);
  }
  97%, 100% {
    transform: scale(1);
  }
}

L’animation s’applique sur la bulle entière et ses pseudo-elements.

Utiliser des images

Jusque là toutes les boules crées l’ont été sans utiliser d’images. l’application d’une image de fond peut donner plus de détails et continuer à user de l’avantage des ombres CSS avec les pseudo-elements. Par exemple, une texture sans ombre de balle de tennis : 

Unshaded tennis ball image

Ajoutons lui un dégradé CSS pour une illusion de profondeur.

Autour du monde

Les animations peuvent également être appliquées à la position de l’image de fond. Cela permet de créer un globe terrestre qui tourne.

Cette image plate a été étirée un peu en haut et en bas pour être utilisée comme image de fond.

Flat world map

Avec un peu d’ombre et d’animation, le globe terrestre en 3D est là. Sélectionnez "Result" dans le Codepen pour le voir en action. Je l’ai réglé pour afficher le HTML par défaut car la performance de cette exemple est faible, du coup le ventilateur de mon portable à tendance à s’emballer.

Note : un grand merci à Sidoruk Sergey (@Sidoruk_SV) pour l’amélioration de ce globe. Ça rend bien.

Ressources

Quelques bons conseils à propos des dégradés linéaires au cas où vous souhaiteriez en savoir plus.

Vous cherchez d’autres exemples en 3D? Essayez Portal CSS pour votre inspiration.

Vos retours

Tous les exemples donnés sont présents sur mon compte Codepen. Un grand merci à Chris et à l’équipe pour avoir fait ce fantastique outil.

Si vous avez des questions à propos de cet article, contactez moi par mail ou sur Twitter.