Fancy billeddekorationer: Masker og avancerede svæveeffekter PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Fancy billeddekorationer: Masker og avancerede svæveeffekter

Velkommen til del 2 af denne tredelte serie! Vi dekorerer stadig billeder uden ekstra elementer og pseudo-elementer. Jeg håber, du allerede har taget dig tid til at fordøje del 1 fordi vi vil fortsætte med at arbejde med en masse gradienter for at skabe fantastiske visuelle effekter. Vi vil også introducere CSS mask ejendom til mere komplekse dekorationer og svæveeffekter.

Fancy billeddekorationsserie

  • Single Element Magic
  • Masker og avancerede svæveeffekter (du er her!)
  • Konturer og komplekse animationer (kommer den 28. oktober )

Lad os vende os til det første eksempel, vi arbejder på sammen...

Frimærket

Tro eller ej, alt hvad der skal til for at lave frimærke-CSS-effekt er to gradienter og et filter:

img {
  --r: 10px; /* control the radius of the circles */
  padding: calc(2 * var(--r));
  filter: grayscale(.4);
  background: 
    radial-gradient(var(--r),#0000 98%,#fff) round
      calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)),
    linear-gradient(#fff 0 0) no-repeat
      50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
}

Som vi så i den forrige artikel, er det første skridt at skabe plads omkring billedet med padding så vi kan tegne en baggrundsgradient og se den der. Så bruger vi en kombination af radial-gradient() , linear-gradient() at skære disse cirkler rundt om billedet.

Her er en trin-for-trin illustration, der viser, hvordan gradienterne er konfigureret:

Bemærk brugen af round værdi i andet trin. Det er meget vigtigt for tricket, da det sikrer, at størrelsen af ​​gradienten er justeret til at være perfekt justeret på alle sider, uanset billedets bredde eller højde.

Fra specifikationen: Billedet gentages så ofte, som det passer inden for baggrundspositionsområdet. Hvis det ikke passer et helt antal gange, skaleres det om, så det gør.

Den afrundede ramme

Lad os se på en anden billeddekoration, der bruger cirkler...

Dette eksempel bruger også en radial-gradient(), men denne gang har jeg oprettet cirkler omkring billedet i stedet for udskæringseffekten. Bemærk, at jeg også bruger round værdi igen. Den sværeste del her er det gennemsigtige mellemrum mellem rammen og billedet, hvor jeg rækker ud efter CSS'en mask ejendom:

img {
  --s: 20px; /* size of the frame */
  --g: 10px; /* the gap */
  --c: #FA6900; 

  padding: calc(var(--g) + var(--s));
  background: 
    radial-gradient(farthest-side, var(--c) 97%, #0000) 
      0 0 / calc(2 * var(--s)) calc(2 * var(--s)) round;
  mask:
    conic-gradient(from 90deg at calc(2 * var(--s)) calc(2 * var(--s)), #0000 25%, #000 0)
      calc(-1 * var(--s)) calc(-1 * var(--s)),
    linear-gradient(#000 0 0) content-box;
}

Maskering giver os mulighed for at vise området af billedet - takket være linear-gradient() derinde - samt 20px omkring hver side af det - takket være conic-gradient(). Det 20px er intet andet end variablen --s der definerer rammens størrelse. Vi skal med andre ord skjule kløften.

Her er hvad jeg mener:

Den lineære gradient er den blå del af baggrunden, mens den kegleformede gradient er den røde del af baggrunden. Den gennemsigtige del mellem begge gradienter er det, vi skærer fra vores element for at skabe illusionen af ​​en indre gennemsigtig grænse.

Den indre gennemsigtige grænse

Til denne vil vi ikke skabe en ramme, men snarere prøve noget andet. Vi vil skabe en gennemsigtig indre grænse indvendig vores billede. Sandsynligvis ikke så nyttigt i et scenarie i den virkelige verden, men det er god praksis med CSS-masker.

I lighed med det foregående eksempel vil vi stole på to gradienter: a linear-gradient() for den indre del, og en conic-gradient() for den ydre del. Vi efterlader et mellemrum mellem dem for at skabe den gennemsigtige kanteffekt.

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */

  --_g: calc(100% - 2 * (var(--d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--d) var(--d), #0000 25%, #000 0)
      0 0 / calc(100% - var(--d)) calc(100% - var(--d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
}
Fancy billeddekorationer: Masker og avancerede svæveeffekter

Du har måske bemærket, at den kegleformede gradient i dette eksempel har en anden syntaks fra det forrige eksempel. Begge formodes at skabe den samme form, så hvorfor er de forskellige? Det er fordi vi kan nå det samme resultat ved hjælp af forskellige syntakser. Dette kan se forvirrende ud i starten, men det er en god funktion. Du er ikke forpligtet til at finde og løsning for at opnå en bestemt form. Du skal kun finde én løsning, der fungerer for dig, ud af de mange muligheder derude.

Her er fire måder at skabe det ydre kvadrat ved hjælp af gradienter:

Der er endnu flere måder at gøre dette på, men du forstår pointen.

Der er ingen Best™-tilgang. Personligt forsøger jeg at finde den med den mindste og mest optimerede kode. For mig er enhver løsning, der kræver færre gradienter, færre beregninger og færre gentagne værdier, den bedst egnede. Nogle gange vælger jeg en mere udførlig syntaks, fordi den giver mig mere fleksibilitet til at ændre variabler og ændre ting. Det kommer med erfaring og øvelse. Jo mere du leger med gradienter, jo mere ved du hvilken syntaks du skal bruge og hvornår.

Lad os vende tilbage til vores indre gennemsigtige grænse og grave i svæveeffekten. Hvis du ikke lagde mærke til det, er der en cool svæveeffekt, der flytter den gennemsigtige kant ved hjælp af en font-size trick. Ideen er at definere --d variabel med en værdi på 1em. Denne variabel kontrollerer grænsens afstand fra kanten. Vi kan transformere sådan:

--_d: calc(var(--d) + var(--s) * 1em)

...giver os følgende opdaterede CSS:

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */
  --o: 15px; /* the offset on hover */
  --s: 1;    /* the direction of the hover effect (+1 or -1)*/

  --_d: calc(var(--d) + var(--s) * 1em);
  --_g: calc(100% - 2 * (var(--_d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--_d) var(--_d), #0000 25%, #000 0)
     0 0 / calc(100% - var(--_d)) calc(100% - var(--_d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
  font-size: 0;
  transition: .35s;
}
img:hover {
  font-size: var(--o);
}

font-size er oprindeligt lig med 0 ,så 1em er også lig med 0 , --_d er være lig med --d. På svævehovedet, dog font-size er lig med en værdi defineret af en --o variabel, der sætter grænsens offset. Dette opdaterer til gengæld --_d variabel, flytter grænsen med forskydningen. Så tilføjer jeg en anden variabel, --s, for at kontrollere det skilt, der afgør, om grænsen flyttes til indersiden eller ydersiden.

font-size trick er virkelig nyttigt, hvis vi ønsker at animere egenskaber, der ellers er uanimerede. Brugerdefinerede egenskaber defineret med @property kan løse dette men støtte til det mangler stadig på det tidspunkt, jeg skriver dette.

The Frame Reveal

Vi lavede følgende afslørende animation i første del af denne serie:

Vi kan tage den samme idé, men i stedet for en kant med en ensfarvet farve vil vi bruge en gradient som denne:

Hvis du sammenligner begge koder, vil du bemærke følgende ændringer:

  1. Jeg brugte den samme gradientkonfiguration fra det første eksempel inde i mask ejendom. Jeg flyttede simpelthen gradienterne fra background ejendom til mask ejendom.
  2. Jeg tilføjede en repeating-linear-gradient() for at oprette gradientkanten.

Det er det! Jeg genbrugte det meste af den samme kode, som vi allerede så - med super små justeringer - og fik endnu en cool billeddekoration med en svæveeffekt.

/* Solid color border */

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

  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;
}
/* Gradient color border */

img {
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap on hover */
  background: repeating-linear-gradient(135deg, #F8CA00 0 10px, #E97F02 0 20px, #BD1550 0 30px);

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, #000 0;
  mask: 
    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,
    linear-gradient(#000 0 0) content-box;
  transition: .3s, mask-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, mask-size .3s .3s;
}

Lad os prøve en anden rammeanimation. Denne er lidt tricky, da den har en tre-trins animation:

Det første trin i animationen er at gøre den nederste kant større. Til dette justerer vi background-size af en linear-gradient():

Du undrer dig sikkert over, hvorfor jeg også tilføjer den øverste kant. Vi har brug for det til det tredje trin. Jeg forsøger altid at optimere den kode, jeg skriver, så jeg bruger én gradient til at dække både top- og bundsiden, men den øverste er skjult og afsløres senere med en mask.

For det andet trin tilføjer vi en anden gradient for at vise venstre og højre kant. Men denne gang gør vi det ved hjælp af background-position:

Vi kan stoppe her, da vi allerede har en god effekt med to gradienter, men vi er her for at skubbe grænserne, så lad os tilføje et strejf af maske for at nå det tredje trin.

Tricket er at gøre den øverste kant skjult, indtil vi viser bunden og siderne, og så opdaterer vi mask-size (eller mask-position) for at vise den øverste del. Som jeg sagde tidligere, kan vi finde en masse gradientkonfigurationer for at opnå den samme effekt.

Her er en illustration af de gradienter, jeg vil bruge:

Jeg bruger to koniske gradienter med en bredde svarende til 200%. Begge gradienter dækker området og efterlader kun den øverste del afdækket (den del vil være usynlig senere). Når jeg svæver, skubber jeg begge gradienter for at dække den del.

Her er en bedre illustration af en af ​​gradienterne for at give dig en bedre ide om, hvad der sker:

Nu sætter vi dette inde i mask ejendom og vi er færdige! Her er den fulde kode:

img {
  --b: 6px;  /* the border thickness*/
  --g: 10px; /* the gap */
  --c: #0E8D94;

  padding: calc(var(--b) + var(--g));
  --_l: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
  background:
    linear-gradient(var(--_l)) 50%/calc(100% - var(--_i,80%)) 100% no-repeat,
    linear-gradient(90deg, var(--_l)) 50% var(--_i,-100%)/100% 200% no-repeat;  
  mask:
    conic-gradient(at 50% var(--b),#0000 25%, #000 0) calc(50% + var(--_i, 50%)) / 200%,
    conic-gradient(at 50% var(--b),#000 75%, #0000 0) calc(50% - var(--_i, 50%)) / 200%;
  transition: 
    .3s calc(.6s - var(--_t,.6s)) mask-position, 
    .3s .3s background-position,
    .3s var(--_t,.6s) background-size,
    .4s transform;
  cursor: pointer;
}
img:hover {
  --_i: 0%;
  --_t: 0s;
  transform: scale(1.2);
}

Jeg har også introduceret nogle variabler for at optimere koden, men det burde du være vant til lige nu.

Hvad med en fire-trins animation? Ja, det er muligt!

Ingen forklaring på dette, fordi det er dit hjemmearbejde! Tag alt det, du har lært i denne artikel, for at dissekere koden og forsøge at formulere, hvad den gør. Logikken ligner alle de foregående eksempler. Nøglen er at isolere hver gradient for at forstå hvert trin i animationen. Jeg holdt koden uoptimeret for at gøre tingene lidt nemmere at læse. jeg har en optimeret version hvis du er interesseret, men du kan også selv prøve at optimere koden og sammenligne den med min version for yderligere øvelse.

Indpakning op

Det var det for del 2 af denne tredelte serie om kreative billeddekorationer, der kun bruger element. Vi har nu et godt greb om, hvordan gradienter og masker kan kombineres for at skabe fantastiske visuelle effekter og endda animationer - uden at række ud efter ekstra elementer eller pseudo-elementer. Ja, en enkelt tag er nok!

Vi har endnu en artikel tilbage i denne serie. Indtil da er her en bonusdemo med en cool svæveeffekt, hvor jeg bruger mask at samle et ødelagt billede.

Fancy billeddekorationsserie

  • Single Element Magic
  • Masker og avancerede svæveeffekter (du er her!)
  • Konturer og komplekse animationer (kommer den 28. oktober )

Tidsstempel:

Mere fra CSS-tricks