إنشاء مكون زر الإجراء العائم (FAB)

نظرة عامة أساسية حول كيفية إنشاء مكوّنات زر الإجراء العائم متجاوبة وسهلة الاستخدام ومتوافقة مع الألوان

في هذه المشاركة، أريد أن أشارك أفكاري حول كيفية إنشاء مكوّنات زر إجراء عائم (FAB) تتكيّف مع الألوان وتستجيب وتتسم بإمكانية الوصول. جرِّب العرض التوضيحي واطّلِع على المصدر.

إذا كنت تفضّل مشاهدة فيديو، إليك نسخة من هذا المنشور على YouTube:

نظرة عامة

تُستخدَم أزرار الإجراء العائم بشكل أكبر على الأجهزة الجوّالة مقارنةً بأجهزة الكمبيوتر، ولكنّها شائعة في كلتا الحالتين. وتُبقي هذه الأزرار الإجراءات الأساسية في مرمى البصر، ما يجعلها سهلة الاستخدام ومتاحة في كل مكان. وقد اشتهر هذا الأسلوب في تجربة المستخدم بفضل Material UI، ويمكنك الاطّلاع هنا على اقتراحاتهم بشأن الاستخدام والموضع.

العناصر والأنماط

يتضمّن رمز HTML لعناصر التحكّم هذه عنصر حاوية ومجموعة من زر واحد أو أكثر. يضع الحاوية أزرار الإجراءات العائمة ضمن إطار العرض وتدير فجوة بين الأزرار. يمكن أن تكون الأزرار صغيرة أو تلقائية، ما يتيح بعض التنوّع بين الإجراءات الأساسية والثانوية.

حاوية زر الإجراء العائم

يمكن أن يكون هذا العنصر <div> عاديًا، ولكن لنقدّم خدمة للمستخدمين المكفوفين، سنضيف إليه بعض السمات المفيدة لتوضيح الغرض من هذا الحاوية ومحتواها.

ترميز أزرار الإجراءات العائمة

ابدأ بفئة .fabs لربط CSS بالنمط، ثم أضِف role="group" وaria-label حتى لا يكون مجرد حاوية عامة، بل يكون له اسم وغرض.

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

نمط أزرار الإجراءات الرئيسية

لكي تكون أزرار الإجراء العائم سهلة الاستخدام، يجب أن تبقى ضمن إطار العرض في جميع الأوقات. هذه حالة استخدام رائعة للدالة 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. يؤدي ذلك إلى ترتيب العناصر الفرعية فوق بعضها البعض (في عمود) وعكس ترتيبها المرئي. ويؤدي ذلك إلى جعل العنصر الأول الذي يمكن التركيز عليه هو العنصر السفلي بدلاً من العنصر العلوي، وهو الموضع الذي ينتقل إليه التركيز عادةً وفقًا لمستند HTML. يؤدي عكس الترتيب المرئي إلى توحيد التجربة للمستخدمين المبصرين ومستخدمي لوحة المفاتيح، لأنّ تصميم الإجراء الأساسي على أنّه أكبر من الأزرار الصغيرة يشير إلى المستخدمين المبصرين بأنّه إجراء أساسي، وسيركّز مستخدمو لوحة المفاتيح على هذا الإجراء باعتباره العنصر الأول في المصدر.

يظهر زرّان عائمَان مع أداة 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);
  }
}

بعد ذلك، أضِف بعض الأنماط لمساعدة رموز SVG في ملء المساحة.

.fab {
  

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

أخيرًا، أزِل التمييز عند النقر من الزر لأنّنا أضفنا ملاحظات مرئية خاصة بنا بشأن التفاعل:

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

زر الإجراء العائم المصغّر

الهدف من هذا القسم هو إنشاء صيغة مختلفة لزر الإجراء العائم. من خلال تصغير حجم بعض أزرار الإجراءات العائمة مقارنةً بالإجراء التلقائي، يمكننا الترويج للإجراء الذي ينفّذه المستخدم في معظم الأحيان.

Mini FAB markup

يكون رمز HTML هو نفسه رمز زر الإجراء العائم، ولكن نضيف الفئة ".mini" لمنح CSS إمكانية الوصول إلى المتغير.

<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; لترتيب الزر الأساسي بشكل مرئي في الأسفل، بالقرب من أصابع المستخدمين لتسهيل الوصول إليه. وهذا أمر جيد لأنّ الزر التلقائي بارز بصريًا وهو أيضًا أول زر يظهر لمستخدمي لوحة المفاتيح، ما يمنحهم تجارب مشابهة جدًا.

أخيرًا، لا تنسَ إخفاء الرموز عن مستخدمي برامج قراءة الشاشة والتأكّد من توفير تصنيف للزر حتى لا يكون غامضًا. تم إجراء ذلك في رمز HTML باستخدام aria-hidden="true" في <svg> وaria-label="Some action" في <button>.

Animation

يمكن إضافة أنواع مختلفة من الرسوم المتحركة لتحسين تجربة المستخدم. كما هو الحال في تحديات واجهة المستخدم الرسومية الأخرى، سنضبط بعض الخصائص المخصّصة لتحديد الغرض من تجربة الحركة المخفَّضة وتجربة الحركة الكاملة. بشكل تلقائي، ستفترض الأنماط أنّ المستخدم يريد تقليل الحركة، ثم سيتم استخدام طلب البحث عن الوسائط prefers-reduced-motion لتبديل قيمة الانتقال إلى الحركة الكاملة.

استراتيجية الحدّ من الحركة مع سمات مخصّصة

يتم إنشاء ثلاث خصائص مخصّصة في CSS التالي: --_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);
    }
  }
}

الخاتمة

بعد أن عرفت كيف فعلتُ ذلك، كيف ستفعل أنت ذلك؟ 🙂

لنستكشف الطرق المختلفة لإنشاء مواقع إلكترونية على الويب.

يمكنك إنشاء عرض توضيحي، إرسال تغريدة إليّ تتضمّن رابطًا إليه، وسأضيفه إلى قسم "ريمكسات من المنتدى" أدناه.

ريمكسات من إنشاء المنتدى

ما مِن عناصر للاطّلاع عليها هنا حتى الآن.

الموارد