اگر وبسایتی دارید، داشتن یک لودر (بارگذار) به کاربران کمک می کند تا بتوانند به محض کلیک کردن روی یک پیوند (لینک) یا دکمه، بفهمند که اتفاقی در حال رخ دادن است. شما می توانید از این لودر در مکان های مختلف استفاده کنید و باید تا حد امکان ساده باشد. در این مقاله نحوه ساخت لودینگ با CSS را فراخواهیم گرفت دو نوع لودر را تنها با یک div و چند خط کد CSS می سازیم. افزون بر این آن را قابل تنظیم می کنیم تا بتوانید به راحتی تغییرات مختلفی را در آن ایجاد کنید. در زیر تصویر چیزی که می خواهیم بسازیم را خواهید دید:
در زیر یک نسخه نمایشی از آنچه که در حال ساخت هستیم، وجود دارد:
<div class="loader"></div> <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div> <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div> <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div>
.loader { --b: 10px; /* border thickness */ --n: 10; /* number of dashes*/ --g: 10deg; /* gap between dashes*/ --c: red; /* the color */ width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; padding: 1px; background: conic-gradient(#0000,var(--c)) content-box; -webkit-mask: repeating-conic-gradient(#0000 0deg, #000 1deg calc(360deg/var(--n) - var(--g) - 1deg), #0000 calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))), radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b))); mask: repeating-conic-gradient(#0000 0deg, #000 1deg calc(360deg/var(--n) - var(--g) - 1deg), #0000 calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))), radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b))); -webkit-mask-composite: destination-in; mask-composite: intersect; animation: load 1s infinite steps(var(--n)); } @keyframes load {to{transform: rotate(1turn)}}
برای دیدن نتیجه این نشانی را ببینید.
ما 4 لودر مختلف داریم که از یک کد استفاده می کنند. تنها با تغییر چند متغیر، میتوانیم یک لودر جدید بدون نیاز به تغییر کد CSS ایجاد کنیم.
متغیرها به صورت زیر تعریف می شوند:
در زیر یک تصویر برای مشاهده متغیرهای مختلف وجود دارد:
بیایید به کد CSS بپردازیم. ما از شکل دیگری برای نشان دادن ساخت گام به گام لودر استفاده خواهیم کرد.
ابتدا با کد زیر یک دایره ایجاد می کنیم:
.loader { width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; }
تا اینجا هیچ چیز پیچیده ای نداریم. به استفاده از نسبت ابعاد توجه کنید که به ما اجازه می دهد فقط یک مقدار (عرض) را برای تغییر اندازه تغییر دهیم. سپس یک رنگ گرادیان مخروطی از شفاف به رنگ تعریف شده (متغیر c--) اضافه می کنیم:
.loader { width:100px; /* size */ aspect-ratio: 1; border-radius: 50%; background: conic-gradient(#0000,var(--c)); }
در این مرحله ویژگی mask را برای پنهان کردن برخی از قسمتهای دایره به صورت تکراری معرفی میکنیم. این کار به متغیرهای n-- و d-- بستگی دارد. اگر به شکل دقیق نگاه کنید، متوجه الگوی زیر خواهیم شد:
بخش دیدنی
بخش نادیدنی
بخش دیدنی
بخش نادیدنی
و ادامه دارد....
برای انجام این کار، از repeating-conic-gradient (#000 0 X, #0000 0 Y) استفاده می کنیم. از 0 تا X یک رنگ مات (قسمت قابل مشاهده) و از X تا Y یک رنگ شفاف (قسمت نامرئی) داریم.
متغیرهای خود را معرفی می کنیم:
کد تا الان به صورت زیر است:
.loader { width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; background: conic-gradient(#0000,var(--c)); mask: repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n)) }
مرحله بعدی دشوارترین مرحله است، زیرا برای به دست آوردن شکل نهایی باید mask دیگری را برای ایجاد نوعی سوراخ اعمال کنیم. برای انجام این کار، از یک radial-gradient با متغیر b خود استفاده می کنیم:
radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0)
یک دایره کامل از با ضخامتی برابر با b را داریم.این را به mask قبلی اضافه می کنیم:
.loader { width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; background: conic-gradient(#0000,var(--c)); mask: radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0), repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n)) }
ما دو لایه mask داریم، اما نتیجه آن چیزی نیست که می خواهیم. با اجرای برنامه بالا تصویر زیر را خواهیم دید:
شاید عجیب به نظر برسد اما منطقی است. بخش نهایی چیزی نیست جز مجموع هر قسمت قابل مشاهده از هر لایه ماسک. می توانیم این رفتار را با استفاده از mask-composite تغییر دهیم. در اینجا، بایدintersect (و destination-out) را برای ویژگی پیشوندی در نظر بگیریم. کد به صورت زیر در خواهد آمد:
.loader { width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; background: conic-gradient(#0000,var(--c)); mask: radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0), repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n)); -webkit-mask-composite: destination-in; mask-composite: intersect; }
کار ما با شکل تمام شده است. در اینجا فقط به انیمیشن نیاز داریم. گام بعدی ایجاد یک چرخش بی نهایت برای اسپینر است. تنها چیزی که باید به آن توجه کرد این است که از انیمیشن steps برای ایجاد توهم خط تیره ثابت و رنگ های متحرک استفاده کرده ایم. در اینجا یک تصویر برای مشاهده تفاوت ها وجود دارد:
اولی یک چرخش خطی و پیوسته شکل است (نه آن چیزی که ما می خواهیم) و دومی یک انیمیشن از هم گسسته است. در زیر کد کامل انیمیشن آمده است:
<div class="loader"></div> <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div> <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div> <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div>
.loader { --b: 10px; /* border thickness */ --n: 10; /* number of dashes*/ --g: 10deg; /* gap between dashes*/ --c: red; /* the color */ width: 100px; /* size */ aspect-ratio: 1; border-radius: 50%; padding: 1px; background: conic-gradient(#0000,var(--c)) content-box; -webkit-mask: repeating-conic-gradient(#0000 0deg, #000 1deg calc(360deg/var(--n) - var(--g) - 1deg), #0000 calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))), radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b))); mask: repeating-conic-gradient(#0000 0deg, #000 1deg calc(360deg/var(--n) - var(--g) - 1deg), #0000 calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))), radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b))); -webkit-mask-composite: destination-in; mask-composite: intersect; animation: load 1s infinite steps(var(--n)); } @keyframes load {to{transform: rotate(1turn)}}
در بالا چند تفاوت با کدی که در پیش آمده بود خواهید دید:
این ها برخی ویرایش ها برای جلوگیری از اشکال های دیداری هستند. گرادیانها در برخی موارد نتایج عجیب تولید میکنند، بنابراین برای دوری جستن از آن ها باید برخی از مقادیر را به صورت دستی تنظیم کنیم.
مانند لودر پیشین، بیایید با یک نمای کلی شروع کنیم:
برای دیدن نتیجه به این نشانی مراجعه کنید.
همان پیکربندی لودر قبلی را داریم. متغیرهای CSS که لودر را کنترل می کنند به صورت زیر هستند:
از شکل بالا می بینیم که عرض عنصر به 3 متغیر بستگی دارد. CSS آن به صورت زیر خواهد بود:
.loader { width: calc(var(--n)*(var(--s) + var(--g)) - var(--g)); height: 30px; /* use any value you want here */ padding: var(--g); border: 1px solid; }
برای تنظیم شکاف در هر طرف از padding استفاده می کنیم. سپس width (عرض) برابر با تعداد نوارها ضرب در عرض و فاصله آن ها خواهد بود. یک شکاف را حذف می کنیم زیرا برای N نوار N-1 شکاف داریم. برای ایجاد نوارها از گرادیان زیر استفاده می کنیم.
repeating-linear-gradient(90deg, currentColor 0 var(--s), #0000 0 calc(var(--s) + var(--g)) )
از 0 تا s رنگ تعریف شده و از s تا s + g یک رنگ شفاف (شکاف) است. از currentColor استفاده می کنیم که مقدار ویژگی color است. توجه داشته باشید که هیچ رنگی را در داخل border تعریف نکرده ایم بنابراین از مقدار color نیز استفاده خواهد کرد. اگر بخواهیم رنگ لودر را تغییر دهیم، فقط باید ویژگی color را تنظیم کنیم.کد تا اینجا:
.loader { width: calc(var(--n)*(var(--s) + var(--g)) - var(--g)); height: 30px; padding: var(--g); border: 1px solid; background: repeating-linear-gradient(90deg, currentColor 0 var(--s), #0000 0 calc(var(--s) + var(--g)) ) left / 100% 100% content-box no-repeat; }
از content-box استفاده میکنیم تا مطمئن شویم که گرادیان، ناحیه padding را پوشش نمیدهد. سپس اندازه معادل100% 100% و یک موقعیت سمت چپ یا left تعریف را می کنیم. نوبت به انیمیشن رسیده است. برای این لودر، اندازه پسزمینه را از 0% 100% به 100% 100% تغییر می دهیم که به معنی width گرادیان از 0% تا 100% است. مانند لودر قبلی، برای داشتن یک انیمیشن مجزا به جای یک انیمیشن پیوسته، از step استفاده می کنیم.
می توان این کار را با افزودن کد زیر انجام داد:
.loader { animation: load 1.5s steps(var(--n)) infinite; } @keyframes load { 0% {background-size: 0% 100%} }
اگر به شکل آخر دقت کنید متوجه می شوید که انیمیشن کامل نیست. حتی اگر از N استفاده کرده باشیم، یک نوار در پایان از دست داده ایم. برای غلبه بر این، باید یک مرحله اضافی اضافه کنیم. اندازه پسزمینه گرادیان خود را افزایش میدهیم تا حاوی نوارهای N+1 باشد و از steps(N+1) استفاده میکنیم. این کار ما را به کد نهایی می رساند:
.loader { width: calc(var(--n)*(var(--s) + var(--g)) - var(--g)); height: 30px; padding: var(--g); margin: 5px auto; border: 1px solid; background: repeating-linear-gradient(90deg, currentColor 0 var(--s), #0000 0 calc(var(--s) + var(--g)) ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% content-box no-repeat; animation: load 1.5s steps(calc(var(--n) + 1)) infinite; } @keyframes load { 0% {background-size: 0% 100%} }
توجه داشته باشید که عرض گرادیان برابر است با N+1 ضرب در عرض یک نوار و یک شکاف (به جای 100٪)
امیدواریم آموزش ساخت لودینگ با CSS مورد استفاده شما قرار گرفته باشد.
منبع: وب سایت freecodecamp
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.