Animerede baggrundsstriber, der skifter på Hover PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Animerede baggrundsstriber, der skifter, når du svæver

Hvor ofte rækker du ud efter CSS background-size ejendom? Hvis du er ligesom mig - og sikkert mange andre frontend-folk - så er det normalt, når du background-size: cover et billede til at udfylde rummet af et helt element.

Nå, jeg blev præsenteret for en interessant udfordring, der krævede mere avanceret baggrundsstørrelse: baggrundsstriber, der skifter ved svævning. Tjek dette ud og svæv det med din markør:

Der sker meget mere der end størrelsen på baggrunden, men det var det trick, jeg havde brug for for at få striberne til at skifte. Jeg tænkte, at jeg ville vise dig, hvordan jeg ankom der, ikke kun fordi jeg synes, det er en rigtig flot visuel effekt, men fordi det krævede, at jeg blev kreativ med gradienter og blandingstilstande, som jeg tror, ​​du kunne nyde.

Lad os starte med en meget grundlæggende opsætning for at holde tingene enkle. Jeg taler om en single

i HTML, der er udformet som en grøn firkant:

div {
  width: 500px;
  height: 500px;
  background: palegreen;
}
Animerede baggrundsstriber, der skifter, når du svæver

Opsætning af baggrundsstriber

Hvis dit sind gik direkte til en CSS lineær gradient, da du så disse striber, så er vi allerede på samme side. Vi kan ikke ligefrem lave en gentagne gradient i dette tilfælde, da vi ønsker, at striberne skal optage ujævne mængder plads og overføre dem, men vi kan skabe fem striber ved at kæde fem baggrunde oven på vores eksisterende baggrundsfarve og placere dem til toppen - højre for containeren:

div {
  width: 500px;
  height: 500px;
  background: 
    linear-gradient(black, black) top right,
    linear-gradient(black, black) top 100px right,
    linear-gradient(black, black) top 200px right,
    linear-gradient(black, black) top 300px right,
    linear-gradient(black, black) top 400px right, 
    palegreen;
}

Jeg lavede vandrette striber, men vi kunne også gå lodret med den tilgang, vi dækker her. Og vi kan forenkle dette en del med brugerdefinerede egenskaber:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
}

--gt værdi er gradienten og --n er en konstant, vi bruger til at skubbe striberne nedad, så de er forskudt lodret. Og du har måske bemærket, at jeg ikke har sat en sand gradient, men snarere solide sorte striber i linear-gradient() funktion — det er med vilje, og vi kommer til, hvorfor jeg gjorde det om lidt.

En ting mere, vi bør gøre, før vi går videre, er at forhindre vores baggrund i at gentage sig; ellers vil de flisebelægge og fylde hele rummet:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
}

Vi kunne have sat background-repeat i background stenografi, men jeg besluttede at bryde det ud her for at gøre tingene nemme at læse.

Forskydning af striberne

Vi har teknisk set striber, men det er ret svært at sige, fordi der ikke er nogen afstand mellem dem, og de dækker hele beholderen. Det er mere som om vi har en solid sort firkant.

Det er her, vi kommer til at bruge background-size ejendom. Vi ønsker at indstille både højden og bredden af ​​striberne, og egenskaben understøtter en to-værdi syntaks, der tillader os at gøre præcis det. Og vi kan kæde disse størrelser ved at komme adskille dem på samme måde, som vi gjorde på background.

Lad os starte enkelt med at indstille bredderne først. Brug af enkeltværdisyntaks til background-size indstiller bredden og standardhøjden til auto. Jeg bruger helt vilkårlige værdier her, så indstil værdierne til det, der fungerer bedst til dit design:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
  background-size: 60%, 90%, 70%, 40%, 10%;
}

Hvis du bruger de samme værdier som jeg, får du dette:

Det ser ikke ligefrem ud til, at vi har sat bredden for alle striberne, vel? Det er på grund af auto højdeadfærd for enkeltværdisyntaksen. Den anden stribe er bredere end de andre under den, og den dækker dem. Vi burde indstille højderne, så vi kan se vores arbejde. De skal alle have samme højde, og vi kan faktisk genbruge vores --n variabel, igen, for at holde tingene simple:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
    background-repeat: no-repeat;
    background-size: 60% var(--n), 90% var(--n), 70% var(--n), 40% var(--n), 10% var(--n); // HIGHLIGHT 15
}

Ah, meget bedre!

Tilføjelse af mellemrum mellem striberne

Dette er et helt valgfrit trin, hvis dit design ikke kræver mellemrum mellem striberne, men mit gjorde det, og det er ikke alt for kompliceret. Vi ændrer højden på hver stribe background-size en lille smule, hvilket reducerer værdien, så de ikke fylder hele det lodrette rum.

Vi kan fortsætte med at bruge vores --n variabel, men træk et lille beløb fra, f.eks 5px, ved brug af calc() at få det, vi ønsker.

background-size: 60% calc(var(--n) - 5px), 90% calc(var(--n) - 5px), 70% calc(var(--n) - 5px), 40% calc(var(--n) - 5px), 10% calc(var(--n) - 5px);

Det er en masse gentagelser, vi kan eliminere med en anden variabel:

div {
  --h: calc(var(--n) - 5px);
  /* etc. */
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Maskering og blanding

Lad os nu bytte om palegreen baggrundsfarve, vi har brugt til visuelle formål indtil dette tidspunkt for hvid.

div {
  /* etc. */
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    #fff;
  /* etc. */
}

Et sort/hvidt mønster som dette er perfekt til maskering og blanding. For at gøre det skal vi først pakke vores ind

i en ny forældrebeholder og introducer en anden

under det:

Vi vil lave en lille CSS re-factoring her. Nu hvor vi har en ny forældrebeholder, kan vi videregive det faste width , height egenskaber, vi brugte på vores

der ovre:

section {
  width: 500px;
  height: 500px;
} 

Jeg vil også bruge CSS Grid til at placere de to

elementer oven på hinanden. Dette er det samme trick Temani Afif bruger til at skabe sit super fede billedgallerier. Tanken er, at vi placerer begge div'er over den fulde container ved hjælp af grid-area ejendom og juster alt mod midten:

section {
  display: grid;
  align-items: center;
  justify-items: center;
  width: 500px;
  height: 500px;
} 

section > div {
  width: inherit;
  height: inherit;
  grid-area: 1 / 1;
}

Tjek nu det her ud. Grunden til, at jeg brugte en solid gradient, der går fra sort til sort tidligere, er for at indstille os til at maskere og blande de to

lag. Dette er ikke sand maskering i den forstand, at vi kalder det mask egenskab, men kontrasten mellem lagene styrer, hvilke farver der er synlige. Området dækket af hvidt vil forblive hvidt, og området dækket af sort siver igennem. MDN's dokumentation om blandingstilstande har en god forklaring på hvordan det virker.

For at få det til at virke, vil jeg anvende den rigtige gradient, vi ønsker at se på den første

mens vi anvender stilreglerne fra vores initial

på den nye ved hjælp af :nth-child() pseudo-vælger:

div:nth-child(1) { 
  background: linear-gradient(to right, red, orange); 
}

div:nth-child(2)  {
  --gt: linear-gradient(black, black);
  --n: 100px;
  --h: calc(var(--n) - 5px);
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    white;
  background-repeat: no-repeat;
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Hvis vi stopper her, vil vi faktisk ikke se nogen visuel forskel fra det, vi havde før. Det er fordi vi ikke har lavet selve blandingen endnu. Så lad os gøre det nu ved hjælp af screen blandingstilstand:

div:nth-child(2)  {
  /* etc. */
  mix-blend-mode: screen;
}

Jeg brugte en beige baggrundsfarve i den demo, jeg viste i begyndelsen af ​​denne artikel. Den lidt mørkere form for råhvid farve gør det muligt for lidt farve at flyde gennem resten af ​​baggrunden:

Svæveeffekten

Den sidste brik i dette puslespil er svæveeffekten, der udvider striberne til fuld bredde. Lad os først skrive vores vælger til det. Vi ønsker, at dette skal ske, når den overordnede container (

i vores tilfælde) er svævet. Når den har svævet, ændrer vi baggrundsstørrelsen på striberne i den anden

:

/* When 
is hovered, change the second div's styles */ section:hover > div:nth-child(2){ /* styles go here */ }

Vi vil gerne ændre background-size af striberne til hele beholderens bredde, mens den samme højde bevares:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
}

Det "snapper" baggrunden til fuld bredde. Hvis vi tilføjer lidt transition til dette, så ser vi striberne udvide sig ved at svæve:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
  transition: background-size 1s;
}

Her er den sidste demo igen:

Jeg tilføjede kun tekst derinde for at vise, hvordan det kunne se ud at bruge dette i en anden sammenhæng. Hvis du gør det samme, så er det værd at sørge for, at der er tilstrækkelig kontrast mellem tekstfarven og de farver, der bruges i gradienten til at overholde WCAG retningslinjer. Og selvom vi kort berører tilgængelighed, er det det værd overvejer brugerpræferencer for reduceret bevægelse når det kommer til svæveeffekten.

Det er en wrap!

Ret pænt, ikke? Det synes jeg bestemt. Det, jeg også godt kan lide ved dette, er, at det er ret vedligeholdelsesvenligt og kan tilpasses. For eksempel kan vi ændre stribernes højde, farver og retning ved at ændre nogle få værdier. Du kan endda variere nogle flere ting derinde - som farver og bredder - for at gøre det endnu mere konfigurerbart.

Jeg er virkelig interesseret, hvis du ville have grebet dette an på en anden måde. Hvis ja, så del venligst i kommentarerne! Det ville være fint at se, hvor mange varianter vi kan samle.

Tidsstempel:

Mere fra CSS-tricks