फ़्लोटिंग ऐक्शन बटन (एफ़एबी) कॉम्पोनेंट बनाना

रंग के हिसाब से अडैप्टिव, रिस्पॉन्सिव, और ऐक्सेस किए जा सकने वाले एफ़एबी कॉम्पोनेंट बनाने के तरीके के बारे में बुनियादी जानकारी.

इस पोस्ट में, हम आपको एफ़एबी कॉम्पोनेंट को रंग के हिसाब से बनाने, रिस्पॉन्सिव, और ऐक्सेस करने लायक एफ़एबी कॉम्पोनेंट बनाने के तरीकों के बारे में बताना चाहते हैं. डेमो आज़माएं और सोर्स देखें!

अगर आप वीडियो पसंद करते हैं, तो यहां इस पोस्ट का YouTube वर्शन दिया गया है:

खास जानकारी

डेस्कटॉप के मुकाबले मोबाइल पर एफ़एबी ज़्यादा आम हैं. हालांकि, ये दोनों ही मामलों में ज़्यादा मिलते हैं. वे प्राथमिक कार्रवाइयों को व्यू में रखते हैं, जिससे उन्हें सुविधाजनक और सभी के लिए उपलब्ध बनाया जाता है. उपयोगकर्ता अनुभव की इस स्टाइल को Material यूज़र इंटरफ़ेस (यूआई) ने मशहूर बनाया है. साथ ही, इस्तेमाल और प्लेसमेंट के बारे में उनके सुझाव यहां देखे जा सकते हैं.

एलिमेंट और स्टाइल

इन कंट्रोल के एचटीएमएल में एक कंटेनर एलिमेंट और एक या उससे ज़्यादा बटन का सेट शामिल होता है. कंटेनर, एफ़एबी को व्यूपोर्ट में रखता है और बटनों के बीच के गैप को मैनेज करता है. बटन छोटे या डिफ़ॉल्ट हो सकते हैं, जो मुख्य और दूसरी कार्रवाइयों के बीच कुछ अच्छा दिखाते हैं.

एफ़एबी कंटेनर

यह एलिमेंट एक सामान्य <div> हो सकता है, लेकिन इस तरह के कंटेनर के मकसद और कॉन्टेंट को समझाने के लिए, इन एलिमेंट का इस्तेमाल कर सकते हैं.

एफ़एबी मार्कअप

स्टाइल में जोड़ने के लिए, सीएसएस के लिए .fabs क्लास से शुरू करें. इसके बाद, role="group" और aria-label को जोड़ें, ताकि यह सिर्फ़ एक सामान्य कंटेनर न हो, बल्कि यह नाम और काम का हो.

<div class="fabs" role="group" aria-label="Floating action buttons">
  <!-- buttons will go here -->
</div>

एफ़एबी स्टाइल

एफ़एबी को सुविधाजनक बनाने के लिए, वे हमेशा व्यूपोर्ट में बने रहते हैं. यह स्थिति fixed के लिए इस्तेमाल का एक अच्छा उदाहरण है. मैंने इस व्यूपोर्ट पोज़िशन में inset-block और inset-inline का इस्तेमाल करने का विकल्प चुना है, ताकि रैंक, उपयोगकर्ता के दस्तावेज़ मोड के हिसाब से हो. जैसे, दाएं से बाएं या बाएं से दाएं. कस्टम प्रॉपर्टी का इस्तेमाल दोहराव को रोकने और व्यूपोर्ट के निचले और किनारों से बराबर दूरी पक्का करने के लिए भी किया जाता है:

.fabs {
  --_viewport-margin: 2.5vmin;

  position: fixed;
  z-index: var(--layer-1);

  inset-block: auto var(--_viewport-margin);
  inset-inline: auto var(--_viewport-margin);
}

इसके बाद, कंटेनर डिसप्ले flex दिया जाएगा और उसके लेआउट की दिशा बदलकर column-reverse की जाएगी. इससे बच्चों का स्टैक एक-दूसरे (कॉलम) के ऊपर हो जाता है और उनके दिखने का क्रम भी उलटा हो जाता है. फ़ोकस करने लायक पहले एलिमेंट को सबसे ऊपर के बजाय बॉटम एलिमेंट बनाने का असर होता है. एचटीएमएल दस्तावेज़ के हिसाब से फ़ोकस सामान्य तौर पर वहीं पर होता है. विज़ुअल ऑर्डर में बदलाव करने से, सामान्य तौर पर दिखने वाले उपयोगकर्ताओं और कीबोर्ड इस्तेमाल करने वालों को एक जैसा अनुभव मिलता है. ऐसा इसलिए, क्योंकि मुख्य कार्रवाई की स्टाइल, मिनी बटन से बड़ी होती है. इसका मतलब है कि उपयोगकर्ता देख सकते हैं कि यह एक प्राइमरी ऐक्शन है और कीबोर्ड के उपयोगकर्ता इसे सोर्स के पहले आइटम के तौर पर फ़ोकस करेंगे.

स्क्रीन पर दो एफ़एबी बटन दिख रहे हैं. इनके ग्रिड लेआउट को ओवरले करने वाले DevTools दिखाए गए हैं. इन एट्रिब्यूट के बीच के अंतर को धारीदार पैटर्न में दिखाता है. साथ ही, यह उनकी तय की गई ऊंचाई और चौड़ाई भी दिखाता है.

.fabs {
  …

  display: flex;
  flex-direction: column-reverse;
  place-items: center;
  gap: var(--_viewport-margin);
}

सेंटरिंग को place-items की मदद से हैंडल किया जाता है. साथ ही, gap कंटेनर में रखे गए एफ़एबी बटन के बीच स्पेस जोड़ता है.

एफ़एबी बटन

अब कुछ बटनों को ऐसे स्टाइल में ढालें कि वे हर चीज़ के ऊपर फ़्लोट कर रहे हों.

डिफ़ॉल्ट एफ़एबी

स्टाइल करने के लिए, पहला बटन डिफ़ॉल्ट बटन होता है. यह सभी एफ़एबी बटनों के बेस के तौर पर काम करेगा. बाद में, हम ऐसा वैरिएंट बनाएंगे जो इनमें से कम से कम बुनियादी स्टाइल में बदलाव करते हुए विकल्प के तौर पर दिखेगा.

एफ़एबी मार्कअप

<button> एलिमेंट सही विकल्प है. हम इसे बेस से शुरू करेंगे, क्योंकि इसमें माउस, टच, और कीबोर्ड इस्तेमाल करने का बेहतरीन अनुभव मिलता है. इस मार्कअप का सबसे अहम पहलू यह है कि aria-hidden="true" की मदद से, स्क्रीन रीडर इस्तेमाल करने वालों से आइकॉन को छिपा दिया जाए. साथ ही, इसमें ज़रूरी लेबल टेक्स्ट को खुद <button> मार्कअप में जोड़ा जा सकता है. इन मामलों में लेबल जोड़ते समय, मुझे title जोड़ना भी पसंद है. इससे माउस का इस्तेमाल करने वाले लोगों को यह जानकारी मिलती है कि आइकॉन में क्या जानकारी शेयर की जा रही है.

<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>

एफ़एबी स्टाइल

सबसे पहले, बटन को मज़बूत परछाई वाले पैड वाले गोल बटन में बदलें, क्योंकि ये बटन की पहली परिभाषित सुविधाएं हैं:

.fab {
  --_size: 2rem;

  padding: calc(var(--_size) / 2);
  border-radius: var(--radius-round);
  aspect-ratio: 1;
  box-shadow: var(--shadow-4);
}

अब रंग जोड़ते हैं. हम उस रणनीति का इस्तेमाल करेंगे जो हमने पहले जीयूआई चैलेंज में इस्तेमाल की है. कस्टम प्रॉपर्टी का साफ़ नाम वाला ऐसा सेट बनाएं जिसमें हल्के और गहरे रंग शामिल हों. इसके बाद, एक ऐसी अडैप्टिव कस्टम प्रॉपर्टी बनाएं जो उपयोगकर्ता की पसंद के रंगों के लिए, लाइट या डार्क वैरिएबल पर सेट होगी:

.fab {
  …

  /* light button and button hover */
  --_light-bg: var(--pink-6);
  --_light-bg-hover: var(--pink-7);

  /* dark button and button hover */
  --_dark-bg: var(--pink-4);
  --_dark-bg-hover: var(--pink-3);

  /* adaptive variables set to light by default */
  --_bg: var(--_light-bg);

  /* static icon colors set to the adaptive foreground variable */
  --_light-fg: white;
  --_dark-fg: black;
  --_fg: var(--_light-fg);

  /* use the adaptive properties on some styles */
  background: var(--_bg);
  color: var(--_fg);

  &:is(:active, :hover, :focus-visible) {
    --_bg: var(--_light-bg-hover);

    @media (prefers-color-scheme: dark) {
      --_bg: var(--_dark-bg-hover);
    }
  }

  /* if users prefers dark, set adaptive props to dark */
  @media (prefers-color-scheme: dark) {
    --_bg: var(--_dark-bg);
    --_fg: var(--_dark-fg);
  }
}

इसके बाद, कुछ स्टाइल जोड़ें, ताकि SVG आइकॉन सही जगह पर दिखें.

.fab {
  …

  & > svg {
    inline-size: var(--_size);
    block-size: var(--_size);
    stroke-width: 3px;
  }
}

आखिर में, बटन से टैप हाइलाइट हटाएं, क्योंकि हमने इंटरैक्शन के लिए अपना खुद का विज़ुअल फ़ीडबैक जोड़ा है:

.fab {
  -webkit-tap-highlight-color: transparent;
}

मिनी एफ़एबी

इस सेक्शन का मकसद, एफ़एबी बटन के लिए एक वैरिएंट बनाना है. कुछ एफ़एबी को डिफ़ॉल्ट कार्रवाई से छोटा करके, हम उस कार्रवाई को बढ़ावा दे सकते हैं जिसे उपयोगकर्ता सबसे ज़्यादा बार करता है.

मिनी एफ़एबी मार्कअप

एचटीएमएल, एफ़एबी की तरह ही है, लेकिन हम इसमें ".mini" क्लास जोड़ते हैं, ताकि सीएसएस को वैरिएंट में बेहतर तरीके से शामिल किया जा सके.

<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
मिनी एफ़एबी स्टाइल

कस्टम प्रॉपर्टी का इस्तेमाल करने की वजह से, सिर्फ़ --_size वैरिएबल में बदलाव करने की ज़रूरत है.

.fab.mini {
  --_size: 1.25rem;
}

एक स्क्रीनशॉट, जिसमें दो फैब बटन हैं और सबसे ऊपर मौजूद बटन, सबसे नीचे मौजूद बटन से छोटे हैं.

सुलभता

एफ़एबी की मदद से सुलभता के लिए, पेज के कीबोर्ड फ़्लो में प्लेसमेंट तय करना ज़रूरी है. इस डेमो में सिर्फ़ एफ़एबी हैं. कीबोर्ड के क्रम और फ़्लो के मामले में इससे मुकाबला करने के लिए कुछ नहीं है. इसका मतलब है कि इसमें कीबोर्ड का बेहतर फ़्लो दिखाने का मौका नहीं है. ऐसी स्थिति में जब फ़ोकस करने के लिए कई एलिमेंट हों, तो हमारा सुझाव है कि आप इस बारे में सोचें कि एफ़एबी बटन फ़्लो में जाने पर उपयोगकर्ता को कहां पर आना चाहिए.

कीबोर्ड इंटरैक्शन का डेमो

जब उपयोगकर्ता एफ़एबी कंटेनर पर फ़ोकस कर रहा होता है, तब हमने role="group" और aria-label="floating action buttons" को पहले ही जोड़ दिया होता है. इनसे स्क्रीन रीडर का इस्तेमाल करने वाले लोगों को कॉन्टेंट के बारे में जानकारी मिलती है कि उन्होंने किस चीज़ पर फ़ोकस किया है. रणनीति बनाकर, मैंने डिफ़ॉल्ट एफ़एबी को पहले रखा है, ताकि लोगों को मुख्य कार्रवाई पहले दिखे. इसके बाद, flex-direction: column-reverse; का इस्तेमाल करके, नीचे दिए मुख्य बटन को विज़ुअल तौर पर क्रम से लगाएं. यह बटन, उपयोगकर्ता की उंगलियों के पास मौजूद होना चाहिए, ताकि इसे आसानी से ऐक्सेस किया जा सके. यह एक अच्छी बात है, क्योंकि इसमें डिफ़ॉल्ट बटन साफ़ तौर पर दिखता है. साथ ही, कीबोर्ड इस्तेमाल करने वालों के लिए भी सबसे पहला बटन है. इससे उन्हें एक जैसा अनुभव मिलता है.

आखिर में, अपने आइकॉन को स्क्रीन रीडर इस्तेमाल करने वालों से छिपाना न भूलें. साथ ही, पक्का करें कि आपने उन्हें बटन के लिए एक लेबल दिया हो, ताकि यह कोई रहस्य न रहे. यह काम, <svg> पर aria-hidden="true" और <button> पर aria-label="Some action" के साथ एचटीएमएल में पहले ही किया जा चुका है.

Animation

उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, कई तरह के ऐनिमेशन जोड़े जा सकते हैं. अन्य GUI चैलेंज की तरह, हम कुछ कस्टम प्रॉपर्टी सेट अप करेंगे, ताकि मोशन अनुभव को कम करने और मोशन का पूरा अनुभव पाने के मकसद को पूरा किया जा सके. डिफ़ॉल्ट रूप से, स्टाइल को यह माना जाएगा कि उपयोगकर्ता कम मोशन चाहता है. इसके बाद, prefers-reduced-motion मीडिया क्वेरी का इस्तेमाल करके, ट्रांज़िशन वैल्यू को फ़ुल मोशन में बदल दिया जाएगा.

कस्टम प्रॉपर्टी के साथ कम मोशन वाली रणनीति का इस्तेमाल करना

इन सीएसएस में तीन कस्टम प्रॉपर्टी बनाई गई हैं: --_motion-reduced, --_motion-ok, और --_transition. उपयोगकर्ता की पसंद के आधार पर, पहले दो होल्ड के हिसाब से सही ट्रांज़िशन और आखिरी वैरिएबल --_transition को क्रमश: --_motion-reduced या --_motion-ok पर सेट किया जाएगा.

.fab {
  /* box-shadow and background-color can safely be transitioned for reduced motion users */
  --_motion-reduced:
    box-shadow .2s var(--ease-3),
    background-color .3s var(--ease-3);

  /* add transform and outline-offset for users ok with motion */
  --_motion-ok:
    var(--_motion-reduced),
    transform .2s var(--ease-3),
    outline-offset 145ms var(--ease-2);

  /* default the transition styles to reduced motion */
  --_transition: var(--_motion-reduced);

  /* set the transition to our adaptive transition custom property*/
  transition: var(--_transition);

  /* if motion is ok, update the adaptive prop to the respective transition prop */
  @media (prefers-reduced-motion: no-preference) {
    --_transition: var(--_motion-ok);
  }
}

ऊपर बताए गए तरीके से, box-shadow, background-color, transform, और outline-offset में किए गए बदलावों को ट्रांसफ़र किया जा सकता है. इससे, उपयोगकर्ता को यूज़र इंटरफ़ेस (यूआई) को बेहतर सुझाव मिलता है कि उसका इंटरैक्शन मिल गया है.

इसके बाद, थोड़ा-बहुत अडजस्ट करके, :active स्टेट को और बेहतर बनाएं translateYइससे बटन को दबाया जाता है और उसमें एक अच्छा इफ़ेक्ट मिलता है:

.fab {
  …

  &:active {
    @media (prefers-reduced-motion: no-preference) {
      transform: translateY(2%);
    }
  }
}

इसके बाद, बटन में मौजूद SVG आइकॉन में किए गए किसी भी बदलाव का ट्रांज़िशन करें:

.fab {
  …

  &[data-icon="plus"]:hover > svg {
    transform: rotateZ(.25turn);
  }

  & > svg {
    @media (prefers-reduced-motion: no-preference) {
      will-change: transform;
      transition: transform .5s var(--ease-squish-3);
    }
  }
}

नतीजा

अब आपको पता चल गया है कि मैंने इसे कैसे किया, तो आप कैसी होंगी‽ 🙂

चलिए, इसे अलग-अलग तरीके से समझें और वेब पर सभी के काम करने के तरीके सीखें.

एक डेमो तैयार करें, मुझे ट्वीट करें वाले लिंक, और मैं उसे नीचे दिए गए कम्यूनिटी रीमिक्स सेक्शन में जोड़ दूंगी!

कम्यूनिटी रीमिक्स

फ़िलहाल, यहां कुछ भी नहीं है.

रिसॉर्स