Créer des icons 100% CSS

Page de code HTML/CSS

En me promenant un peu sur Youtube allant de vidéos en vidéos, je suis tombé sur une conférence très intéressante de Wenting Zhang, qui nous expliquait comment dessiner une petite moustache en utilisant uniquement du CSS. Elle expliquait qu’elle s’était lancée dans un projet de création d’une multitude d’icons uniquement en CSS sur son site. Aimant beaucoup jouer avec le CSS (puisque je m’étais déjà lancé dans le projet de créer un zombie de Minecraft en 3D et animé uniquement à l’aide de HTML et de CSS) j’ai pensé qu’il serait intéressant de me lancer également dans cet exercice. Cet article s’adresse surtout à des personnes ayant déjà des connaissances en CSS et n’a pas vocation à vous expliquer comment le CSS fonctionne en lui-même (à part pour les propriétés évoquées).

Le projet

Histoire d’aller dans une direction et d’éviter de simplement me contenter de designer des icons uniquement pour le plaisir, j’ai décidé de me donner quelques directives pour en faire un réel projet qui serait utilisable dans un cas pratique. Chaque icon doit donc impérativement être composé d’une seule balise <i> afin de simplifier leur utilisation, leur taille doit être modifiable depuis le font-size du parent et sa couleur modifiable depuis le color du parent.

Tous les icons sont également utilisables depuis un seul et même fichier CSS (un peu comme chez FontAwesome). Les bases étant fixées, j’ai donc pu me lancer dans mon propre projet d’icons en CSS. Nous allons donc dans cet article essayer d’en dessiner quelques uns ensemble !

Icons en CSS
Une partie des icons que j’ai commencé à créer en CSS

Les éléments CSS à notre disposition

L’utilisation d’une seule balise pour chacun des icons pourrait laisser croire que nous devrions nous contenter d’icons très simples (basiques) mais en réalité, une seule balise HTML nous permet de manipuler plusieurs éléments.

Les pseudo-éléments

Depuis CSS 2, chaque balise possède également deux pseudo-éléments : ::before et ::after. Un pseudo-élément va être (comme son nom l’indique) un élément supplémentaire contenu dans l’élément auquel il est rattaché. Chacun de ces pseudo-éléments va pouvoir avoir quasiment les mêmes propriétés que l’élément principal ce qui fait qu’avec une balise nous pouvons contrôler trois formes différentes.

Les ombres

Depuis CSS 3, chaque élément peut avoir une ou plusieurs ombres que vous pouvez positionner, redimensionner et colorer comme bon vous semble. Chaque forme que vous créez peut donc être dupliquée autant de fois que vous le voulez avec la taille et la couleur de votre choix.

Les transformations

CSS 3 a aussi vu l’ajout des transformations des éléments arriver. Je ne me sers pas énormément des transform pour les icons mais le rotate() se révèle parfois bien pratique. En cas de besoin, vous pouvez par exemple « pencher » un élément avec skew() (qui produit le même effet que mettre un texte en italique).

Les bordures

Enfin, pour certaines formes un peu particulières tels les triangles, les courbes, les pointes, etc, vous pouvez manipuler les bordures comme bon vous semble. Vous pouvez par exemple jouer sur les arrondis avec border-radius. Vous pouvez aussi jouer sur les couleurs et la transparence des bordures pour créer des former triangulaires. Et si vous combinez les deux vous pouvez par exemple créer une forme de corne (reste à savoir ce que vous allez en faire).

Mais encore une fois, lorsqu’il s’agit de développement, rien de tel que la pratique ! C’est donc parti pour designer nos premiers icons en CSS ! Nous allons ici voir l’exemple de deux icons : un stylo, et une bulle de commentaire.

Le stylo

Icon de stylo en CSS

Comme expliqué plus haut, nos items ne sont composés que d’une balise <i> donc contentez vous d’écrire dans votre body :

<i class="pen"></i>

Nous allons commencer par créer le « corps » du stylo.  Par souci de simplicité, j’essaie de faire en sorte que la balise <i> soit l’élément central de l’icon en règle générale, les pseudos éléments naviguent ensuite autour. Tout d’abord, histoire de simplifier leur positionnement, j’ai décidé que les icons seraient en position: absolute ! Cela nécessite donc de mettre le parent en relative si besoin est. De façon tout à fait arbitraire, nous décidons qu’il fera 2em de haut et 0.7em de large (1em correspond à la taille actuelle de la police d’écriture). Pour le faire apparaître à l’écran, il faut ensuite lui donner une background-color (sa couleur étant par défaut transparente). Il existe une propriété intéressante pour ça en CSS : il s’agit du currentColor qui va correspondre à la couleur de texte actuelle. Nous avons donc déjà ceci :

.pen {
  position: absolute;
  width: 0.7em;
  height: 2em;
  background-color: currentColor;
}

Nous avons donc pu faire apparaître une magnifique barre droite ! Nous devons maintenant nous occuper de la partie supérieure,  en utilisant un ::before. Une des règles du pseudo-élément réside dans le fait qu’il faut impérativement remplir la propriété content, sinon le pseudo-élément ne s’affichera pas. Contentez-vous d’un content: «  » puis mettez sa position en absolute (pour la même raison que l’élément principal). Comme pour l’élément principal, la largeur doit être de 0.7em, tandis que cette fois-ci la hauteur ne sera que de 0.5em. Encore une fois, pour le voir apparaître, son background-color doit être en currentColor.

Il reste ensuite à le positionner : son left doit être à 0 (on veut qu’il soit aligné avec l’élément principal) et son top doit être à -0.6em pour laisser un espace de 0.1em entre les deux parties – sa taille étant je le rappelle de 0.5em et la position se calculant à partir de la partie haute de l’élément -. Enfin, nous allons arrondir les bords supérieurs en utilisant la propriété border-radius, nous arrivons donc à :

.pen::before {
  content: '';
  position: absolute;
  background-color: currentColor;	
  width: 0.7em;
  height: 0.5em;
  top: -0.6em;
  left: 0;
  border-radius: 100% 100% 0 0;
}

Je rappelle que le border-radius commence par le coin supérieur gauche et tourne dans le sens des aiguilles d’une montre.

Nous pouvons donc passer à la pointe. Pour cela, ça nous allons utiliser l’élément ::after qui doit également être en absolute, avec un content vide et un background-color qui vaut currentColor pour les mêmes raisons que l’élément ::before. Nous allons nous servir des bordures pour créer un triangle dont le centre sera le contenu du after : pour obtenir un effet pointu nous devons donc mettre la hauteur et la largeur à 0. Ici encore le left devra être de 0 pour que la pointe soit alignée avec le corps ; le top sera quant à lui à 2.1em (puisque le corps fait 2em de haut et que nous voulons un espace de 0.1em entre le corps et la pointe).

Nous allons maintenant nous occuper des bordures : mettez les 4 bordures en solid et en 3.5em de largeur (la bordure est située de chaque côté, et comme la pointe doit faire 0.7em de largeur comme le corps, nous devons diviser cette largeur par 2 pour obtenir la taille de la bordure). Nous voulons ensuite que seule la bordure supérieure soit colorée, le reste sera transparent. Pour ce faire, utilisez la syntaxe suivante: border-color: currentColor transparent transparent. Nous ne précisons ici que trois couleurs, puisque les couleurs vont de pair pour les bordures. Si vous ne précisez pas la quatrième, elle sera de la même couleur que la seconde.

.pen::after {
  content: '';
  position: absolute;
  width: 0;
  height: 0;
  left: 0;
  top: 2.1em;
  border: solid 0.35em;
  border-color: currentColor transparent transparent;
}

Il ne nous reste plus qu’à mettre un petit transform: rotate(40deg) sur notre élément principal pour qu’il soit penché comme sur la plupart des icons de stylo. Voilà, nous venons de dessiner un stylo uniquement à l’aide d’une balise et d’un peu de CSS ! Voici le code complet :

<!DOCTYPE html>
<html>
<head>
  <title>Icons</title>
  <style type="text/css">
    .pen {
      position: absolute;
      width: 0.7em;
      height: 2em;
      background-color: currentColor;
      transform: rotate(40deg);
    }
    .pen::before {
      content: '';
      position: absolute;
      background-color: currentColor;	
      width: 0.7em;
      height: 0.5em;
      border-radius: 100% 100% 0 0;
      top: -0.6em;
      left: 0;
    }
    .pen::after {
      content: '';
      position: absolute;
      width: 0;
      height: 0;
      left: 0;
      top: 2.1em;
      border: solid 0.35em;
      border-color: currentColor transparent transparent;
    }
  </style>
</head>
<body>
  <i class="pen"></i>
</body>
</html>

La bulle de discussion

Icone commentaire

Comme pour le stylo, vous n’avez besoin que d’une balise avec la bonne classe dans votre body. Ici encore l’élément principal sera en position: absolute et en background-color: currentColor ! Une fois n’est pas coutume, nous allons choisir tout à fait arbitrairement une hauteur de 2em et une largeur de 3em. Pour avoir un effet arrondi parfait nous allons également mettre le border-radius à 100%.

.comment {
  position: absolute;
  background-color: currentColor;
  width: 3em;
  height: 2em;
  border-radius: 100%;
}

En ce qui concerne la petite pointe en dessous de la bulle, nous allons ajouter un pseudo-élément before. Il faut donc impérativement mettre une valeur vide à son content. Afin de lui donner une forme de corne (maintenant, vous savez donc comment l’utiliser !) nous devons créer un rond vide avec seulement la bordure du bas. Nous allons donc laisser le background-color tel qu’il est et définir sa hauteur comme sa largeur à 1em. Nous voulons obtenir un rond comme indiqué plus haut, le border-radius doit donc être de 100%. Pour avoir une pointe, il faut que l’une des bordures ait une largeur nulle, il convient donc définir sa bordure comme étant solide et de largeur border-width: 1em 1em 1em 0. Enfin, nous voulons que seule la bordure inférieure apparaisse, il est nécessaire de colorer les autres en transparent, en appliquant border-color: transparent transparent currentColor.

Nous voulons en revanche que la pointe se situe sur le dessous et non sur le côté : nous allons utiliser le transform en définissant que nous voulons effectuer la rotation, en prenant comme origine le côté droit grâce à transform-origin: right et en faisant tourner notre pointe de 80° sur la gauche, soit transform: rotate(-80deg). Je vous épargne le calcul du placement, le top doit donc être de -1.4em dans notre cas et le left de -1.7em.

.comment::before {
  content: '';
  position: absolute;
  width: 1em;
  height: 1em;
  border-radius: 100%;
  border: solid;
  border-width: 1em 1em 1em 0;
  border-color: transparent transparent currentColor;
  left: -1.7em;
  top: -1.4em;
  transform: rotate(-80deg);
  transform-origin: right;
}

Vous avez déjà une belle forme de bulle de bande-dessinée mais nous allons y ajouter des points de suspension. Pour ce faire, nous allons dessiner un rond blanc avec un pseudo-élément after. Nous devons donc bien évidemment mettre le background-color à #FFF et le border-radius à 100%. Quant à la taille, j’ai choisi 0.4em: car la taille de notre élément est un chiffre pair ; il vaut mieux que les éléments à l’intérieur aient une taille paire aussi pour les positionner plus facilement. Nous devons ensuite le centrer verticalement avec un top: 0.8em que nous allons le placer à 0.6em de la gauche.

Pour créer les deux autres points, nous allons utiliser les fameuses ombres ! La première sera à 0.7em vers la gauche et la seconde à 1.4em, toutes les deux en blanc (les ombres sont par défaut de la même couleur que le texte, donc ici en noir). Leur blur et leur spread doivent être tous les deux à 0, ce qui donne au final :

.comment::after {
  content: '';
  position: absolute;
  background-color: #FFF;
  border-radius: 100%;
  width: 0.4em;
  height: 0.4em;
  left: 0.6em;
  top: 0.8em;
  box-shadow:
    0.7em 0 0 0 #FFF,
    1.4em 0 0 0 #FFF;
}

Ce qui nous donne en globalité :

<!DOCTYPE html>
<html>
<head>
  <title>Icons</title>
  <style type="text/css">
    .comment {
      position: absolute;
      background-color: currentColor;
      width: 3em;
      height: 2em;
      border-radius: 100%;
    }
    .comment::before {
      content: '';
      position: absolute;
      width: 1em;
      height: 1em;
      border-radius: 100%;
      border: solid;
      border-width: 1em 1em 1em 0;
      border-color: transparent transparent currentColor;
      left: -1.7em;
      top: -1.4em;
      transform: rotate(-80deg);
      transform-origin: right;
    }
    .comment::after {
      content: '';
      position: absolute;
      background-color: #FFF;
      border-radius: 100%;
      width: 0.4em;
      height: 0.4em;
      left: 0.6em;
      top: 0.8em;
      box-shadow:
        0.7em 0 0 0 #FFF,
        1.4em 0 0 0 #FFF;
    }
  </style>
</head>
<body>
  <i class="comment"></i>
</body>
</html>

 

Nous avons donc fini de dessiner notre bulle ! Au travers de ces deux icons, nous avons pu voir à peu près tous les éléments dont vous avez besoin pour dessiner tous ceux que j’ai déjà créé, il ne vous manque plus qu’à trouver une idée d’icon à créer et de vous lancer ! Et si vous trouvez cela trop simple, vous pouvez toujours apprendre le Brainfuck !

 

Ne manquez aucun article: inscrivez-vous à notre Newsletter:

Laisser un commentaire