Å lage CSS-bare lastere er en av mine favorittoppgaver. Det er alltid tilfredsstillende å se på de uendelige animasjonene. Og det er det selvfølgelig masse av teknikker og tilnærminger for å lage dem - ikke nødvendig se lenger enn CodePen for å se hvor mange. I denne artikkelen vil vi imidlertid se hvordan du får en enkeltelementlaster til å skrive så lite kode som mulig.
Jeg har laget en samling på mer enn 500 enkelt div-lastere og i denne firedelte serien skal jeg dele triksene jeg brukte for å lage mange av dem. Vi skal dekke et stort antall eksempler, vise hvordan små justeringer kan føre til morsomme variasjoner, og hvor lite kode vi trenger å skrive for å få det hele til!
Single-Element Loaders-serien:
- Enkeltelementlastere: Spinneren — du er her
- Single Element Loaders: The Dots — kommer 17 juni
- Single Element Loaders: The Bars — kommer 24 juni
- Single Element Loaders: Going 3D — kommer 1 juli
For denne første artikkelen skal vi lage et av de mer vanlige lastemønstrene: spinnende stenger:
Her er tilnærmingen
En triviell implementering for denne lasteren er å lage ett element for hver stang pakket inn i et overordnet element (for totalt ni elementer), og deretter leke med opacity
og transform
for å få spinneffekten.
Implementeringen min krever imidlertid bare ett element:
<div class="loader"></div>
…og 10 CSS-erklæringer:
.loader { width: 150px; /* control the size */ aspect-ratio: 1; display: grid; mask: conic-gradient(from 22deg, #0003, #000); animation: load 1s steps(8) infinite;
}
.loader,
.loader:before { --_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */ background: var(--_g)/34% 8% space no-repeat, var(--_g)/8% 34% no-repeat space;
}
.loader:before { content: ""; transform: rotate(45deg);
}
@keyframes load { to { transform: rotate(1turn); }
}
La oss bryte det ned
Ved første øyekast kan koden se merkelig ut, men du vil se at den er enklere enn du kanskje tror. Det første trinnet er å definere dimensjonen til elementet. I vårt tilfelle er det en 150px
torget. Vi kan sette aspect-ratio
å bruke slik at elementet forblir firkantet uansett.
.loader { width: 150px; /* control the size */ aspect-ratio: 1; /* make height equal to width */
}
Når jeg bygger CSS-lastere, prøver jeg alltid å ha én verdi for å kontrollere den totale størrelsen. I dette tilfellet er det width
og alle beregningene vi dekker vil referere til den verdien. Dette lar meg endre en enkelt verdi for å kontrollere lasteren. Det er alltid viktig å enkelt kunne justere størrelsen på våre lastere uten å måtte justere mange tilleggsverdier.
Deretter vil vi bruke gradienter for å lage stolpene. Dette er den vanskeligste delen! La oss bruke en gradient å lage to stolper som nedenfor:
background: linear-gradient(#17177c 0 0) 50%/34% 8% space no-repeat;
Gradienten vår er definert med én farge og to fargestopp. Resultatet er en solid farge uten falming eller overganger. Størrelsen er lik 34%
bred og 8%
høy. Den er også plassert i sentrum (50%
). Trikset er bruken av nøkkelordet verdi space
— dette dupliserer gradienten, og gir oss to totale søyler.
Fra spesifikasjonen:
Bildet gjentas så ofte som det passer innenfor bakgrunnsposisjonsområdet uten å bli klippet, og deretter fordeles bildene for å fylle området. Det første og siste bildet berører kantene av området.
Jeg bruker en bredde lik 34%
som betyr at vi ikke kan ha mer enn to streker (3*34%
er større enn 100%
) men med to streker vil vi ha tomme mellomrom (100% - 2 * 34% = 32%
). Dette rommet er plassert i midten mellom de to stolpene. Vi bruker med andre ord en bredde for gradienten som er mellom 33%
og 50%
for å sikre at vi har minst to stolper med litt mellomrom mellom dem. Verdien space
er det som plasserer dem riktig for oss.
Vi gjør det samme og lager en annen lignende gradient for å få ytterligere to stolper øverst og nederst, som gir oss en background
eiendomsverdi på:
background: linear-gradient(#17177c 0 0) 50%/34% 8% space no-repeat, linear-gradient(#17177c 0 0) 50%/8% 34% no-repeat space;
Vi kan optimalisere det ved å bruke en CSS-variabel for å unngå repetisjon:
--_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */
background: var(--_g)/34% 8% space no-repeat, var(--_g)/8% 34% no-repeat space;
Så nå har vi fire stolper, og takket være CSS-variabler kan vi skrive fargeverdien én gang, noe som gjør det enkelt å oppdatere senere (som vi gjorde med størrelsen på lasteren).
For å lage de gjenværende stolpene, la oss trykke på .loader
element og dets ::before
pseudo-element for å få fire flere takter for totalt åtte totalt.
.loader { width: 150px; /* control the size */ aspect-ratio: 1; display: grid;
}
.loader,
.loader::before { --_g: linear-gradient(#17177c 0 0) 50%; /* update the color here */ background: var(--_g)/34% 8% space no-repeat, var(--_g)/8% 34% no-repeat space;
}
.loader::before { content: ""; transform: rotate(45deg);
}
Legg merke til bruken av display: grid
. Dette lar oss stole på nettets standard stretch
justering for å få pseudo-elementet til å dekke hele området til det overordnede; dermed er det ikke nødvendig å spesifisere en dimensjon på den - et annet triks som reduserer koden og unngår at vi skal håndtere mange verdier!
La oss nå rotere pseudo-elementet med 45deg
for å plassere de gjenværende stolpene. Hold musepekeren over følgende demo for å se trikset:
Stille inn opasitet
Det vi prøver å gjøre er å skape inntrykk av at det er en stolpe som etterlater et spor av falmende stolper etter den når den går en sirkulær bane. Det vi trenger nå er å leke med gjennomsiktigheten til stolpene våre for å lage det sporet, som vi skal gjøre med CSS mask
kombinert med en konisk gradient som følger:
mask: conic-gradient(from 22deg,#0003,#000);
For bedre å se trikset, la oss bruke dette på en fullfarget boks:
Gjennomsiktigheten til den røde fargen øker gradvis med klokken. Vi bruker dette på lasteren vår og vi har stengene med forskjellig dekkevne:
I virkeligheten ser det ut til at hver linje blekner fordi den er maskert av en gradient og faller mellom to semi-transparente farger. Det er knapt merkbart når dette går, så det er liksom som å kunne si at alle stolpene har samme farge med ulik grad av dekkevne.
Rotasjonen
La oss bruke en rotasjonsanimasjon for å få lasteren vår. Merk at vi trenger en trinnvis animasjon og ikke en kontinuerlig, det er derfor jeg bruker steps(8)
. 8
er ingenting annet enn antall stolper, slik at verdien kan endres avhengig av hvor mange stolper som er i bruk.
.loader { animation: load 3s steps(8) infinite;
} /* Same as before: */
@keyframes load { to { transform: rotate(1turn) }
}
Det er det! Vi har vår laster med kun ett element og noen få linjer med CSS. Vi kan enkelt kontrollere størrelsen og fargen ved å justere én verdi.
Siden vi bare brukte ::before
pseudo-element, kan vi legge til fire flere stolper ved å bruke ::after
for å avslutte med totalt 12 streker og nesten samme kode:
Vi oppdaterer rotasjonen av pseudoelementene våre for å vurdere 30deg
og 60deg
istedenfor 45deg
mens du bruker en tolv-trinns animasjon, i stedet for åtte. Jeg reduserte også høyden til 5%
istedenfor 8%
for å gjøre stengene litt tynnere.
Legg også merke til at vi har grid-area: 1/1
på pseudo-elementene. Dette lar oss plassere dem i samme område som hverandre, stablet oppå hverandre.
Gjett hva? Vi kan nå den samme lasteren ved å bruke en annen implementering:
Kan du finne ut logikken bak koden? Her er et hint: opasiteten håndteres ikke lenger med en CSS mask
men inne i gradienten og bruker også opacity
eiendom.
Hvorfor ikke prikker i stedet?
Det kan vi helt gjøre:
Hvis du sjekker koden, vil du se at vi nå jobber med en radiell gradient i stedet for en lineær. Ellers er konseptet helt likt der masken skaper inntrykk av opasitet, men vi har laget formene som sirkler i stedet for linjer.
Nedenfor er en figur for å illustrere den nye gradientkonfigurasjonen:
Hvis du bruker Safari, vær oppmerksom på at demoen kan være buggy. Det er fordi Safari for øyeblikket mangler støtte for at
syntaks i radielle gradienter. Men vi kan rekonfigurere gradienten litt for å overvinne det:
.loader,
.loader:before,
.loader:after { background: radial-gradient( circle closest-side, currentColor 90%, #0000 98% ) 50% -150%/20% 80% repeat-y, radial-gradient( circle closest-side, currentColor 90%, #0000 98% ) -150% 50%/80% 20% repeat-x;
}
Flere lastereksempler
Her er en annen idé for en spinner loader som ligner på den forrige.
For denne stoler jeg bare på background
og mask
for å lage formen (ingen pseudo-elementer nødvendig). Jeg definerer også konfigurasjonen med CSS-variabler for å kunne lage mange variasjoner fra den samme koden - et annet eksempel på bare kreftene til CSS-variabler. Jeg skrev en annen artikkel om denne teknikken hvis du vil ha flere detaljer.
Merk at noen nettlesere fortsatt er avhengige av en -webkit-
prefiks for mask-composite
med sitt eget sett med verdier, og vil ikke vise spinneren i demoen. Her er en måte å gjøre det på uten mast-composite
for mer nettleserstøtte.
Jeg har en annen til deg:
Til denne bruker jeg en background-color
å kontrollere fargen og bruke mask
og mask-composite
for å lage den endelige formen:
Før vi avslutter, her er noen flere spinnlastere jeg laget for en stund tilbake. Jeg er avhengig av forskjellige teknikker, men bruker fortsatt gradienter, masker, pseudo-elementer osv. Det kan være en god øvelse å finne ut logikken til hver enkelt og lære nye triks samtidig. Når det er sagt, hvis du har spørsmål om dem, er kommentarseksjonen nedenfor.
Innpakning opp
Se, det er så mye vi kan gjøre i CSS med ingenting annet enn en enkelt div, et par gradienter, pseudo-elementer, variabler. Det virker som om vi har laget en hel haug med forskjellige spinnende lastere, men de er alle i bunn og grunn det samme med små modifikasjoner.
Dette er bare begynnelsen. I denne serien skal vi se på flere ideer og avanserte konsepter for å lage CSS-lastere.
Single-Element Loaders-serien:
- Enkeltelementlastere: Spinneren — du er her
- Single Element Loaders: The Dots — kommer 17 juni
- Single Element Loaders: The Bars — kommer 24 juni
- Single Element Loaders: Going 3D — kommer 1 juli
Enkeltelementlastere: Spinneren opprinnelig publisert på CSS-triks. Du burde få nyhetsbrevet.
- "
- 10
- 3d
- a
- Om oss
- Ytterligere
- avansert
- Alle
- tillater
- alltid
- En annen
- Påfør
- påføring
- tilnærminger
- AREA
- Artikkel
- bakgrunn
- barer
- I utgangspunktet
- fordi
- før du
- Begynnelsen
- være
- under
- mellom
- Bit
- Eske
- nett~~POS=TRUNC leseren~~POS=HEADCOMP
- Bygning
- Bunch
- endring
- Circle
- kode
- samling
- kombinert
- Felles
- konsept
- Konfigurasjon
- Vurder
- innhold
- kontroll
- kunne
- Par
- dekke
- skape
- opprettet
- skaper
- Opprette
- I dag
- avtale
- avhengig
- detaljer
- gJORDE
- forskjellig
- Dimensjon
- Vise
- ned
- lett
- effekt
- elementer
- etc
- nøyaktig
- eksempel
- eksempler
- Øvelse
- falme
- Figur
- Først
- passer
- etter
- følger
- fra
- moro
- videre
- Giving
- blikk
- skal
- god
- større
- Grid
- høyde
- her.
- Hvordan
- Hvordan
- HTTPS
- stort
- Tanken
- Ideer
- bilde
- bilder
- gjennomføring
- viktig
- I andre
- økende
- IT
- Juli
- føre
- LÆRE
- Nivå
- linjer
- lite
- laste
- Se
- ser
- laget
- gjøre
- GJØR AT
- maske
- masker
- Saken
- midler
- kunne
- mer
- Antall
- Optimalisere
- Annen
- ellers
- samlet
- egen
- Spille
- posisjon
- mulig
- forrige
- eiendom
- spørsmål
- RE
- å nå
- Reality
- gjenværende
- Krever
- Safari
- Sa
- samme
- Serien
- sett
- Form
- figurer
- Del
- lignende
- Enkelt
- enkelt
- Størrelse
- liten
- So
- solid
- noen
- Rom
- mellomrom
- kvadrat
- Still
- støtte
- Pek
- oppgaver
- teknikker
- De
- ting
- tid
- topp
- berøre
- Transform
- Åpenhet
- reiser
- Oppdater
- us
- bruke
- verdi
- W3
- Hva
- mens
- innenfor
- uten
- ord
- arbeid
- skriving