Fancy bildedekorasjoner: Single Element Magic PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Fancy bildedekorasjoner: Single Element Magic

Som tittelen sier, vi skal dekorere bilder! Det er en haug med andre artikler der ute som snakker om dette, men det vi dekker her er ganske annerledes fordi det er mer en utfordring. Utfordringen? Dekorer et bilde med kun tag og ingenting mer.

Det riktige, ingen ekstra markering, ingen divs og ingen pseudo-elementer. Bare det ene merket.

Høres vanskelig ut, ikke sant? Men mot slutten av denne artikkelen – og de andre som utgjør denne lille serien – skal jeg bevise at CSS er kraftig nok til å gi oss flotte og fantastiske resultater til tross for begrensningene ved å jobbe med ett enkelt element.

Fancy bildedekorasjonsserie

  • Enkeltelementmagi — du er her
  • Masker og avanserte sveveeffekter (kommer 21 oktober )
  • konturer og komplekse animasjoner (kommer 28 oktober )

La oss starte med vårt første eksempel

Før vi graver inn i koden, la oss liste opp mulighetene for å style en uten noen ekstra elementer eller pseudo-elementer. Vi kan bruke border, box-shadow, outline, og selvfølgelig, background. Det kan se rart ut å legge til en bakgrunn til et bilde fordi vi ikke kan se det som det vil være bak bildet - men trikset er å skape plass rundt bildet ved hjelp av padding og / eller border og deretter tegne bakgrunnen vår inne i det rommet.

Jeg tror du vet hva som kommer siden jeg snakket om background, Ikke sant? Ja, gradienter! Alle dekorasjonene vi skal lage er avhengige av mange gradienter. Hvis du har fulgte meg en stund tror jeg at dette sannsynligvis ikke kommer som noen overraskelse for deg i det hele tatt. 😁

La oss gå tilbake til vårt første eksempel:

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);
}

Vi definerer padding og en gjennomsiktig border ved å bruke variabelen --s å skape et rom rundt bildet vårt som tilsvarer tre ganger så stor variabel.

Hvorfor bruker vi begge padding og border i stedet for det ene eller det andre? Vi kan få ved å bruke bare en av dem, men jeg trenger denne kombinasjonen for min gradient fordi, som standard, startverdien til background-clip is border-box og background-origin er lik padding-box.

Her er en trinn-for-trinn-illustrasjon for å forstå logikken:

I utgangspunktet har vi ingen kantlinjer på bildet, så gradienten vår vil lage to segmenter med 1px av tykkelse. (Jeg bruker 3px i denne spesifikke demoen slik at det er lettere å se.) Vi legger til en farget kant og gradienten gir oss fortsatt det samme resultatet inne i polstringsområdet (pga. background-origin), men det gjentar seg bak grensen. Hvis vi gjør fargen på kanten gjennomsiktig, kan vi bruke repetisjonen og vi får den rammen vi ønsker.

De outline i demoen har en negativ offset. Det skaper en firkantet form på toppen av gradienten. Det er det! Vi la til en fin dekorasjon til bildet vårt ved å bruke en gradient og en outline. Vi kunne ha brukt flere gradienter! Men jeg prøver alltid å holde koden min så enkel som mulig, og jeg fant ut at å legge til en outline er bedre på den måten.

Her er en løsning med kun gradient der jeg bare bruker padding å definere rommet. Fortsatt samme resultat, men med en mer kompleks syntaks.

La oss prøve en annen idé:

For denne tok jeg det forrige eksemplet fjernet outline, og brukte en clip-path for å kutte gradienten på hver side. De clip-path verdien er litt detaljert og forvirrende, men her er en illustrasjon for å bedre se poengene:

Fancy bildedekorasjoner: Single Element Magic

Jeg tror du forstår hovedideen. Vi skal kombinere bakgrunner, konturer, klipping og litt maskering for å oppnå forskjellige typer dekorasjoner. Vi kommer også til å vurdere noen kule sveveanimasjoner som en ekstra bonus! Det vi har sett på så langt er bare en liten oversikt over hva som kommer!

Den eneste hjørnerammen

Denne tar fire gradienter. Hver gradient dekker ett hjørne, og når vi holder musepekeren utvider vi dem for å lage en full ramme rundt bildet. La oss dissekere koden for en av gradientene:

--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;

Vi skal tegne en gradient med en størrelse lik 50px 50px og plasser den øverst til venstre (0 0). For gradientens konfigurasjon, her er en trinn-for-trinn-illustrasjon som viser hvordan jeg nådde det resultatet.

Vi har en tendens til å tro at gradienter bare er bra for overgang mellom to farger. Men i virkeligheten kan vi gjøre så mye mer med dem! De er spesielt nyttige når det gjelder å lage forskjellige former. Trikset er å sørge for at vi har harde stopp mellom farger - som i eksempelet ovenfor - i stedet for jevne overganger:

#0000 25%, darkblue 0

Dette er i utgangspunktet å si: "fyll gradienten med en gjennomsiktig farge til 25% av området, og fyll deretter det gjenværende området med darkblue.

Du klør deg kanskje i hodet over 0 verdi. Det er et lite hack for å forenkle syntaksen. I virkeligheten bør vi bruke dette til å gjøre en hard stopp mellom fargene:

#0000 25%, darkblue 25%

Det er mer logisk! Den gjennomsiktige fargen slutter kl 25% og darkblue starter nøyaktig der gjennomsiktigheten slutter, og gjør en hard stopp. Hvis vi erstatter den andre med 0, vil nettleseren gjøre jobben for oss, så det er en litt mer effektiv måte å gjøre det på.

Et sted i spesifikasjonen, det står:

hvis en fargestopp or overgang hint har en posisjon som er mindre enn den angitte posisjonen til et fargestopp eller overgangshint før den i listen, sett posisjonen til å være lik den største spesifiserte posisjonen til et fargestopp eller overgangshint før den.

0 er alltid mindre enn noen annen verdi, så nettleseren vil alltid konvertere den til den største verdien som kommer før den i erklæringen. I vårt tilfelle er det tallet 25%.

Nå bruker vi den samme logikken på alle hjørnene, og vi avslutter med følgende kode:

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;
}

Jeg har introdusert CSS-variabler for å unngå noe redundans ettersom alle gradientene bruker samme fargekonfigurasjon.

For sveveeffekten er alt jeg gjør å øke størrelsen på gradientene for å lage hele bildet:

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

Ja det er 51% istedenfor 50% — som skaper en liten overlapping og unngår mulige hull.

La oss prøve en annen idé med samme teknikk:

Denne gangen bruker vi bare to gradienter, men med en mer kompleks animasjon. Først oppdaterer vi posisjonen til hver gradient, og øker deretter størrelsene for å lage hele bildet. Jeg introduserte også flere variabler for bedre kontroll over fargen, størrelsen, tykkelsen og til og med gapet mellom bildet og rammen.

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;
}

Hvorfor gjør --_i og --_p variabler har et understrek i navnet sitt? Understrekingene er en del av en navnekonvensjon jeg bruker for å vurdere "interne" variabler som brukes for å optimalisere koden. De er ikke noe spesielt, men jeg vil gjøre en forskjell mellom variablene vi justerer for å kontrollere rammen (som --b, --c, etc.) og de jeg bruker for å gjøre koden kortere.

Koden kan se forvirrende ut og ikke lett å forstå, men jeg skrev en tredelt serie hvor jeg detaljerer slik teknikk. Jeg anbefaler på det sterkeste å lese minst den første artikkelen for å forstå hvordan jeg nådde koden ovenfor.

Her er en illustrasjon for å bedre forstå de forskjellige verdiene:

Viser det samme bildet av to klassiske biler tre ganger for å illustrere CSS-variablene som brukes i koden.
Fancy bildedekorasjoner: Single Element Magic

The Frame Reveal

La oss prøve en annen type animasjon der vi avslører hele bildet når vi peker:

Kult, ikke sant? Og hvis du ser nøye etter, vil du legge merke til at linjene forsvinner i motsatt retning på musen ut som gjør effekten enda mer fancy! Jeg brukte en lignende effekt i en tidligere artikkel.

Men denne gangen, i stedet for å dekke hele elementet, dekker jeg bare en liten del ved å definere en height for å få noe sånt som dette:

Dette er den øvre kanten av rammen vår. Vi gjentar den samme prosessen på hver side av bildet, og vi har vår sveveeffekt:

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%;
}

Som du kan se, bruker jeg den samme gradienten fire ganger, og hver av dem har en annen posisjon for å dekke bare én side om gangen.

En annen? La oss gå!

Denne ser litt vanskelig ut, og den krever faktisk litt fantasi for å forstå hvordan to koniske gradienter utløser denne typen magi. Her er en demo for å illustrere en av gradientene:

Pseudo-elementet simulerer gradienten. Den er i utgangspunktet ute av syne, og ved sveving endrer vi først posisjonen for å få den øvre kanten av rammen. Så øker vi høyden for å få rett kant. Gradientformen ligner på de vi brukte i den siste delen: to segmenter for å dekke to sider.

Men hvorfor laget jeg gradientens bredde 200%? Du skulle tro 100% ville være nok, ikke sant?

100% burde være nok, men jeg vil ikke kunne flytte gradienten som jeg vil hvis jeg holder bredden lik 100%. Det er en annen liten finurlighet knyttet til hvordan background-position virker. Jeg dekker dette inn en tidligere artikkel. Jeg også la ut et svar på Stack Overflow håndtere dette. Jeg vet det er mye lesing, men det er virkelig verdt tiden din.

Nå som vi har forklart logikken for en gradient, er den andre enkel fordi den gjør akkurat det samme, men dekker venstre og nedre kant i stedet. Alt vi trenger å gjøre er å bytte noen verdier og vi er ferdige:

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;
}

Som du kan se, er begge gradientene nesten identiske. Jeg bytter rett og slett ut verdiene for størrelse og plassering.

Rammerotasjonen

Denne gangen skal vi ikke tegne en ramme rundt bildet vårt, men heller justere utseendet til et eksisterende.

Du spør sikkert hvordan jeg er i stand til å forvandle en rett linje til en vinklet linje. Nei, magien er annerledes enn det. Det er bare illusjonen vi får etter å ha kombinert enkle animasjoner for fire gradienter.

La oss se hvordan animasjonen for toppgradienten er laget:

Jeg oppdaterer ganske enkelt posisjonen til en repeterende gradient. Ikke noe fancy ennå! La oss gjøre det samme for høyre side:

Begynner du å se trikset? Begge gradientene skjærer hverandre i hjørnet for å skape en illusjon der den rette linjen endres til en vinklet. La oss fjerne omrisset og skjule overløpet for å se det bedre:

Nå legger vi til to gradienter for å dekke de gjenværende kantene, og vi er ferdige:

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%;
}

Hvis vi tar denne koden og justerer den litt, kan vi få en annen kul animasjon:

Kan du finne ut logikken i dette eksemplet? Det er leksene dine! Koden kan se skummel ut, men den bruker samme logikk som de forrige eksemplene vi så på. Prøv å isolere hver gradient og forestill deg hvordan den animerer.

Innpakning opp

Det er mange gradienter i én artikkel!

Det er det sikkert, og jeg advarte deg! Men hvis utfordringen er å dekorere et bilde uten ekstra elementer og pseudo-elementer, sitter vi igjen med bare noen få muligheter og gradienter er det kraftigste alternativet.

Ikke bekymre deg hvis du er litt borte i noen av forklaringene. Jeg anbefaler alltid noen av mine gamle artikler hvor jeg går mer i detalj med noen av konseptene vi resirkulerte for denne utfordringen.

Jeg skal dra med en siste demo for å holde deg over til neste artikkel i denne serien. Denne gangen bruker jeg radial-gradient() for å lage en annen morsom sveveeffekt. Jeg lar deg dissekere koden for å finne ut hvordan den fungerer. Still meg spørsmål i kommentarfeltet hvis du står fast!

Fancy bildedekorasjonsserie

  • Enkeltelementmagi — du er her
  • Masker og avanserte sveveeffekter (kommer 21 oktober )
  • konturer og komplekse animasjoner (kommer 28 oktober )

Tidstempel:

Mer fra CSS triks