Fermer

novembre 19, 2023

Formes de ruban multilignes réactives CSS (partie 1) —

Formes de ruban multilignes réactives CSS (partie 1) —


Au début des années 2010, il était presque impossible d’éviter les formes de ruban dans les conceptions Web. C’est en fait en 2010 que Chris Coyier a partagé un extrait CSS qui, j’en suis sûr, a été utilisé des milliers de fois.

Et pour cause : les rubans sont amusants et intéressants à regarder. Ils sont souvent utilisés pour les titres, mais ce n’est bien sûr pas tout. Vous trouverez des rubans de coin sur les fiches produits (« Soldes ! »), des badges avec des extrémités de ruban coupées (« Première place ! ») ou même des rubans servant d’icônes pour les marque-pages. Les rubans sont ludiques, s’enroulant autour des éléments, ajoutant de la profondeur et des ancrages visuels pour attirer l’attention.

J’ai créé une collection de plus de 100 formes de ruban, et nous allons en étudier quelques-uns dans cette petite série en deux parties. Le défi est de s’appuyer sur un seul élément pour créer différents types de formes de ruban. Ce que nous voulons vraiment, c’est créer une forme qui peut accueillir autant de lignes de texte que vous leur lancez. En d’autres termes, il n’existe pas de dimension fixe ni de nombres magiques : la forme doit s’adapter à son contenu.

Voici une démo de ce que nous construisons dans cette première partie :

Voir le stylo [Responsive multi-line ribbon shapes](https://codepen.io/smashingmag/pen/LYMjNoo) par Accompagner Afif.

Voir le stylo Formes de ruban multilignes réactives par Accompagner Afif.

Vous pouvez jouer avec le texte, ajuster la taille de l’écran, modifier les propriétés de la police et la forme s’adaptera toujours parfaitement au contenu. Cool, non ? Ne regardez pas le code pour l’instant car nous allons le construire ensemble à partir de zéro.

Comment ça marche?

Nous allons nous appuyer sur un seul élément HTML, un <h1> dans ce cas, vous pouvez utiliser n’importe quel élément de votre choix à condition qu’il puisse contenir du texte.

<h1>Your text goes here</h1>

Maintenant, si vous regardez attentivement les formes du ruban, vous remarquerez une disposition générale qui est la même pour les deux modèles. Il y a vraiment un morceau qui se répète encore et encore.

Forme de ruban avec une pièce sélectionnée qui se répète sur toute la forme
(Grand aperçu)

Bien sûr, ce n’est pas exactement la forme de ruban que nous souhaitons, mais il ne nous manque que les découpes aux extrémités. L’idée est de commencer par ce design générique et d’ajouter la décoration supplémentaire au fur et à mesure.

Les deux rubans de la démo que nous avons examinée sont construits en utilisant à peu près le même CSS ; les seules différences sont les nuances qui aident à les différencier, comme la couleur et la décoration. C’est ma sauce secrète ! La plupart de les rubans de mon générateur partagent une structure de code commune et j’ajuste simplement quelques valeurs pour obtenir différentes variations.

Commençons par les dégradés

Chaque fois que j’entends dire que la conception d’un composant doit être répétée, je pense instantanément aux dégradés d’arrière-plan. Ils sont parfaits pour créer des motifs reproductibles et sont capables de tracer des lignes avec des arrêts nets entre les couleurs.

Nous parlons essentiellement d’appliquer un arrière-plan derrière un élément de texte. Chaque ligne de texte obtient l’arrière-plan et se répète pour autant de lignes de texte qu’il y en a. Le dégradé doit donc être aussi grand qu’une ligne de texte. Si vous ne le saviez pas, nous avons récemment obtenu la nouvelle hauteur de ligne (lh) unité en CSS qui nous permet d’obtenir la valeur calculée de l’élément line-height. Dans notre cas, 1lh sera toujours égal à la hauteur d’une ligne de texte, ce qui est parfait pour ce dont nous avons besoin.

Lignes de texte avec une mesure à côté d'une hauteur de ligne égale à 1lh
(Grand aperçu)

Note: Il semble que Safari utilise la hauteur de ligne calculée d’un élément parent plutôt que de baser la hauteur de ligne lh unité sur l’élément lui-même. J’en ai tenu compte dans le code en définissant explicitement un line-height sur le body élément, qui est le parent dans notre cas spécifique. Mais j’espère que cela deviendra inutile à un moment donné dans le futur.

Abordons notre premier dégradé. C’est une forme rectangulaire derrière le texte qui couvre une partie de la ligne et laisse un espace de respiration entre les lignes.

Un dégradé de forme rectangulaire de couleur rouge marqué de 70 % et 30 % de couleur transparente entre les lignes
(Grand aperçu)

La couleur rouge du dégradé est définie sur 70% de la hauteur, ce qui laisse 30% de couleur transparente pour tenir compte de l’espace entre les lignes.

h1 {
  --c: #d81a14;
  
  background-image: linear-gradient(var(--c) 70%, #0000 0);
  background-position: 0 .15lh;
  background-size: 100% 1lh;
}

Rien de bien complexe, non ? Nous avons établi un dégradé de fond sur un h1 élément. La couleur est contrôlée avec une variable CSS (--c), et nous l’avons dimensionné avec le lh unité pour l’aligner avec le contenu du texte.

Notez que le décalage (.15lh) est égal à la moitié de l’espace entre les lignes. Nous aurions pu utiliser un dégradé avec trois valeurs de couleur (par exemple, transparent, #d81a14et transparent), mais il est plus efficace et plus lisible de conserver les éléments en deux couleurs, puis d’appliquer un décalage.

Ensuite, nous avons besoin d’un deuxième dégradé pour la partie enroulée ou inclinée du ruban. Ce dégradé est positionné derrière le premier. La figure suivante le démontre en ajoutant un peu d’opacité à la couleur du ruban avant pour mieux voir la relation.

Deux lignes de texte avec un dégradé pour la partie enveloppée du ruban positionnée derrière le premier dégradé
(Grand aperçu)

Voici comment je l’ai abordé :

linear-gradient(to bottom right, #0000 50%, red 0 X, #0000 0);

Cette fois, nous utilisons des mots-clés pour définir la direction du dégradé (to bottom right). Pendant ce temps, la couleur commence à la diagonale (50%) au lieu de sa valeur par défaut 0% et devrait s’arrêter à une valeur que nous indiquons comme X pour un espace réservé. Cette valeur est un peu délicate, alors obtenons un visuel qui illustre ce que nous faisons.

Un dégradé pour la partie enveloppée du ruban avec la flèche verte qui illustre la direction du dégradé avec différents arrêts de couleur
(Grand aperçu)

La flèche verte illustre le sens du dégradé, et on peut voir les différents arrêts de couleurs : 50%, Xet 100%. Nous pouvons appliquer quelques règles de géométrie pour résoudre X:

(X - 50%) / (100% - 50%) = 70%/100%
X = 85%

Cela nous donne le point exact de la fin de l’arrêt de couleur dure du dégradé. Nous pouvons appliquer le 85% valeur à notre configuration de dégradé en CSS :

h1 {
  --c: #d81a14;
  
  background-image: 
    linear-gradient(var(--c) 70%, #0000 0), 
    linear-gradient(to bottom left, #0000 50%, color-mix(in srgb, var(--c), #000 40%) 0 85%, #0000 0);
  background-position: 0 .15lh;
  background-size: 100% 1lh;
}

Vous avez probablement remarqué que j’ai ajouté le nouveau color-mix() fonction au deuxième dégradé. Pourquoi le présenter maintenant ? Parce qu’on peut l’utiliser pour mélanger la couleur principale (#d81a14) avec du blanc ou du noir. Cela nous permet pour obtenir des valeurs de couleur plus foncées ou plus claires sans avoir à introduire plus de valeurs de couleur et de variables dans le mélange. Cela aide à garder les choses efficaces !

Voir le stylo [The gradient configuration](https://codepen.io/smashingmag/pen/eYbwwyo) par Accompagner Afif.

Voir le stylo La configuration du dégradé par Accompagner Afif.

Nous avons réalisé la pièce principale de la conception ! Nous pouvons porter notre attention sur la création de la forme du ruban. Vous remarquerez des répétitions indésirables en haut et en bas. Ne vous inquiétez pas ; il sera corrigé dans la section suivante.

Ensuite, fabriquons les rubans

Avant d’entrer dans le vif du sujet, prenons un moment pour nous rappeler que nous fabriquons deux rubans. La démo au début de cet article fournit deux exemples : un rouge et un vert. Ils sont similaires dans leur structure mais diffèrent dans les détails visuels.

Pour le premier, nous prenons le début et la fin du ruban et en découpons un triangle. Nous ferons la même chose avec le deuxième exemple de ruban avec une étape de pliage supplémentaire pour la partie découpée.

Le premier ruban

La seule chose que nous devons faire pour le premier ruban est d’appliquer un clip-path pour découper la forme triangulaire des extrémités du ruban tout en coupant les artefacts indésirables du dégradé répétitif en haut et en bas du ruban.

Deux variantes du premier ruban avant et après l'application du chemin de détourage
(Grand aperçu)

Nous disposons de toutes les coordonnées nécessaires pour effectuer nos découpes à l’aide du polygon() fonction sur le clip-path propriété. Les coordonnées ne sont pas toujours intuitives, mais j’ai développé le code et ajouté quelques commentaires ci-dessous pour vous aider à identifier certains points de la figure.

h1 {
  --r: 10px; /* control the cutout */

  clip-path: polygon(
   0 .15lh, /* top-left corner */
   100% .15lh, /* top right corner */
   calc(100% - var(--r)) .5lh, /* top-right cutout */
   100% .85lh,
   100% calc(100% - .15lh), /* bottom-right corner  */
   0 calc(100% - .15lh), /* bottom-left corner */
   var(--r) calc(100% - .5lh), /* bottom-left cutout */
   0 calc(100% - .85lh)
  );
}

Ceci termine le premier ruban ! Maintenant, nous pouvons conclure (jeu de mots) avec le deuxième ruban.

Le deuxième ruban

Nous utiliserons les deux pseudo-éléments pour compléter la forme. L’idée peut être décomposée ainsi :

  1. Nous créer deux rectangles qui sont placés au début et à la fin du ruban.
  2. Nous faites pivoter les deux rectangles avec un angle que l’on définit à l’aide d’une nouvelle variable, --a.
  3. Nous Appliquer un clip-path pour créer la découpe et le découpage du triangle là où le dégradé vert déborde du haut et du bas de la forme.
Le deuxième ruban en trois images : avec deux rectangles créés, deux rectangles pivotés et un chemin de détourage appliqué
(Grand aperçu)

Tout d’abord, les variables :

h1 {
  --r: 10px;  /* controls the cutout */
  --a: 20deg; /* controls the rotation */
  --s: 6em;   /* controls the size */
}

Ensuite, nous appliquerons des styles au :before et :after pseudo-éléments qu’ils partagent en commun :

h1:before,
h1:after {
  content: "";
  position: absolute;
  height: .7lh;
  width: var(--s);
  background: color-mix(in srgb, var(--c), #000 40%);
  rotate: var(--a);
}

Ensuite, nous positionnons chaque pseudo-élément et réalisons nos clips :

h1:before {
  top: .15lh;
  right: 0;
  transform-origin: top right;
  clip-path: polygon(0 0, 100% 0, calc(100% - .7lh / tan(var(--a))) 100%, 0 100%, var(--r) 50%);
}

h1:after {
  bottom: .15lh;
  left: 0;
  transform-origin: bottom left;
  clip-path: polygon(calc(.7lh / tan(var(--a))) 0, 100% 0, calc(100% - var(--r)) 50%, 100% 100%, 0 100%);
}

Nous avons presque fini! Nous avons encore un débordement indésirable où le dégradé répétitif saigne du haut et du bas de la forme. De plus, nous avons besoin de petites découpes pour correspondre à la forme du pseudo-élément.

Le deuxième ruban avant et après le tracé du clip
(Grand aperçu)

C’est clip-path encore une fois à la rescousse, cette fois sur l’élément principal :

clip-path: polygon(
    0 .15lh,
    calc(100% - .7lh/sin(var(--a))) .15lh,
    calc(100% - .7lh/sin(var(--a)) - 999px) calc(.15lh - 999px*tan(var(--a))),
    100% -999px,
    100% .15lh,
    calc(100% - .7lh*tan(var(--a)/2)) .85lh,
    100% 1lh,
    100% calc(100% - .15lh),
    calc(.7lh/sin(var(--a))) calc(100% - .15lh),
    calc(.7lh/sin(var(--a)) + 999px) calc(100% - .15lh + 999px*tan(var(--a))),
    0 999px,
    0 calc(100% - .15lh),
    calc(.7lh*tan(var(--a)/2)) calc(100% - .85lh),
    0 calc(100% - 1lh)
);

Ugh, ça a l’air effrayant ! Je profite d’un nouvel ensemble de fonctions trigonométriques cela aide beaucoup dans les calculs mais semble probablement étranger et déroutant si vous les voyez pour la première fois. Il y a une explication mathématique derrière chaque valeur dans l’extrait que j’aimerais expliquer, mais elle est longue. Cela dit, je serai plus qu’heureux de les expliquer plus en détail si vous m’écrivez un mot dans les commentaires.

Notre deuxième ruban est terminé ! Voici à nouveau la démo complète avec les deux variantes.

Voir le stylo [CodePen Home
Responsive multi-line ribbon shapes](https://codepen.io/smashingmag/pen/LYMjNoo) par Accompagner Afif.

Voir le stylo CodePen Accueil Formes de ruban multilignes réactives par Accompagner Afif.

Emballer

Nous avons examiné deux variantes de ruban qui utilisent presque la même structure de code, mais nous pouvons en créer de très nombreuses autres de la même manière. Votre devoir, si vous l’acceptez, sera de faire les variations suivantes en utilisant ce que vous avez appris jusqu’à présent.

Versions finales de deux variantes de ruban
(Grand aperçu)

Vous pouvez toujours trouver le code à l’intérieur ma collection de rubans, mais c’est un bon exercice pour essayer d’écrire du code sans. Peut-être trouverez-vous une implémentation différente de la mienne et souhaiterez-vous la partager avec moi dans les commentaires ! Dans le prochain article de cette série en deux parties, nous augmenterons la complexité et produirons deux formes de ruban plus intéressantes.

Lectures complémentaires sur SmashingMag

Éditorial fracassant
(gg, ouais)




Source link

novembre 19, 2023