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

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

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

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

खास जानकारी

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

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

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

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

यह एलिमेंट एक सामान्य <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 से कंटेनर में मौजूद किसी भी FAB बटन के बीच स्पेस जोड़ा जाता है.

एफ़एबी बटन

कुछ बटनों को इस तरह स्टाइल करें कि वे सबके ऊपर फ़्लोट करते हुए दिखें.

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

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

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

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

इसके बाद, कुछ स्टाइल जोड़ें, ताकि एसवीजी आइकॉन स्पेस में फ़िट हो सकें.

.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" है.

ऐनिमेशन

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

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

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

नतीजा

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

आइए, अलग-अलग तरीकों का इस्तेमाल करके, वेब पर कॉन्टेंट बनाने के सभी तरीके जानें.

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

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

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

संसाधन