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

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

इस पोस्ट में, मुझे कलर-अडैप्टिव, रिस्पॉन्सिव, और ऐक्सेस किए जा सकने वाले FAB कॉम्पोनेंट बनाने के बारे में अपने विचार शेयर करने हैं. डेमो आज़माएं और सोर्स देखें!

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

खास जानकारी

डेस्कटॉप की तुलना में मोबाइल पर FAB का इस्तेमाल ज़्यादा किया जाता है. हालांकि, दोनों ही प्लैटफ़ॉर्म पर इनका इस्तेमाल किया जाता है. ये प्राइमरी ऐक्शन को व्यू में रखते हैं, जिससे वे सुविधाजनक और हर जगह मौजूद होते हैं. इस यूज़र एक्सपीरियंस स्टाइल को Material UI ने लोकप्रिय बनाया था. इसके इस्तेमाल और प्लेसमेंट के बारे में सुझाव यहां मिल सकते हैं.

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

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

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

इस एलिमेंट को सामान्य <div> के तौर पर इस्तेमाल किया जा सकता है. हालांकि, आइए हम दृष्टिबाधित लोगों की मदद करें और इस कंटेनर के मकसद और कॉन्टेंट के बारे में बताने के लिए, इसे कुछ काम के एट्रिब्यूट के साथ टैग करें.

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

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

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

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

FAB को आसानी से इस्तेमाल करने के लिए, उन्हें हमेशा व्यूपोर्ट में रखा जाता है. यह position 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);
}

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

.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;
}

इस स्क्रीनशॉट में, स्टैक किए गए दो फ़्लोटिंग ऐक्शन बटन दिखाए गए हैं. इसमें सबसे ऊपर वाला बटन, सबसे नीचे वाले बटन से छोटा है.

सुलभता

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

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

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

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

ऐनिमेशन

उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, अलग-अलग तरह के ऐनिमेशन जोड़े जा सकते हैं. अन्य जीयूआई चैलेंज की तरह ही, हम कुछ कस्टम प्रॉपर्टी सेट अप करेंगे. इनसे मोशन कम करने और मोशन को पूरी तरह से दिखाने के लिए, उपयोगकर्ता के इरादे के बारे में पता चलेगा. डिफ़ॉल्ट रूप से, स्टाइल यह मान लेंगी कि उपयोगकर्ता को मोशन कम चाहिए. इसके बाद, 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);
    }
  }
}

नतीजा

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

आइए, हम अपने तरीकों में विविधता लाएं और वेब पर काॅन्टेंट पोस्ट करने के सभी तरीके जानें.

डेमो बनाएं और मुझे ट्वीट करें. इसके बाद, मैं इसे यहां कम्यूनिटी रीमिक्स सेक्शन में जोड़ दूंगा!

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

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

संसाधन