Animerte bakgrunnsstriper som går over på Hover PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Animerte bakgrunnsstriper som går over når du svever

Hvor ofte skal du strekke deg etter CSS background-size eiendom? Hvis du er som meg - og sannsynligvis mange andre front-end folk - så er det vanligvis når du background-size: cover et bilde for å fylle rommet til et helt element.

Vel, jeg ble presentert for en interessant utfordring som krevde mer avansert bakgrunnsstørrelse: bakgrunnsstriper som går over ved sveving. Sjekk dette og hold det med markøren:

Det er mye mer som skjer der enn størrelsen på bakgrunnen, men det var trikset jeg trengte for å få stripene til å gå over. Jeg tenkte jeg skulle vise deg hvordan jeg kom dit, ikke bare fordi jeg synes det er en veldig fin visuell effekt, men fordi det krevde at jeg ble kreativ med gradienter og blandingsmoduser som jeg tror du kan like.

La oss starte med et veldig grunnleggende oppsett for å gjøre ting enkelt. Jeg snakker om en singel

i HTML-en som er stilt som en grønn firkant:

div {
  width: 500px;
  height: 500px;
  background: palegreen;
}
Animerte bakgrunnsstriper som går over når du svever

Sette opp bakgrunnsstripene

Hvis tankene dine gikk rett til en lineær CSS-gradient når du så disse stripene, så er vi allerede på samme side. Vi kan ikke akkurat gjøre en repeterende gradient i dette tilfellet siden vi vil at stripene skal oppta ujevn mengde plass og overføre dem, men vi kan lage fem striper ved å lenke fem bakgrunner på toppen av vår eksisterende bakgrunnsfarge og plassere dem til toppen - høyre 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 laget horisontale striper, men vi kunne også gå vertikalt med tilnærmingen vi dekker her. Og vi kan forenkle dette ganske mye med egendefinerte egenskaper:

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

Så, --gt verdi er gradienten og --n er en konstant vi bruker for å dytte stripene nedover slik at de er forskjøvet vertikalt. Og du har kanskje lagt merke til at jeg ikke har satt en ekte gradient, men heller solide svarte striper i linear-gradient() funksjon — det er med vilje, og vi kommer til hvorfor jeg gjorde det om litt.

En ting til vi bør gjøre før vi går videre er å forhindre at bakgrunnen vår gjentar seg; ellers vil de flislegge og fylle hele plassen:

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 ha satt background-repeat i background stenografi, men jeg bestemte meg for å dele det ut her for å gjøre det lett å lese.

Forskyvning av stripene

Vi har teknisk sett striper, men det er ganske vanskelig å si fordi det ikke er noen avstand mellom dem og de dekker hele beholderen. Det er mer som om vi har en solid svart firkant.

Det er her vi får bruke background-size eiendom. Vi ønsker å sette både høyden og bredden på stripene, og egenskapen støtter en to-verdi syntaks som lar oss gjøre akkurat det. Og vi kan kjede disse størrelsene ved å skille dem med komma på samme måte som vi gjorde på background.

La oss starte enkelt med å stille inn breddene først. Bruke enkeltverdisyntaksen for background-size setter bredden og standard høyden auto. Jeg bruker helt vilkårlige verdier her, så sett verdiene til det som fungerer best for designet ditt:

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 bruker de samme verdiene som jeg, får du dette:

Ser ikke akkurat ut som vi setter bredden på alle stripene, gjør det vel? Det er på grunn av auto høydeoppførselen til enkeltverdisyntaksen. Den andre stripen er bredere enn de andre under den, og den dekker dem. Vi burde sette høydene slik at vi kan se arbeidet vårt. De skal alle være like høye, og vi kan faktisk gjenbruke våre --n variabel, igjen, for å holde ting enkelt:

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, mye bedre!

Legge til mellomrom mellom stripene

Dette er et helt valgfritt trinn hvis designet ditt ikke krever mellomrom mellom stripene, men mitt gjorde det, og det er ikke altfor komplisert. Vi endrer høyden på hver stripe background-size en smidge, reduserer verdien slik at de ikke fyller hele det vertikale rommet.

Vi kan fortsette å bruke vår --n variabel, men trekk fra et lite beløp, si 5px, Ved hjelp calc() for å 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 mye repetisjon vi kan eliminere med en annen 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

La oss nå bytte ut palegreen bakgrunnsfarge vi har brukt til visuelle formål frem til nå for hvit.

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 svart-hvitt mønster som dette er perfekt for maskering og blanding. For å gjøre det, skal vi først pakke inn vår

i en ny overordnet beholder og introduser en andre

under den:

Vi skal gjøre en liten CSS-refaktorering her. Nå som vi har en ny overordnet container, kan vi passere den faste width og height egenskaper vi brukte på vår

der borte:

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

Jeg kommer også til å bruke CSS Grid for å plassere de to

elementer oppå hverandre. Dette er det samme trikset Temani Afif bruker for å lage sitt superkule bildegallerier. Tanken er at vi plasserer begge divene over hele beholderen ved å bruke grid-area eiendom og juster alt mot midten:

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

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

Nå, sjekk dette ut. Grunnen til at jeg brukte en solid gradient som går fra svart til svart tidligere, er for å sette oss opp for maskering og blanding av de to

lag. Dette er ikke ekte maskering i den forstand at vi kaller mask egenskap, men kontrasten mellom lagene styrer hvilke farger som er synlige. Området dekket av hvitt vil forbli hvitt, og området dekket av svart lekker gjennom. MDNs dokumentasjon om blandingsmoduser har en fin forklaring på hvordan dette fungerer.

For å få det til å fungere, bruker jeg den virkelige gradienten vi ønsker å se på den første

mens vi bruker stilreglene fra initialen vår

på den nye ved å bruke :nth-child() pseudovelger:

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 noen visuell forskjell fra det vi hadde før. Det er fordi vi ikke har gjort selve blandingen ennå. Så la oss gjøre det nå ved å bruke screen blandingsmodus:

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

Jeg brukte en beige bakgrunnsfarge i demoen jeg viste i begynnelsen av denne artikkelen. Den litt mørkere typen off-white-farging lar litt farge blø gjennom resten av bakgrunnen:

Hover-effekten

Den siste biten i dette puslespillet er sveveeffekten som utvider stripene til full bredde. Først, la oss skrive ut velgeren vår for det. Vi vil at dette skal skje når overordnet container (

i vårt tilfelle) holdes over. Når den holdes, endrer vi bakgrunnsstørrelsen på stripene i den andre

:

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

Vi vil endre background-size av stripene til hele beholderens bredde mens samme høyde opprettholdes:

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

Det "snapper" bakgrunnen til full bredde. Hvis vi legger til litt transition til dette, så ser vi stripene utvides ved sveving:

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

Her er den siste demoen igjen:

Jeg la bare til tekst der for å vise hvordan det kan se ut å bruke dette i en annen sammenheng. Hvis du gjør det samme, er det verdt å sørge for at det er nok kontrast mellom tekstfargen og fargene som brukes i gradienten til å overholde WCAG retningslinjer. Og mens vi kort berører tilgjengelighet, er det verdt det vurdere brukerpreferanser for redusert bevegelse når det gjelder sveveeffekten.

Det er en wrap!

Ganske ryddig, ikke sant? Det tror jeg absolutt. Det jeg liker med denne også er at den er ganske vedlikeholdbar og kan tilpasses. For eksempel kan vi endre høyden, fargene og retningen til stripene ved å endre noen få verdier. Du kan til og med variere noen flere ting der inne - som farger og bredder - for å gjøre det enda mer konfigurerbart.

Jeg er veldig interessert om du ville ha stilt dette på en annen måte. I så fall, del gjerne i kommentarene! Det ville vært fint å se hvor mange varianter vi kan samle.

Tidstempel:

Mer fra CSS triks