Enkeltelementlastere: Går i 3D! PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Enkeltelementlastere: Går i 3D!

For denne fjerde og siste artikkelen i vår liten serie om enkeltelementlastere, skal vi utforske 3D-mønstre. Når du lager et 3D-element, er det vanskelig å forestille seg at bare ett HTML -element er nok til å simulere noe som alle seks flater i en kube. Men  kanskje vi kan komme unna med noe mer kube-i likhet med i stedet ved å vise bare de tre fremre sidene av formen – det er fullt mulig, og det er det vi skal gjøre sammen.

Artikkelserie

Den delte kubelasteren

Her er en 3D-laster der en kube er delt i to deler, men er kun laget med kun ett enkelt element:

CodePen Embed Fallback

Hver halvdel av kuben er laget ved hjelp av et pseudo-element:

Enkeltelementlastere: Går i 3D! PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Enkeltelementlastere: Går i 3D!

Kult, ikke sant?! Vi kan bruke en konisk gradient med CSS clip-path på elementet ::before og ::after pseudos for å simulere de tre synlige ansiktene til en 3D-kube. Negativ margin er det som trekker de to pseudoene sammen for å overlappe og simulere en hel kube. Resten av arbeidet vårt er for det meste å animere de to halvdelene for å få pene lastere!

La oss sjekke ut en visualisering som forklarer matematikken bak klippebanepunktene som ble brukt til å lage dette kubelignende elementet:

Enkeltelementlastere: Går i 3D! PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Enkeltelementlastere: Går i 3D!

Vi har våre variabler og en ligning, så la oss sette dem i arbeid. Først vil vi etablere variablene våre og angi størrelsen for hoveddelen .loader element:

.loader { --s: 150px; /* control the size */ --_d: calc(0.353 * var(--s)); /* 0.353 = sin(45deg)/2 */ width: calc(var(--s) + var(--_d)); aspect-ratio: 1; display: flex;
}

Ingenting er for sprøtt så langt. Vi har en 150px kvadrat som er satt opp som en fleksibel beholder. Nå etablerer vi pseudoene våre:

.loader::before,
.loader::after { content: ""; flex: 1;
}

Det er to halvdeler i .loader container. Vi må male dem inn, så det er der vi har konisk gradient sparker inn:

.loader::before,
.loader::after { content: ""; flex: 1; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0);
}

Gradienten er der, men det ser rart ut. Vi må fest den til elementet:

.loader::before,
.loader::after { content: ""; flex: 1; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0); clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
}

La oss sørge for at de to halvdelene overlapper med a negativ margin:

.loader::before { margin-right: calc(var(--_d) / -2);
} .loader::after { margin-left: calc(var(--_d) / -2);
}

La oss nå få dem til å bevege seg!

.loader::before,
.loader::after { /* same as before */ animation: load 1.5s infinite cubic-bezier(0, .5, .5, 1.8) alternate;
} .loader::after { /* same as before */ animation-delay: -.75s
} @keyframes load{ 0%, 40% { transform: translateY(calc(var(--s) / -4)) } 60%, 100% { transform: translateY(calc(var(--s) / 4)) }
}

Her er den siste demoen igjen:

CodePen Embed Fallback

Fremdriftskubelasteren

La oss bruke samme teknikk for å lage en 3D-fremdriftslaster. Ja, fortsatt bare ett element!

CodePen Embed Fallback

Vi endrer ikke noe så langt som å simulere kuben på samme måte som vi gjorde før, annet enn å endre lasterens høyde og sideforhold. Animasjonen vi lager er avhengig av en overraskende enkel teknikk der vi oppdaterer bredden på venstre side mens høyre side fyller den gjenværende plassen, takket være flex-grow: 1.

Det første trinnet er å legge til litt åpenhet på høyre side ved å bruke opacity:

CodePen Embed Fallback

Dette simulerer effekten av at den ene siden av kuben fylles ut mens den andre er tom. Deretter oppdaterer vi fargen på venstre side. For å gjøre det oppdaterer vi enten de tre fargene inne i den koniske gradienten, eller vi gjør det ved å legge til en bakgrunnsfarge med en background-blend-mode:

.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply;
}

Dette trikset lar oss bare oppdatere fargen én gang. Høyre side av lasteren smelter sammen med de tre nyansene av hvitt fra den koniske gradienten for å lage tre nye nyanser av fargen vår, selv om vi bare bruker én fargeverdi. Fargelureri!

CodePen Embed Fallback

La oss animere bredden på lasterens venstre side:

CodePen Embed Fallback

Oi, animasjonen er litt merkelig i begynnelsen! Legg merke til hvordan det liksom starter utenfor kuben? Dette er fordi vi starter animasjonen på 0% bredde. Men på grunn av clip-path og negativ margin vi bruker, det vi trenger å gjøre i stedet er å starte fra vår --_d variabel, som vi brukte til å definere clip-path poeng og negativ margin:

@keyframes load { 0%, 5% {width: var(--_d); } 95%, 100% {width: 100%; }
}

Det er litt bedre:

CodePen Embed Fallback

Men vi kan gjøre denne animasjonen enda jevnere. La du merke til at vi mangler litt? La meg vise deg et skjermbilde for å sammenligne hvordan den endelige demoen skal se ut med den siste demoen:

Enkeltelementlastere: Går i 3D! PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Det er undersiden av kuben! Siden det andre elementet er gjennomsiktig, må vi se undersiden av det rektangelet som du kan se i eksempelet til venstre. Det er subtilt, men burde være der!

Vi kan legge til en gradient til hovedelementet og klippe det som vi gjorde med pseudoene:

background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat;

Her er hele koden når alt er trukket sammen:

.loader { --s: 100px; /* control the size */ --_d: calc(0.353*var(--s)); /* 0.353 = sin(45deg) / 2 */ height: var(--s); aspect-ratio: 3; display: flex; background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat; clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
}
.loader::before,
.loader::after { content: ""; clip-path: inherit; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0);
}
.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply; margin-right: calc(var(--_d) / -2); animation: load 2.5s infinite linear;
}
.loader:after { flex: 1; margin-left: calc(var(--_d) / -2); opacity: 0.4;
} @keyframes load { 0%, 5% { width: var(--_d); } 95%, 100% { width: 100%; }
}
CodePen Embed Fallback

Det er det! Vi brukte nettopp en smart teknikk som bruker pseudo-elementer, koniske gradienter, klipping, bakgrunnsblanding og negative marginer for å få, ikke én, men to søte 3D-lastere med ikke mer enn ett enkelt element i markeringen.

Mer 3D

Vi kan fortsatt gå lenger og simulere et uendelig antall 3D-kuber ved å bruke ett element - ja, det er mulig! Her er et rutenett med kuber:

CodePen Embed Fallback

Denne demoen og de følgende demoene støttes ikke i Safari i skrivende stund.

Galt, ikke sant? Nå lager vi et gjentatt mønster av kuber laget med et enkelt element ... og ingen pseudoer heller! Jeg vil ikke gå i detaljer om matematikken vi bruker (det er veldig spesifikke tall der inne), men her er en figur for å visualisere hvordan vi kom hit:

Enkeltelementlastere: Går i 3D! PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Enkeltelementlastere: Går i 3D!

Vi bruker først en conic-gradient for å lage det gjentatte kubemønsteret. Gjentakelsen av mønsteret styres av tre variabler:

  • --size: Tro mot navnet kontrollerer dette størrelsen på hver kube.
  • --m: Dette representerer antall kolonner.
  • --n: Dette er antall rader.
  • --gap: dette gapet eller avstanden mellom kubene
.cube { --size: 40px; --m: 4; --n: 5; --gap :10px; aspect-ratio: var(--m) / var(--n); width: calc(var(--m) * (1.353 * var(--size) + var(--gap))); background: conic-gradient(from -90deg at var(--size) calc(0.353 * var(--size)), #249FAB 135deg, #81C5A3 0 270deg, #26609D 0) /* update the colors here */ 0 0 / calc(100% / var(--m)) calc(100% / var(--n));
}

Deretter legger vi et maskelag ved å bruke et annet mønster med samme størrelse. Dette er den vanskeligste delen av denne ideen. Ved å bruke en kombinasjon av en linear-gradient og en conic-gradient vi vil kutte noen få deler av elementet vårt for å holde bare kubeformene synlige.

.cube { /* etc. */ mask: linear-gradient(to bottom right, #0000 calc(0.25 * var(--size)), #000 0 calc(100% - calc(0.25 * var(--size)) - 1.414 * var(--gap)), #0000 0), conic-gradient(from -90deg at right var(--gap) bottom var(--gap), #000 90deg, #0000 0); mask-size: calc(100% / var(--m)) calc(100% / var(--n)); mask-composite: intersect;
}

Koden kan se litt kompleks ut, men takket være CSS-variabler er alt vi trenger å gjøre å oppdatere noen verdier for å kontrollere matrisen vår av kuber. Trenger du et 10⨉10 rutenett? Oppdater --m og --n variabler til 10. Trenger du et større gap mellom kuber? Oppdater --gap verdi. Fargeverdiene brukes kun én gang, så oppdater dem for en ny fargepalett!

Nå som vi har en annen 3D-teknikk, la oss bruke den til å bygge varianter av lasteren ved å leke med forskjellige animasjoner. For eksempel, hva med et gjentatt mønster av kuber som glir uendelig fra venstre til høyre?

CodePen Embed Fallback

Denne lasteren definerer fire kuber i en enkelt rad. Det betyr vår --n verdien er 4 og --m er lik 1 . Disse trenger vi med andre ord ikke lenger!

I stedet kan vi jobbe med --size og --gap variabler i en rutenettbeholder:

.loader { --size: 70px; --gap: 15px; width: calc(3 * (1.353 * var(--size) + var(--gap))); display: grid; aspect-ratio: 3;
}

Dette er vår container. Vi har fire kuber, men ønsker kun å vise tre i beholderen om gangen slik at vi alltid har en som sklir inn mens en sklir ut. Derfor tar vi hensyn til bredden 3 og ha sideforholdet satt til 3 også.

La oss sørge for at kubemønsteret vårt er satt opp for bredden på fire kuber. Vi skal gjøre dette på containerens ::before pseudo-element:

.loader::before { content: ""; width: calc(4 * 100% / 3); /* Code to create four cubes */
}

Nå som vi har fire terninger i en tre-kubebeholder, kan vi rettferdiggjøre kubemønsteret til enden av rutenettbeholderen for å flyte over det, og viser de tre siste kubene:

.loader { /* same as before */ justify-content: end;
}

Her er det vi har så langt, med en rød kontur for å vise grensene til rutenettbeholderen:

CodePen Embed Fallback

Nå er alt vi trenger å gjøre å flytte pseudo-elementet til høyre ved å legge til animasjonen vår:

@keyframes load { to { transform: translate(calc(100% / 4)); }
}
CodePen Embed Fallback

Fikk du trikset med animasjonen? La oss avslutte dette ved å skjule det overfylte kubemønsteret og ved å legge til et snev av maskering for å skape den falmingseffekten som starter og slutter:

.loader { --size: 70px; --gap: 15px; width: calc(3*(1.353*var(--s) + var(--g))); display: grid; justify-items: end; aspect-ratio: 3; overflow: hidden; mask: linear-gradient(90deg, #0000, #000 30px calc(100% - 30px), #0000);
}
CodePen Embed Fallback

Vi kan gjøre dette mye mer fleksibelt ved å introdusere en variabel, --n, for å angi hvor mange kuber som skal vises i beholderen samtidig. Og siden det totale antallet kuber i mønsteret skal være en mer enn --n, vi kan uttrykke det som calc(var(--n) + 1).

Her er hele greia:

CodePen Embed Fallback

OK, enda en 3D-laster som er lik, men som har kubene som skifter farge etter hverandre i stedet for å skyve:

CodePen Embed Fallback

Vi kommer til å stole på en animert bakgrunn med background-blend-mode for denne:

.loader { /* ... */ background: linear-gradient(#ff1818 0 0) 0% / calc(100% / 3) 100% no-repeat, /* ... */; background-blend-mode: multiply; /* ... */ animation: load steps(3) 1.5s infinite;
}
@keyframes load { to { background-position: 150%; }
}

Jeg har fjernet den overflødige koden som ble brukt til å lage den samme layouten som forrige eksempel, men med tre kuber i stedet for fire. Det jeg legger til her er en gradient definert med en spesifikk farge som blander seg med den koniske gradienten, akkurat som vi gjorde tidligere for fremdriftslinjen 3D-lasteren.

Derfra animerer den bakgrunnsgradienten background-position som en tre-trinns animasjon for å få kubene til å blinke farger én om gangen.

Hvis du ikke er kjent med verdiene jeg bruker for background-position og bakgrunnssyntaksen, anbefaler jeg på det sterkeste en av mine tidligere artikler og en av mine Stack Overflow-svar. Du finner en veldig detaljert forklaring der.

Kan vi oppdatere antall kuber for å gjøre det til variabler?

Ja, jeg har en løsning for det, men jeg vil gjerne at du tar en knekk på det i stedet for å legge det inn her. Ta det vi har lært fra forrige eksempel og prøv å gjøre det samme med dette - del deretter arbeidet ditt i kommentarene!

Variasjoner i massevis!

I likhet med de tre andre artiklene i denne serien, vil jeg gjerne gi deg litt inspirasjon til å gå videre og lage dine egne lastere. Her er en samling som inkluderer 3D-lasterne vi har laget sammen, pluss noen andre for å få fantasien i gang:

CodePen Embed Fallback

Det er en innpakning

Jeg håper virkelig du likte å bruke tid på å lage enkeltelementlastere med meg de siste ukene. Det er sprøtt at vi startet med tilsynelatende enkel spinner og så gradvis lagt til nye deler for å jobbe oss helt opp til 3D-teknikker som fortsatt bare bruker et enkelt element i markeringen. Dette er nøyaktig hvordan CSS ser ut når vi utnytter dens krefter: skalerbar, fleksibel og gjenbrukbar.

Takk igjen for at du leste denne lille serien! Jeg melder meg av ved å minne deg på at jeg har en samling av mer enn 500 lastere hvis du leter etter flere ideer og inspirasjon.

Artikkelserie


Enkeltelementlastere: Går i 3D! opprinnelig publisert på CSS-triks. Du burde få nyhetsbrevet.

Tidstempel:

Mer fra CSS triks