Comment et pourquoi dessiner en CSS ?

Comment et pourquoi dessiner en CSS ?

Aujourd’hui je suis très heureux de recevoir Dorian pour cet Article invité ! Merci à lui de continuer la danse avec cette excellente lecture sur le CSS.




Dorian est un développeur web et un mentor à OpenClassrooms. Sur son blog, Il parle de code, de CSS, de design et d’autres trucs. Tu retrouveras des séries d’articles, des astuces, des tutoriels, plein d’expériences et des ressources intéressantes.




Dans cet article on va détourner une technologie de son usage initial et on va faire de la magie noire. 🧙‍♂️

On va parler à 200% de CSS car je vais te montrer comment dessiner en CSS.

Mais pourquoi dessiner en CSS ? Personnellement j’y attache deux raisons : apprendre et passer un bon moment. Personnellement c’est comme ça que j’en ai appris autant sur le CSS. En réalisant des challenges créatifs avec uniquement du CSS et en les partageant.

Je vais reproduire une illustration de Marko Stupic dans le but de te faire découvrir cette « discipline » où l’on peut créer, apprendre et passer un bon moment en même temps.

J’aimerais préciser que pour l’article je vais uniquement reproduire une illustration. Mais rien ne t’empêche d’utiliser le dessin en CSS comme un moyen de t’exprimer et d’allier l’apprentissage à la création.

Au passage dans tout l’article quand je parlerais d’un nouvel élément, j’écrirais entre parenthèses les classes CSS liées à celui-ci. Comme ça il te sera plus facile de comprendre le code en le lisant.



Définir une « scène »

Je commence par définir le fond de notre scène (.scene). C’est assez simple, je vais tout simplement créer un dégradé circulaire en partant du centre, le tout en donnant à la première couleur plus d’importance.



background: radial-gradient(circle, #1d1440 300px, #0e0b29);


J’en profite pour définir toute ma scène en display: flex; en centrant les éléments verticalement et horizontalement. Cela m’évitera de devoir le faire pour chaque élément.

L’avantage c’est aussi que je pourrais gérer la taille et le positionnement de toute ma création simplement en agissant sur cette scène.



Dessiner la fenêtre

Maintenant on va dessiner la fenêtre, c’est l’élément central de l’illustration.

Je vais d’abord créer un élément (.window) qui me servira de container pour tous les éléments de ma fenêtre et de cadre. Pour le cadre c’est tout simplement un rond en CSS avec une bordure assez épaisse.

Ensuite je crée un nouvel élément (.glass) et j’utilise les pseudos-éléments after et before pour créer deux nouveaux éléments (.glass::before et .glass::after) qui vont composer nos supports de fenêtres.

Petite astuce, j’utilise des rectangles avec des bordures sur les axes X et Y pour réaliser les supports de fenêtres plus simplement. Comme ça je peux régler leur taille juste en modifiant les propriétés height ou width.

Pour terminer je vais définir un effet de lumière bleue sur la vitre. Pour cela j’utilise un ombrage orienté vers l’intérieur de mon élément, un peu comme si je voulais créer un effet néon.



box-shadow: inset 0px 5px 36px 8px rgba(72,148,247,1);


Et hop on arrive au résultat suivant.



Ajouter des ombres et de la lumière en CSS

Maintenant que j’ai une fenêtre, je vais devoir représenter les ombres et la lumière émise à travers la fenêtre.

Quand on dessine en CSS, il n’est pas possible de créer une source de lumière et de générer des ombres comme par magie. Il va donc falloir jouer avec les ombrages et les couleurs pour créer ces effets.



Lumière émise

Je vais commencer par les effets de lumière. Cette lumière va permettre de donner du relief à ma fenêtre.

Grâce au dégradé défini dans notre scène, nous avons déjà créé notre premier effet de lumière.

Pour créer le deuxième effet de lumière (présent sous la fenêtre), je vais créer un élément (.light), dans lequel je vais définir un ovale.

J’utilise un ovale pour créer un effet de relief simple, le bas de mon effet sera plus large que ses côtés, comme si la lumière se propageait vers l’avant.

Je vais ensuite lui définir un dégradé qui part de la couleur de fond vers une couleur plus claire.

Avant et après. On distingue maintenant plus clairement la fenêtre.



Ombres

“You need the dark in order to show the light.” Bob Ross

Comme on peut le voir sur l’illustration, les supports de la fenêtre vont créer des ombres qui indirectement définissent la lumière produite par la fenêtre.

Pour dessiner ces ombres, on va d’abord créer un nouvel élément (.shadow) qui sera un enfant de l’élément de la lumière (.light).

Afin de créer les ombres, je vais utiliser la même astuce que pour mes supports de fenêtres. After et before + deux carrés.

Premièrement, j’applique une rotation de 45 degrés au premier carré (.shadow::after) afin de créer un losange. Il me suffit ensuite de le positionner au centre et de lui ajouter deux bordures pour réaliser les ombres.

Pour le deuxième carré, c’est le même principe, sauf que je vais utiliser la fonction skew() qui permet de créer une distorsion en étirant l’élément.

Je vais, grâce à cette fonction, pouvoir créer un losange plus large que le précédent et donc l’utiliser pour créer une ombre qui suit la trajectoire de la lumière.

Ça peut-être difficile à comprendre je le conçois, c’est pourquoi j’ai ajouté des commentaires et j’ai laissé les bordures colorées sur le Codepen afin que tu puisses mieux appréhender le concept.



Créer l’extérieur et la vue sur l’espace.

Je vais maintenant me charger de créer le décor extérieur. Je vais dessiner en CSS des nuages et des étoiles.



Ciel et étoiles

Pour le fond de mon décor je vais utiliser un élément (.sky) avec deux dégradés de couleurs, un pour le ciel et un autre pour le fond des nuages. Passons aux étoiles.

Je pense que je t’apprends rien mais un développeur c’est feignant, du coup pour les étoiles je vais tout simplement utiliser SCSS. Ça me permet d’utiliser une boucle for pour créer le style de mes étoiles et créer de l’aléatoire dans leur positionnement.

Une boucle, des valeurs aléatoires, un peu de maths pour générer plus d’étoiles en haut de ma fenêtre qu’en bas, du CSS. Et.. voici un ciel avec des étoiles qui changent de place à chaque rendu.



Nuages

Pour les nuages, je ne vais pas devoir faire le feignant. Surtout si je veux que ça ressemble à peu près à l’image. Je n’ai pas le choix, je vais devoir les placer à la main. 😬

Je vais donc créer deux wrappers (.white-clouds et .gray-clouds) dans lesquels je vais créer des éléments (.cloud) qui composeront les nuages. Ça me permet de décrire le style des nuages dans les wrappers et d’avoir uniquement à positionner mes bouts de nuages dans le reste du CSS. J’aère le code et je fais moins de répétitions.

Pour les bouts des nuages, je fais simple et je vais créer des carrés blancs ou gris avec une bordure arrondie au maximum. J’utilise en plus les pseudos-éléments after et before pour créer 3 bouts de nuages par élément (.cloud).

Pour finir je vais utiliser la pseudo-classe :nth-child pour positionner tous mes bouts de nuages. Voici un petit extrait du code SCSS pour un nuage.



&:nth-child(1) {
  left: 25%; bottom: -5%;
  width: 70px; height: 70px;
  &::before {
    bottom: 50%; right: 120%;
    width: 60px; height: 60px;
  }
  &::after {
    top: 10%; right: 50%;
    width: 90px; height: 90px;
  }
}


Comme tu peux le voir dans le code, je vais uniquement gérer le positionnement de mes nuages. On pourrait même encore l’optimiser avec du SCSS pour simplifier et réduire la quantité de code.





Bonus avant de finir

Un petit plus avant de finir. En effet j’ai décidé de ne pas dessiner en CSS les astronautes car sinon l’article aurait été trop long (en plus c’est moins intéressant à expliquer). J’ai donc créé un casque vide inspiré de l’image pour habiller un peu la scène.

Voici le résultat en image du schéma jusqu’à l’implémentation.





5 éléments CSS pour un « casque »

Je vais rapidement détailler les étapes et les techniques utilisées :

1 – Je crée un élément et j’arrondis les angles.

2 – J’ajoute le derrière du casque avec la même technique, en arrondissant à 80% un côté.

3 – Je clone le premier élément et j’utilise un linear-gradient pour n’afficher que la partie de devant.



linear-gradient(to right, #271a51 0px, #271a51 25px, transparent 25px);

Avec ce code je n’affiche que 25% de l’élément.

4 – Je crée un élément en arrière-plan, je l’arrondi au maximum, j’utilise un linear-gradient pour créer un effet fumé puis un box-shadow pour créer du relief.

5 – Pour finir j’utilise et je positionne un élément en forme de cercle avec seulement la bordure droite de visible afin d’arrondir le casque au niveau de la visière.



Résultat final

Pour la touche finale, j’ai animé le casque avec une simple animation de rotation et je l’ai positionné derrière la fenêtre, prêt à dériver dans l’espace.

Et voici le résultat, que je te conseille au passage de regarder en plein écran.





Conclusion

Bon ok c’est sympa, mais sinon ça sert à quoi de dessiner en CSS ? Pourquoi ajouter 500 lignes de CSS alors que je peux utiliser du SVG ?

C’est effectivement ce que l’on pourrait se dire à la suite de cet article et c’est vrai. Cependant tu as surement remarqué que j’ai utilisé une pléthore de propriétés CSS comme par exemple des box-shadow, des gradients, des transformations, des positionnements, des pseudos-éléments, mais aussi du SCSS et un peu de maths.

Et c’est là que dessiner en CSS prend tout son sens. C’est selon moi un excellent moyen de progresser en CSS tout en créant.

Au final il ne faut pas oublier que le métier de développeur c’est avant tout un métier créatif, alors autant apprendre en créant.

Qui me parle ?

Dorian
Dorian est un développeur web et un mentor à OpenClassrooms. Sur son blog, Il parle de code, de CSS, de design et d’autres trucs. Tu retrouveras des séries d’articles, des astuces, des tutoriels, plein d’expériences et des ressources intéressantes.

4 commentaires sur “Comment et pourquoi dessiner en CSS ?”

  1. c’est génial ce qu’il a fait ! Cela donne pas mal envie de se lancer à faire des choses comme ça (ce qui change des maquettes de sites internet)

T'en penses quoi ?

Your email address will not be published. Required fields are marked *