Décorations d'images fantaisie : Intelligence des données Magic PlatoBlockchain à élément unique. Recherche verticale. Aï.

Décorations d'image fantaisie : magie à un seul élément

Comme le titre l'indique, nous allons décorer des images ! Il y a un tas d'autres articles qui en parlent, mais ce que nous couvrons ici est un peu différent parce que c'est plus un défi. Le défi? Décorez une image en utilisant uniquement le balise et rien de plus.

Ce droit, pas de balisage supplémentaire, pas de divs et pas de pseudo-éléments. Juste une balise.

Cela semble difficile, non ? Mais à la fin de cet article - et des autres qui composent cette petite série - je prouverai que CSS est suffisamment puissant pour nous donner des résultats excellents et époustouflants malgré la limitation de travailler avec un seul élément.

Fantaisie Image Décorations série

  • Magie d'élément unique — Tu es là
  • Masques et effets de survol avancés (à venir le 21 octobre )
  • Contours et animations complexes (à venir le 28 octobre )

Commençons par notre premier exemple

Avant de creuser dans le code, énumérons les possibilités de style d'un sans éléments supplémentaires ou pseudo-éléments. On peut utiliser border, box-shadow, outline, Et, bien sûr, background. Il peut sembler étrange d'ajouter un arrière-plan à une image car nous ne pouvons pas le voir car il sera derrière l'image — mais l'astuce consiste à créer de l'espace autour l'image en utilisant padding (facultatif) border puis dessinez notre arrière-plan à l'intérieur de cet espace.

Je pense que vous savez ce qui vient après puisque j'ai parlé de background, droite? Oui, les gradients! Toutes les décorations que nous allons réaliser reposent sur de nombreux dégradés. Si vous avez m'a suivi pendant un certain temps, je pense que cela ne vous surprendra probablement pas du tout. 😁

Revenons à notre premier exemple :

img {
  --s: 10px; /* control the size */
  padding: var(--s);
  border: calc(2 * var(--s)) solid #0000;
  outline: 1px solid #000;
  outline-offset: calc(-1 * var(--s));
  background: conic-gradient(from 90deg at 1px 1px, #0000 25%, #000 0);
}

Nous définissons padding et un transparent border en utilisant la variable --s pour créer un espace autour de notre image égal à trois fois cette variable.

Pourquoi utilisons-nous les deux padding ainsi que le border à la place de l'un ou de l'autre ? On peut s'en sortir en n'en utilisant qu'un seul mais j'ai besoin de cette combinaison pour mon dégradé car, par défaut, la valeur initiale de background-clip is border-box ainsi que le background-origin est égal à padding-box.

Voici une illustration étape par étape pour comprendre la logique :

Au départ, nous n'avons pas de bordures sur l'image, donc notre dégradé créera deux segments avec 1px d'épaisseur. (J'utilise 3px dans cette démo spécifique donc c'est plus facile à voir.) Nous ajoutons une bordure colorée et le dégradé nous donne toujours le même résultat à l'intérieur de la zone de remplissage (en raison de background-origin) mais il se répète derrière la bordure. Si nous rendons la couleur de la bordure transparente, nous pouvons utiliser la répétition et nous obtenons le cadre que nous voulons.

Les outline dans la démo a un décalage négatif. Cela crée une forme carrée en haut du dégradé. C'est ça! Nous avons ajouté une belle décoration à notre image en utilisant un dégradé et un outline. Nous aurions pu utiliser plus de dégradés ! Mais j'essaie toujours de garder mon code aussi simple que possible et j'ai trouvé que l'ajout d'un outline est mieux ainsi.

Voici une solution à gradient uniquement où j'utilise uniquement padding pour délimiter l'espace. Toujours le même résultat mais avec une syntaxe plus complexe.

Essayons une autre idée :

Pour celui-ci, j'ai pris l'exemple précédent en supprimant le outline, et appliqué un clip-path pour couper le dégradé de chaque côté. Le clip-path value est un peu verbeux et déroutant mais voici une illustration pour mieux voir ses points :

Décorations d'image fantaisie : magie à un seul élément

Je pense que vous avez saisi l'idée principale. Nous allons combiner des arrière-plans, des contours, des détourages et quelques masquages ​​pour réaliser différents types de décorations. Nous allons également considérer quelques animations de survol sympas comme un bonus supplémentaire ! Ce que nous avons vu jusqu'à présent n'est qu'un petit aperçu de ce qui s'en vient !

Le cadre en coin uniquement

Celui-ci prend quatre dégradés. Chaque dégradé couvre un coin et, au survol, nous les agrandissons pour créer un cadre complet autour de l'image. Disséquons le code pour l'un des dégradés :

--b: 5px; /* border thickness */
background: conic-gradient(from 90deg at top var(--b) left var(--b), #0000 90deg, darkblue 0) 0 0;
background-size: 50px 50px; 
background-repeat: no-repeat;

Nous allons dessiner un dégradé de taille égale à 50px 50px et placez-le dans le coin supérieur gauche (0 0). Pour la configuration du dégradé, voici une illustration étape par étape montrant comment j'ai atteint ce résultat.

Nous avons tendance à penser que les dégradés ne sont bons que pour faire la transition entre deux couleurs. Mais en réalité, nous pouvons faire tellement plus avec eux ! Ils sont particulièrement utiles lorsqu'il s'agit de créer différentes formes. L'astuce consiste à s'assurer que nous avons des arrêts durs entre les couleurs — comme dans l'exemple ci-dessus — plutôt que des transitions douces :

#0000 25%, darkblue 0

Cela revient à dire : "remplissez le dégradé avec une couleur transparente jusqu'à ce que 25% de la zone, puis remplissez la zone restante avec darkblue.

Vous pourriez vous gratter la tête sur le 0 valeur. C'est un petit hack pour simplifier la syntaxe. En réalité, nous devrions l'utiliser pour faire un arrêt brutal entre les couleurs :

#0000 25%, darkblue 25%

C'est plus logique ! La couleur transparente se termine à 25% ainsi que le darkblue commence exactement là où la transparence se termine, faisant un arrêt brutal. Si nous remplaçons le second par 0, le navigateur fera le travail pour nous, c'est donc un moyen légèrement plus efficace de s'y prendre.

Quelque part dans la spécification, ça dit:

si un arrêt de couleur or indice de transition a une position inférieure à la position spécifiée de tout arrêt de couleur ou indice de transition avant lui dans la liste, définissez sa position pour qu'elle soit égale à la plus grande position spécifiée de tout arrêt de couleur ou indice de transition avant lui.

0 est toujours plus petite que toute autre valeur, donc le navigateur la convertira toujours en la plus grande valeur qui la précède dans la déclaration. Dans notre cas, ce nombre est 25%.

Maintenant, on applique la même logique à tous les coins et on termine avec le code suivant :

img {
  --b: 5px; /* border thickness */
  --c: #0000 90deg, darkblue 0; /* define the color here */
  padding: 10px;
  background:
    conic-gradient(from 90deg  at top    var(--b) left  var(--b), var(--c)) 0 0,
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--c)) 100% 0,
    conic-gradient(from 0deg   at bottom var(--b) left  var(--b), var(--c)) 0 100%,
    conic-gradient(from -90deg at bottom var(--b) right var(--b), var(--c)) 100% 100%;
  background-size: 50px 50px; /* adjust border length here */
  background-repeat: no-repeat;
}

J'ai introduit des variables CSS pour éviter une certaine redondance car tous les dégradés utilisent la même configuration de couleur.

Pour l'effet de survol, je ne fais qu'augmenter la taille des dégradés pour créer le plein cadre :

img:hover {
  background-size: 51% 51%;
}

Oui ce est 51% au lieu de 50% — qui crée un petit chevauchement et évite d'éventuels écarts.

Essayons une autre idée en utilisant la même technique :

Cette fois, nous n'utilisons que deux dégradés, mais avec une animation plus complexe. Tout d'abord, nous mettons à jour la position de chaque dégradé, puis augmentons leurs tailles pour créer le cadre complet. J'ai également introduit plus de variables pour un meilleur contrôle de la couleur, de la taille, de l'épaisseur et même de l'écart entre l'image et le cadre.

img {
  --b: 8px;  /* border thickness*/
  --s: 60px; /* size of the corner*/
  --g: 14px; /* the gap*/
  --c: #EDC951; 

  padding: calc(var(--b) + var(--g));
  background-image:
    conic-gradient(from  90deg at top    var(--b) left  var(--b), #0000 25%, var(--c) 0),
    conic-gradient(from -90deg at bottom var(--b) right var(--b), #0000 25%, var(--c) 0);
  background-position:
    var(--_p, 0%) var(--_p, 0%),
    calc(100% - var(--_p, 0%)) calc(100% - var(--_p, 0%));
  background-size: var(--s) var(--s);
  background-repeat: no-repeat;
  transition: 
    background-position .3s var(--_i,.3s), 
    background-size .3s calc(.3s - var(--_i, .3s));
}
img:hover {
  background-size: calc(100% - var(--g)) calc(100% - var(--g));
  --_p: calc(var(--g) / 2);
  --_i: 0s;
}

Pourquoi faire la --_i ainsi que le --_p variables ont un trait de soulignement dans leur nom ? Les traits de soulignement font partie d'une convention de dénomination que j'utilise pour considérer les variables "internes" utilisées pour optimiser le code. Ils n'ont rien de spécial mais je veux faire une différence entre les variables que nous ajustons pour contrôler le cadre (comme --b, --c, etc.) et ceux que j'utilise pour raccourcir le code.

Le code peut sembler déroutant et pas facile à saisir mais j'ai écrit un série en trois parties où je détaille telle technique. Je recommande fortement de lire au moins le premier article pour comprendre comment j'ai atteint le code ci-dessus.

Voici une illustration pour mieux comprendre les différentes valeurs :

Affichage trois fois de la même image de deux voitures classiques pour illustrer les variables CSS utilisées dans le code.
Décorations d'image fantaisie : magie à un seul élément

La révélation du cadre

Essayons un autre type d'animation où nous révélons l'image complète au survol :

Cool, non ? Et vous, si vous regardez bien, vous remarquerez que les lignes disparaissent dans le sens opposé au passage de la souris ce qui rend l'effet encore plus fantaisiste ! J'ai utilisé un effet similaire dans un article précédent.

Mais cette fois, au lieu de couvrir tout l'élément, je ne couvre qu'une petite partie en définissant un height pour obtenir quelque chose comme ça :

C'est la bordure supérieure de notre cadre. Nous répétons le même processus de chaque côté de l'image et nous avons notre effet de survol :

img {
  --b: 10px; /* the border thickness*/
  --g: 5px; /* the gap on hover */
  --c: #8A9B0F; 

  padding: calc(var(--g) + var(--b));
  --_g: no-repeat linear-gradient(var(--c) 0 0);
  background: 
    var(--_g) var(--_i, 0%) 0,
    var(--_g) 100% var(--_i, 0%),
    var(--_g) calc(100% - var(--_i, 0%)) 100%,
    var(--_g) 0 calc(100% - var(--_i, 0%));
  background-size: var(--_i, 0%) var(--b),var(--b) var(--_i, 0%);
  transition: .4s, background-position 0s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
}

Comme vous pouvez le voir, j'applique le même dégradé quatre fois et chacun a une position différente pour couvrir un seul côté à la fois.

Un autre? Allons-y!

Celui-ci semble un peu délicat et il faut en effet un peu d'imagination pour comprendre comment deux gradients coniques réussissent ce genre de magie. Voici une démo pour illustrer un des dégradés :

Le pseudo-élément simule le gradient. Il est initialement hors de vue et, en vol stationnaire, nous changeons d'abord sa position pour obtenir le bord supérieur du cadre. Ensuite, nous augmentons la hauteur pour obtenir le bon bord. La forme du dégradé est similaire à celles que nous avons utilisées dans la dernière section : deux segments pour couvrir deux côtés.

Mais pourquoi ai-je fait la largeur du dégradé 200%? Vous penseriez 100% ça suffirait non ?

100% devrait suffire mais je ne pourrai pas déplacer le dégradé comme je le souhaite si je garde sa largeur égale à 100%. C'est une autre petite bizarrerie liée à la façon dont background-position travaux. Je couvre cela dans un article précédent. moi aussi posté une réponse sur Stack Overflow faire face à cela. Je sais que c'est beaucoup de lecture, mais ça vaut vraiment le coup.

Maintenant que nous avons expliqué la logique d'un dégradé, le second est facile car il fait exactement la même chose, mais en couvrant les bords gauche et inférieur à la place. Tout ce que nous avons à faire est d'échanger quelques valeurs et nous avons terminé :

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b))  no-repeat,
    conic-gradient(            at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200%  no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}

Comme vous pouvez le voir, les deux dégradés sont presque identiques. J'échange simplement les valeurs de la taille et de la position.

La rotation du cadre

Cette fois, nous n'allons pas dessiner un cadre autour de notre image, mais plutôt ajuster l'apparence d'une image existante.

Vous vous demandez probablement comment diable je suis capable de transformer une ligne droite en une ligne inclinée. Non, la magie est différente de cela. C'est juste l'illusion que nous obtenons après avoir combiné des animations simples pour quatre dégradés.

Voyons comment l'animation du dégradé du haut est réalisée :

Je mets simplement à jour la position d'un dégradé répétitif. Rien d'extraordinaire pour le moment ! Faisons de même pour le côté droit :

Vous commencez à voir le truc ? Les deux dégradés se croisent au coin pour créer l'illusion où la ligne droite est remplacée par une ligne inclinée. Supprimons le contour et masquons le débordement pour mieux le voir :

Maintenant, nous ajoutons deux autres dégradés pour couvrir les bords restants et nous avons terminé :

img {
  --g: 4px; /* the gap */
  --b: 12px; /* border thickness*/
  --c: #669706; /* the color */

  padding: calc(var(--g) + var(--b));
  --_c: #0000 0 25%, var(--c) 0 50%;
  --_g1: repeating-linear-gradient(90deg ,var(--_c)) repeat-x;
  --_g2: repeating-linear-gradient(180deg,var(--_c)) repeat-y;
  background:
    var(--_g1) var(--_p, 25%) 0, 
    var(--_g2) 0 var(--_p, 125%),
    var(--_g1) var(--_p, 125%) 100%, 
    var(--_g2) 100% var(--_p, 25%);
  background-size: 200% var(--b), var(--b) 200%;
  transition: .3s;
}
img:hover {
  --_p: 75%;
}

Si nous prenons ce code et l'ajustons légèrement, nous pouvons obtenir une autre animation sympa :

Pouvez-vous comprendre la logique dans cet exemple ? C'est vos devoirs ! Le code peut sembler effrayant, mais il utilise la même logique que les exemples précédents que nous avons examinés. Essayez d'isoler chaque dégradé et imaginez comment il s'anime.

Emballage en place

Cela fait beaucoup de dégradés dans un seul article !

C'est sûr et je vous ai prévenu! Mais si le défi est de décorer une image sans éléments supplémentaires et pseudo-éléments, il ne nous reste que quelques possibilités et les dégradés sont l'option la plus puissante.

Ne vous inquiétez pas si vous êtes un peu perdu dans certaines explications. Je recommande toujours certains de mes anciens articles où j'entre plus en détail avec certains des concepts que nous avons recyclés pour ce défi.

Je repars avec une dernière démo pour vous tenir jusqu'au prochain article de cette série. Cette fois, j'utilise radial-gradient() pour créer un autre effet de survol amusant. Je vous laisse disséquer le code pour voir comment cela fonctionne. Posez-moi des questions dans les commentaires si vous bloquez !

Fantaisie Image Décorations série

  • Magie d'élément unique — Tu es là
  • Masques et effets de survol avancés (à venir le 21 octobre )
  • Contours et animations complexes (à venir le 28 octobre )

Horodatage:

Plus de Astuces CSS