Fermer

septembre 29, 2023

Comment créer des formes de ruban CSS avec un seul élément —

Comment créer des formes de ruban CSS avec un seul élément —


Dans cet article, je vais vous montrer comment utiliser des astuces CSS modernes pour créer des formes de ruban CSS sophistiquées avec un minimum de code. En bonus supplémentaire, nos rubans auront des animations de survol !

Les rubans CSS sont partout et vous pouvez trouver une tonne d’articles à leur sujet, mais ceux que nous allons créer ici sont un peu spéciaux. Nous allons nous appuyer sur un seul élément pour créer chacune des formes et sur des variables CSS pour les contrôler facilement. Nous n’allons pas nous fier à des dimensions fixes ou à des nombres magiques. Les formes s’adapteront à leur contenu afin que vous n’ayez pas à vous soucier du texte à l’intérieur.

j’ai fait une collection de formes de ruban CSS avec beaucoup d’exemples sympas, et dans cet article, nous allons en étudier deux types, illustrés ci-dessous.

Ruban plié et ruban tourné

J’appellerai celui de gauche le « ruban plié » et celui de droite le « ruban tourné ».

Création d’une forme de ruban plié CSS

La première étape de la création de notre ruban CSS plié consiste à définir les variables de notre forme.

Nommer les parties de notre forme de ruban : r pour la profondeur de la flèche avant et de la découpe d'extrémité, et s pour la hauteur du pli

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;
}

Deux variables contrôleront la forme et une variable contrôlera la couleur.

Passons maintenant au code. Nous allons principalement nous appuyer sur clip-path. L’image ci-dessous illustre la forme du polygone que nous allons utiliser.

Le ruban rectangle coupé aux deux extrémités

Nous ajoutons un peu de remplissage pour éviter de couper le texte, puis nous appliquons le clip-path:

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;

  line-height: 1.6; 
  padding-inline: 1.2lh calc(var(--r) + .2lh);
  background: var(--c);
  clip-path: polygon(1lh 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,100% 100%, 0 100%,0 100%); 
}

Utilisation de l’unité CSS lh

Vous vous demandez peut-être ce qui se passe avec le lh unité. C’est une nouvelle unité qui correspond au line-height valeur. Puisque nous utilisons une seule ligne de texte, le line-height le réglage est ce qui contrôle la hauteur, donc 1lh équivaut à la hauteur de l’élément, ce qui est super utile. (Vous pouvez en savoir plus sur le lh unité en Un aperçu des unités de dimensionnement CSS.)

Dans clip-pathje dois découper la forme d’un triangle isocèle, et pour ce faire, je dois connaître la hauteur de l’élément. 1lh est égal à cette hauteur.

Un triangle d'angle dont les côtés mesurent 1lh

Maintenant, pour créer la partie pliée, nous allons toujours utiliser clip-path et mettez à jour le polygone précédent. Ce qui est cool avec clip-path c’est qu’il peut couper « en dehors » des limites de l’élément. Cela peut paraître surprenant, voire inutile, étant donné que nous n’avons rien à l’extérieur, mais cela signifie que nous pouvons inclure des éléments comme l’ombre de la boîte, le contour, les pseudo-éléments, etc.

Dans notre cas, nous nous appuierons sur box-shadow. L’image ci-dessous illustre l’astuce.

Une ombre en demi-cercle sous l’extrémité pointue du ruban

Notez comment je mets à jour le clip-path d’inclure quatre nouveaux points, dont trois sont extérieurs à l’élément. Comme la pièce que l’on coupe est à l’extérieur, elle n’est pas visible, mais si on ajoute un gros box-shadow nous faisons si visible. J’ai utilisé une couleur bleue pour illustrer l’idée ci-dessus, mais dans le code nous utiliserons la même couleur que l’arrière-plan :

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;

  line-height: 1.6; 
  padding-inline: 1.2lh calc(var(--r) + .2lh);
  background: var(--c);
  clip-path: polygon(1lh 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,1lh 100%,1lh calc(100% + var(--s)),.5lh calc(100% + var(--s) + var(--r)),0 calc(100% + var(--s)),0 100%);
  box-shadow: 0 0 0 999px var(--c); 
}

Enfin, nous ajoutons une touche d’effet d’ombre en introduisant un dégradé et une autre boîte-ombre et le tour est joué. Notre forme de ruban CSS est parfaite !

Vous vous demandez probablement comment créer le deuxième ruban (le vert). On fait la même chose mais avec un polygone différent. On prend le premier polygone et on l’inverse.

Un polygone peut s’écrire ainsi :

clip-path: polygon(X1 Y1, X2 Y2, ..., Xn Yn)

Pour obtenir la forme opposée, on change tout Xi par 100% - Xi. Aussi simple que cela! Avant de vérifier mon code, essayez de le faire seul en utilisant le polygone du premier ruban.

Dans la démo ci-dessus, survolez les formes pour remarquer une jolie animation. Pour y parvenir, nous devons mettre à jour le polygone au survol en décalant certains points. Je ne réécrirai pas tout le polygone en survol, mais je définirai une variable CSS qui contrôlera le décalage.

Si vous vous concentrez sur l’animation, vous remarquerez que nous avons trois points se déplaçant vers la gauche et trois points se déplaçant également vers le bas et vers la gauche.

Flèches indiquant les points du polygone et la direction dans laquelle ils se déplacent

Nous mettons à jour le Xi des points se déplaçant vers la gauche avec Xi + d et nous mettons à jour le Yi des points en mouvement faisant avec Yi + d. Ensuite, nous mettons simplement à jour la variable d pour contrôler le mouvement :

.ribbon {
  --d: 0px; 
  clip-path: polygon(calc(1lh + var(--d)) 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,calc(1lh + var(--d)) 100%,calc(1lh + var(--d)) calc(100% + var(--s) + var(--d)),calc(.5lh + var(--d)) calc(100% + var(--s) + var(--r) + var(--d)),var(--d) calc(100% + var(--s) + var(--d)),var(--d) 100%);
}
.ribbon:hover {
  --d: .2lh;
}

Si vous voyez un tel polygone pour la première fois, vous risquez d’être confus, car cela semble un peu effrayant. Mais en réalité, ce n’est pas si complexe. Nous avons commencé avec un polygone simple et nous avons lentement ajouté plus de points et plus de calculs jusqu’à atteindre ce polygone complexe.

Création d’une forme de ruban CSS pivotée

Abordons la deuxième forme. Pour celui-ci, nous utiliserons les nouvelles fonctions trigonométriques ainsi que les variables CSS et calc() comme le précédent. Pour comprendre la logique derrière cette forme, faisons-la pivoter et gardons le texte en ligne droite.

Une forme de ruban en forme de Z

J’ajoute un peu de transparence pour voir les parties derrière l’élément principal. J’utiliserai des pseudo-éléments pour les créer. J’ai également ajouté le contour bleu pour illustrer la zone de l’élément. Cette forme sera contrôlée avec deux variables :

.ribbon {
  --r: 30px;  
  --a: 15deg; 
}

Le r fait le même travail qu’avec la forme précédente. Le a contrôlera la rotation de l’élément principal et bien d’autres choses.

Commençons par l’élément principal. Nous pouvons voir sur la figure qu’il faut le couper de chaque côté, vous pouvez donc logiquement penser à utiliser clip-path, mais pas cette fois. Nous nous appuierons sur une coloration dégradée, où la partie à découper aura une couleur transparente :

.ribbon {
  --r: 30px;  
  --a: 15deg; 

  background:
    linear-gradient(calc(90deg + var(--a)),
      #0000 calc(1lh*sin(var(--a))),
      var(--c) 0 calc(100% - 1lh*sin(var(--a))),
      #0000 0
    );
}

Voici la géométrie.

Une forme géométrique utilisée pour couper le triangle d'angle

Le a est la variable d’angle que nous avons définie. Compte tenu de cela, le gradient doit avoir un angle égal à 90deg + aet la couleur transparente devrait commencer à 0 et s’arrêter à d. Faire quelques calculs, d est égal à 1lh*sin(a). Si on applique la même logique de l’autre côté, on obtient le code suivant :

background:
  linear-gradient(calc(90deg + var(--a)),
    #0000 0% calc(1lh*sin(var(--a))),
    var(--c) calc(1lh*sin(var(--a))) calc(100% - 1lh*sin(var(--a))),
    #0000 calc(100% - 1lh*sin(var(--a))) 100%
  );

Nous effectuons une certaine optimisation en supprimant le 0% et 100% (ils sont implicites), et lorsque nous avons deux arrêts de couleur consécutifs et égaux, nous pouvons remplacer le deuxième par 0:

background:
  linear-gradient(calc(90deg + var(--a)),
    #0000 calc(1lh*sin(var(--a))),
    var(--c) 0 calc(100% - 1lh*sin(var(--a))),
    #0000 0
  );

Nous en avons fini avec l’élément principal, passons donc aux pseudo-éléments. Ici aussi, nous avons besoin de quelques astuces de géométrie pour identifier la taille.

Largeurs et hauteurs marquées sur la forme du ruban Z

Nous pouvons facilement trouver la hauteur H à partir de la figure précédente que nous avons utilisée pour identifier la configuration du gradient. C’est égal à 1lh/cos(a). Pour la largeur W, elle est égale à (100% - x)*cos(a)100% est la largeur de l’élément principal et x est cette petite partie où nous avons la transparence. C’est égal à 1lh*tan(a).

Les deux pseudo-éléments ont la même taille, notre code est donc le suivant :

.ribbon:before,
.ribbon:after {
  content: "";
  position: absolute;
  height: calc(1lh/cos(var(--a)));
  width: calc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
}

Si vous n’êtes pas à l’aise avec les mathématiques et que vous êtes un peu perdu avec la formule, ce n’est pas grave. Vous n’avez pas besoin de les comprendre avec précision. Le but est de pouvoir ajuster la forme à l’aide de variables CSS. Les formules sont là pour faciliter les choses et nous éviter d’avoir affaire à des valeurs codées en dur et à des nombres magiques.

Après la dimension, nous devons placer correctement chaque pseudo-élément, le faire pivoter et utiliser clip-path pour la partie découpée :

.ribbon:before,
.ribbon:after {
  content: "";
  position: absolute;
  transform: translate3d(0,0,-1px);
  rotate: var(--a);
  height: calc(1lh/cos(var(--a)));
  width: calc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
  background: color-mix(in srgb,var(--c),#000 40%);
}
h1:before {
  right: 0;
  top: 0;
  transform-origin: top right;
  clip-path: polygon(0 0,100% 0,100% 100%,0 100%,var(--r) 50%);
}
h1:after {
  left: 0;
  bottom: 0;
  transform-origin: bottom left;
  clip-path: polygon(0 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
}

Le code doit être explicite et le clip-path la valeur doit être facile à comprendre. Nous avons utilisé des polygones plus complexes avec la première forme.

Notez l’utilisation de color-mix(), ce qui me permet de créer une version sombre de la couleur principale. J’utilise également une translation 3D avec une valeur négative sur l’axe z pour amener les pseudo-éléments derrière l’élément principal. Vous pourriez penser que c’est le travail de z-indexmais cela ne fonctionnera pas en raison de problèmes de contexte d’empilement que j’ai détaillés dans ce fil de discussion Stack Overflow.

Maintenant, si nous faisons pivoter l’élément dans la direction opposée, nous obtenons notre forme de ruban CSS.

Comme pour l’exemple précédent, je vous laisse décortiquer le code du ruban vert et voir quelles modifications j’ai apportées pour obtenir la forme opposée.

Conclusion

C’était un exercice amusant, vous ne trouvez pas ? Nous avons exploré certaines fonctionnalités CSS modernes telles que les variables CSS, calc()et les fonctions trigonométriques, et nous les avons combinées pour créer des formes de ruban fantaisistes.

Si vous en voulez plus, allez voir ma collection complète de formes de ruban. Essayez d’en construire certains seul avant de vérifier le code. Ce sera un bon exercice pour mettre en pratique ce que vous avez appris ici.






Source link