लोडिंग स्पिनर (या गतिविधि इंडिकेटर) से उपयोगकर्ताओं को पता चलता है कि कोई प्रोसेस चल रही है. हालांकि, इससे यह पता नहीं चलता कि प्रोसेस पूरी होने में कितना समय लगेगा. प्रोग्रेस दिखाने वाली रिंग के उलट, स्पिनर "अनिश्चित" होता है. आम तौर पर, यह गतिविधि दिखाने के लिए ऐनिमेशन का इस्तेमाल करता है.
इस गाइड में, स्पिनर को लागू करने के लिए ये तरीके अपनाए गए हैं:
- नेटिव
<progress>एलिमेंट को सिमैंटिक फ़ाउंडेशन के तौर पर इस्तेमाल करना.valueएट्रिब्यूट को शामिल न करने पर, ब्राउज़र इसे एक ऐसे प्रोग्रेस बार के तौर पर दिखाता है जिसकी वैल्यू तय नहीं होती. इससे यह पक्का होता है कि सहायक टेक्नोलॉजी, सही जानकारी दें. - कॉम्पोनेंट को
conic-gradient()से स्टाइल किया गया है, ताकि विज़ुअल "ट्रेल" बनाया जा सके. साथ ही,background-clip: border-areaसे कॉम्पोनेंट के बीच के हिस्से को खाली करके रिंग बनाई गई है. - सीएसएस ट्रांसफ़ॉर्म का इस्तेमाल करके, स्पिनर को बेहतर तरीके से ऐनिमेट करना और
prefers-reduced-motionका पालन करना, ताकि सभी उपयोगकर्ताओं को बेहतर अनुभव मिल सके.
तय समय में पूरे होने वाले टास्क को मैनेज करने के लिए, प्रोग्रेस दिखाने वाली रिंग देखें.
लागू करना
1. मार्कअप
नेटिव <progress> एलिमेंट को सिमैंटिक सोर्स ऑफ़ ट्रुथ और विज़ुअल कॉम्पोनेंट, दोनों के तौर पर इस्तेमाल करें. value एट्रिब्यूट के बिना, यह साफ़ तौर पर तय नहीं होता.
<progress aria-label="Loading" class="loading-spinner"></progress>
2. स्टाइल
नेटिव यूज़र इंटरफ़ेस (यूआई) को छिपाना
<progress> एलिमेंट को स्पिनर के तौर पर स्टाइल करने के लिए, पहले प्रोग्रेस बार के लिए डिफ़ॉल्ट ब्राउज़र स्टाइल को छिपाएं.
/* Hide native bars */
progress.loading-spinner:indeterminate::-webkit-progress-bar {
display: none;
background: none;
}
progress.loading-spinner:indeterminate::-webkit-progress-value {
display: none;
background: none;
}
progress.loading-spinner:indeterminate::-moz-progress-bar {
display: none;
background: none;
}
progress.loading-spinner:indeterminate::slider-fill {
display: none;
background: none;
}
स्पिनर रिंग और ट्रेल
स्पिनर, विज़ुअल ट्रेल बनाने के लिए conic-gradient का इस्तेमाल करता है.
@property --arc-start {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --arc-end {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
/* Use a custom property to conditionally include the dash animation */
@property --progress-dash-animation {
syntax: "*";
inherits: false;
initial-value: , progress-dash 3s ease-in-out infinite;
}
progress.loading-spinner:indeterminate {
--_from: calc(90deg + var(--arc-start, 0deg));
--_to: calc(90deg + var(--arc-end, 158deg));
--size: 40px;
--thickness: 2px;
--spinner-color: #3b82f6;
--track-color: #e2e5e7;
--spinner-duration: 1.5s;
--_used-spinner-duration: var(--spinner-duration);
--spinner-timing: linear;
position: relative;
width: var(--size);
height: var(--size);
border-radius: 50%;
appearance: none;
/* Create the fading trail with dynamic angles */
background: conic-gradient(
from var(--_from),
var(--spinner-color) calc(var(--_to) - var(--_from)),
transparent 0
)
var(--track-color);
@supports (background-clip: border-area) {
background-clip: border-area;
border: var(--thickness) solid transparent;
background-origin: border-box;
}
/* ... fallback for background-clip: border-area ... */
/* The dash animation is only included if @property is supported */
animation:
progress-spin var(--_used-spinner-duration) linear infinite
var(--progress-dash-animation, );
}
@keyframes progress-spin {
to {
rotate: 1turn;
}
}
@keyframes progress-dash {
from {
--arc-start: 0deg;
--arc-end: 3deg;
}
50% {
--arc-start: 100deg;
--arc-end: 358deg;
}
to {
--arc-start: 360deg;
--arc-end: 363deg;
}
}
मोशन से जुड़ी प्राथमिकताओं का ध्यान रखना
जिन लोगों को मोशन सेंसिटिविटी की समस्या है उन्हें तेज़ी से घूमने वाले एलिमेंट से परेशानी हो सकती है. prefers-reduced-motion मीडिया क्वेरी का हमेशा ध्यान रखें. उपयोगकर्ता की --spinner-duration वैल्यू को बदलने के लिए, इंटरनल --_used-spinner-duration प्रॉपर्टी सेट करें.
@media (prefers-reduced-motion: reduce) {
.loading-spinner {
/* Slow down the animation significantly rather than stopping it entirely,
so the user still knows that the process is active. */
--_used-spinner-duration: 6s;
}
}
फ़ॉलबैक रणनीतियां
अगर @property काम करता है, तो डैश ऐनिमेशन अपने-आप शामिल हो जाता है. इसके लिए, --progress-dash-animation प्रॉपर्टी के initial-value का इस्तेमाल किया जाता है. जिन ब्राउज़र में @property काम नहीं करता उनमें प्रॉपर्टी रजिस्ट्रेशन को अनदेखा कर दिया जाता है. साथ ही, ऐनिमेशन को सामान्य रोटेशन पर सेट कर दिया जाता है. इस फ़ॉलबैक के लिए, JavaScript की ज़रूरत नहीं है.
ऐसे ब्राउज़र जो फ़िलहाल background-clip: border-area के साथ काम नहीं करते उनके लिए, mask-image का इस्तेमाल करें, ताकि सेंटर को खाली किया जा सके.
/* Fallback: use mask-image to create the ring */
@supports not (background-clip: border-area) {
--clip-boundary: calc(100% - var(--thickness));
mask-image: radial-gradient(
farthest-side,
transparent var(--clip-boundary),
black var(--clip-boundary)
);
border: 0;
}