Rengeteg preloader megoldás található a neten: generátorok, megírt kis kódok, gifek és egyebek. Viszont én mindenképpen olyan megoldást szerettem volna, ami natív CSS, lehetőleg javascript nélkül. Mivel a böngészők egyre fejlettebb CSS támogatással vannak felvértezve, gondoltam, használjuk ki ezeket. Hamar rá is bukkantam a megfelelőnek ígérkező megoldásra, és némi átírás és kibővítés után végül meg is született az alábbi kód.
A HTML markup végtelenül egyszerű, magyarázatra sem szorul:
<div class="countdown-wrap"> <div class="countdown"> <span class="numbers num1">1</span> <span class="numbers num2">2</span> <span class="numbers num3">3</span> <span class="side side-left"> <span class="fill"></span> </span> <span class="side side-right"> <span class="fill"></span> </span> </div> </div>
Ez jelen esetben háromtól számol vissza, de ez elég könnyen módosítható.
A kódunkban így mutat a countdown-wrap div konténerünk, az alábbi néhány formázással:
.countdown-wrap { display: inline-block; margin: 0 10px; font-family: 'Arial'; position: relative; }
Ezt a div-et alapvetően el is hagyhatnánk, és a szükséges tulajdonságokat a countdown div-re ruházhatjuk át – nekem így tisztábbnak tűnt és könnyebben kezelhetőnek; módosíthatónak, bárhová beilleszthetőnek .
A countdown div-vel formázzuk hát meg a szürke hátterű kört és megadjuk egy animation-nel, hogy 3 másodperc után legyen láthatatlan. A “pörgettyűnk” 50×50 px méretet kapta:
.countdown-wrap .countdown { position: relative; border-radius: 100%; width: 50px; height: 50px; background: #eee; opacity: 0; animation-duration: 3s; animation-name: countdown-hide; } @keyframes countdown-hide { 0% {opacity: 1;} 99% {opacity: 1;} 100% {opacity: 0;} }
Készítünk egy after pszeudót a countdown div-nek, ami egy “fake mask” – egy fehér hátterű kör, ami kisebb a countdown div-nél, így kapjuk meg a 3 px vékony szürke kört. Ha nem fehér háttérre tesszük a “pörgettyűt”, akkor az itt lévő háttérszínt kell módosítanunk, hogy továbbra is maszknak tűnjön, már ha ez a cél.
Íme:
.countdown-wrap .countdown::after { content: ""; background: #fff; position: absolute; width: 44px; height: 44px; border-radius: 50%; top: 3px; left: 3px; display: block; }
Ezt követően megformázzuk a számokat, hogy a megfelelő méretben, a megfelelő helyen és időben jelenjenek meg, majd tűnjenek el. A számokat abszolút pozícióval kell a bal felső sarokhoz igazítani ahhoz, hogy a kör közepén jelenjenek meg. Átlátszóságuk nulla, melyet majd az animáció módosít az 1 másodperces futásakor, elején és végén az idő 10%-a alatt, láthatóra, majd nem láthatóra. Azért, hogy a számok ne egyszerre jelenjenek meg, hanem egymás után, ahogyan egy visszaszámlálóhoz illik, megadunk nekik 0, 1 és 2 másodperces várakoztatást, hogy melyik szám mikor hívja meg az animációt. Így tehát a hármas szám, amivel kezdünk, nem várakozik; kettes szám 1 másodperc után hívja az animációt, míg az egyes szám 2 másodpercet várakozik az animáció hívása előtt.
.countdown-wrap .countdown .numbers { position: absolute; left: 15px; top: 5px; color: #555; font-size: 36px; font-weight: bold; z-index: 100; opacity: 0; animation-duration: 1s; animation-name: num-show-hide; } @keyframes num-show-hide { 0% {opacity: 0;} 10% {opacity: 1;} 90% {opacity: 1;} 100% {opacity: 0;} } .countdown-wrap .countdown .numbers.num1 { animation-delay: 2s; } .countdown-wrap .countdown .numbers.num2 { animation-delay: 1s; } .countdown-wrap .countdown .numbers.num3 { animation-delay: 0s; }
A végére hagytam az igazán látványos részt, amikor a “pörgettyű” animációját alakítjuk ki.
A side div-ek mindketten egy 50% széles téglalapok, melyek balra és jobbra helyezkednek el egymás mellett, kitöltve így a countdown szülő elemet. Ezek maszkként funkcionálnak majd a fill div gyermek elemük számára.
.countdown-wrap .countdown .side { width: 50%; height: 100%; overflow: hidden; position: absolute; } .countdown-wrap .countdown .side-left { left: 0; } .countdown-wrap .countdown .side-right { right: 0; }
A fill div-ek mindketten egy-egy félkört alkotnak, az ellenkező oldalon, mint a szülőelemük, így alapesetben nem láthatóak, hiszen pozíciójuk kívül helyezi őket a szülőelem által befoglalt területen.
.countdown-wrap .countdown .side .fill { border-radius: 50px; position: absolute; width: 100%; height: 100%; background: #bfbfbf; /* countdown color */ animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 2s; animation-iteration-count: 2; opacity: 1; } .countdown-wrap .countdown .side-left .fill { left: 100%; border-top-left-radius: 0; border-bottom-left-radius: 0; animation-name: countdown-rotate-left; transform-origin: 0 50%; } .countdown-wrap .countdown .side-right .fill { left: -100%; border-top-right-radius: 0; border-bottom-right-radius: 0; animation-name: countdown-rotate-right; transform-origin: 100% 50%; }
Ezek az elemek 2 másodperc alatt fordulnak teljesen körbe, bevárva egymást minkét oldalon. Így a “pörgettyű” felváltva lesz kitöltött és nem kitöltött egy-egy másodpercre, azaz világosszürke (ez a countdown div háttérszine), és sötétszürke (ez a fill div-ek háttérszine).
A csík színe úgy változik, hogy az adott fill div elfordulásakor, vagy a szülőelemének pozíciójára fordul rá (ekkor lesz látható és kitölti a világos szürke csíkot a sötét szürke), vagy abból fordul ki (ekkor pedig a sötétszürke csíkból egyre kevesebb, végül semmi nem lesz látható).
@keyframes countdown-rotate-right { 0% {transform: rotate(0deg);} 25% {transform: rotate(180deg);} 50% {transform: rotate(180deg);} 75% {transform: rotate(360deg);} 100% {transform: rotate(360deg);} } @keyframes countdown-rotate-left { 0% {transform: rotate(0deg);} 25% {transform: rotate(0deg);} 50% {transform: rotate(180deg);} 75% {transform: rotate(180deg);} 100% {transform: rotate(360deg);} }
A leírt kódokban nem használtam a prefix-eket (-webkit-, -moz-, stb.) a szükséges helyeken, ezeket mindenképpen érdemes elkészíteni hozzá, amennyiben ezt a megoldást választjuk.
A countdown nagyon jól működött, azonban végül az igény úgy módosult, hogy a visszaszámlálás időtartama dinamikusan módosítható legyen, így mégis befészkelte magát az eredménybe a javascript. Azonban ha fix másodpercre van szükség, akkor ez jó megoldás lehet bárki számára.
Végül a teljes kód JADE és LESS formátumban, és az eredmény.