إنشاء مكوِّن متعدد الاختيارات

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

في هذه المشاركة، أود أن أشاركك في التفكير في طريقة لإنشاء مكون تحديد متعدد. ندعوك لبدء العرض التوضيحي.

عرض توضيحي

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

نظرة عامة

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

التفاعلات

والهدف من ذلك هو تمكين التمرير السريع لخيارات التصفية لجميع المستخدمين أنواع مدخلات متفاوتة. سيتم تقديم هذا مع نموذج قابل للتكيّف والاستجابة زوج من المكونات. شريط جانبي تقليدي لمربعات الاختيار لسطح المكتب ولوحة المفاتيح وقارئات الشاشة، و<select multiple> لمستخدمي اللمس.

لقطة شاشة للمقارنة تعرض إضاءة وإضاءة داكنة في سطح المكتب مع شريط جانبي
وخانات الاختيار في مقابل نظامي التشغيل iOS وAndroid للجوّال باستخدام عنصر تحديد متعدد.

يؤدي هذا القرار باستخدام تحديد متعدد مدمج لللمس، وليس لسطح المكتب، إلى توفير العمل وإنشاء العمل، ولكني أعتقد أنه يوفر تجارب مناسبة ذات ديون رمزية أقل من إنشاء التجربة سريعة الاستجابة بأكملها في مكون واحد.

اللمس

يعمل مكوِّن اللمس على توفير مساحة ويساعد على دقة تفاعل المستخدم في الجوّال. يوفر مساحة عن طريق تصغير شريط جانبي كامل من مربعات الاختيار إلى <select> تجربة لمس مركّبة مدمجة. ويساعد ذلك في دقة الإدخال من خلال عرض تجربة تراكب لمسة كبيرة يوفرها النظام.

حاسمة
معاينة لقطة شاشة للعنصر المتعدد الاختيارات في Chrome على أجهزة Android وiPhone
جهاز iPad يشتمل كل من iPad وiPhone على وضع تفعيل الخيارات المتعددة، ويحصل كل منهما على
تجربة فريدة محسنة لحجم الشاشة.

لوحة المفاتيح وجهاز تحكّم في الألعاب

يوجد أدناه شرح حول كيفية استخدام <select multiple> من لوحة المفاتيح.

ولا يمكن تصميم مجموعة الخيارات المتعددة المدمجة هذه ويتم توفيرها فقط في مساحة صغيرة تخطيط غير مناسب لتقديم الكثير من الخيارات. انظر كيف يمكنك ترى اتساع الخيارات في هذا المربع الصغير؟ وعلى الرغم من أنه يمكنك تغيير حجمه، إلا أنه لا تزال غير قابلة للاستخدام مثل الشريط الجانبي لمربعات الاختيار.

Markup

وسيتم تضمين كلا المكوّنَين في عنصر <form> نفسه. نتائج في هذا النموذج، سواءٌ كانت مربعات الاختيار أم تحديد متعدد، ستتم مراقبته واستخدامه تصفية الشبكة، ولكن يمكن أيضًا إرسالها إلى أحد الخوادم.

<form>

</form>

مكوّن مربّعات الاختيار

ينبغي أن يتم التفاف مجموعات مربعات الاختيار في <fieldset> العنصر وإعطاء <legend> عندما يتم هيكلة HTML بهذه الطريقة، فإن برامج قراءة الشاشة الإجراء FormData لفهم علاقة العناصر تلقائيًا.

<form>
  <fieldset>
    <legend>New</legend>
    … checkboxes …
  </fieldset>
</form>

مع تنفيذ عملية التجميع، أضِف <label> و<input type="checkbox"> لما يلي: لكل عامل من عوامل التصفية. اخترتُ التفاف البيانات في <div> بحيث تكون السمة gap في CSS يمكننا المباعدة بينها بالتساوي والحفاظ على المحاذاة عندما تصبح التسميات متعددة الأسطر.

<form>
  <fieldset>
    <legend>New</legend>
    <div>
      <input type="checkbox" id="last 30 days" name="new" value="last 30 days">
      <label for="last 30 days">Last 30 Days</label>
    </div>
    <div>
      <input type="checkbox" id="last 6 months" name="new" value="last 6 months">
      <label for="last 6 months">Last 6 Months</label>
    </div>
   </fieldset>
</form>

لقطة شاشة مع تراكب إعلامي للوسيلة الإيضاحية
  عناصر مجموعة الحقول، تعرض اللون واسم العنصر.

المكوِّن <select multiple>

إنّ السمة التي نادرًا ما يتم استخدامها في العنصر <select> هي multiple عند استخدام السمة مع عنصر <select>، يُسمح للمستخدم بما يلي: واختيار الكثير من القائمة. يشبه ذلك تغيير التفاعل من قائمة راديو إلى قائمة مربّعات اختيار.

<form>
  <select multiple="true" title="Filter results by category">
    …
  </select>
</form>

لتصنيف المجموعات وإنشائها داخل <select>، استخدِم <optgroup> ونعطيه السمة labelوالقيمة. هذا العنصر والسمة مشابهة للعنصرين <fieldset> و<legend>.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      …
    </optgroup>
  </select>
</form>

الآن أضف <option> وعناصر عامل التصفية.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      <option value="last 30 days">Last 30 Days</option>
      <option value="last 6 months">Last 6 Months</option>
    </optgroup>
  </select>
</form>

لقطة شاشة لعرض سطح المكتب لعنصر متعدّد الاختيار

تتبع الإدخالات باستخدام العدادات لإبلاغ التكنولوجيا المساعدة

الحالة الدور في تجربة المستخدم هذه لتتبع إجمالي عوامل تصفية لقارئات الشاشة والتقنيات المساعدة الأخرى. الفيديو على YouTube يوضح الميزة. يبدأ الدمج بـ HTML والسمة role="status"

<div role="status" class="sr-only" id="applied-filters"></div>

سيقرأ هذا العنصر التغييرات التي يتم إجراؤها على المحتوى بصوت عالٍ. يمكننا تحديث المحتوى باستخدام CSS العدادات عندما يتفاعل المستخدمون مع مربعات الاختيار. للقيام بذلك، نحتاج أولاً إلى إنشاء للعداد يحمل اسمًا على العنصر الأصلي للمدخلات وعنصر الحالة.

aside {
  counter-reset: filters;
}

سيكون العدد تلقائيًا 0، وهو أمر رائع، إذ لا يوجد :checked في افتراضيًا في هذا التصميم.

بعد ذلك، لزيادة العدّاد الذي تم إنشاؤه حديثًا، سنستهدِف العناصر الثانوية العنصر <aside> الذي يمثل :checked. وعندما يغير المستخدم حالة المدخلات، سيتم احتساب عدّاد filters.

aside :checked {
  counter-increment: filters;
}

أصبحت خدمة CSS على دراية بالعدد العام لواجهة مستخدم مربّع الاختيار ودور الحالة العنصر فارغ وينتظر قيمًا. نظرًا لأن CSS تحافظ على العدد في الذكرى، counter() بالوصول إلى القيمة من الزائف العنصر:

aside #applied-filters::before {
  content: counter(filters) " filters ";
}

سيعلن HTML لعنصر دور الحالة الآن عن "فلترين". إلى الشاشة قارئ البطاقات. هذه بداية جيدة، ولكن يمكننا القيام بعمل أفضل، مثل مشاركة حساب النتائج التي تم تحديث الفلاتر لها. وسننفذ هذا الإجراء باستخدام JavaScript، حيث خارج ما يمكن للعدادات القيام به.

لقطة شاشة لقارئ الشاشة في نظام التشغيل MacOS توضّح عدد الفلاتر النشطة

إثارة الفضول

كانت خوارزمية العدّادات رائعة باستخدام CSS. nesting-1، حيث تمكّنت من وضع جميع بشكل منطقي في كتلة واحدة. يمكن حملها بسهولة ومركزية للقراءة والتحديث.

aside {
  counter-reset: filters;

  & :checked {
    counter-increment: filters;
  }

  & #applied-filters::before {
    content: counter(filters) " filters ";
  }
}

التنسيقات

يصف هذا القسم التخطيطات بين المكونين. معظم وأنماط التخطيط لمكون مربع الاختيار لسطح المكتب.

النموذج

لتحسين الوضوح وسهولة القراءة للمستخدمين، يتم منح النموذج حدًا أقصى بعرض 30 حرفًا، مع ضبط عرض الخط البصري لكل منها تصنيف الفلتر. يستخدم النموذج تنسيق الشبكة والسمة gap لتباعد مجموعات الحقول.

form {
  display: grid;
  gap: 2ch;
  max-inline-size: 30ch;
}

العنصر <select>

تستهلك كل من قائمة التصنيفات ومربعات الاختيار مساحة كبيرة على الهاتف المحمول. وبالتالي، يتحقّق التنسيق لمعرفة جهاز التأشير الأساسي للمستخدم المطلوب تغييره تجربة اللمس.

@media (pointer: coarse) {
  select[multiple] {
    display: block;
  }
}

تشير القيمة coarse إلى أنّ المستخدم لن يتمكّن من التفاعل مع. الشاشة بكميات عالية من الدقة مع جهاز الإدخال الأساسي. في جهاز جوّال، تكون قيمة المؤشر غالبًا coarse، باعتبارها التفاعل الأساسي هو اللمس. على أجهزة الكمبيوتر المكتبي، غالبًا ما تكون قيمة المؤشر fine لأنّها شائعة. توصيل ماوس أو جهاز إدخال آخر عالي الدقة.

المجموعات

يكون التنسيق التلقائي لـ <fieldset> مع <legend> فريدًا:

لقطة شاشة للأنماط التلقائية لمجموعة حقول ووسيلة إيضاح.

في العادة، لتباعد العناصر الفرعية، أستخدم السمة gap، ولكن السمة الفريدة يؤدي تحديد موضع <legend> إلى صعوبة إنشاء مجموعة متباعدة بشكل متساوٍ الأطفال. بدلاً من gap، يستخدم الشقيق المجاور أداة اختيار يتم استخدام margin-block-start.

fieldset {
  padding: 2ch;

  & > div + div {
    margin-block-start: 2ch;
  }
}

ويؤدي هذا إلى تخطي <legend> من تعديل المساحة من خلال استهداف <div> أطفال.

لقطة شاشة تعرض مسافة الهوامش بين الإدخالات وليس وسيلة الإيضاح.

تصنيف الفلتر ومربّع الاختيار

عنصر ثانوي مباشر لـ <fieldset> وفي حدود عرض النموذج كحد أقصى 30ch، قد يلتف نص التصنيف إذا كان طويلاً جدًا. التفاف النص أمر رائع، لكن عدم الاتساق بين النص ومربع الاختيار. يعد Flexbox مثاليًا لهذا.

fieldset > div {
  display: flex;
  gap: 2ch;
  align-items: baseline;
}
لقطة شاشة توضح كيفية توافق علامة الاختيار مع
    السطر الأول من النص في سيناريو التفاف متعدد الأسطر.
استمتِع بالمزيد من اللعب في Codepen.

الشبكة المتحركة

يتم تنفيذ الرسم المتحرك للتنسيق بواسطة Isotope. حاسمة مكون إضافي فعال وفعال للفرز والتصفية التفاعلية.

JavaScript

بالإضافة إلى المساعدة في تنظيم شبكة جذابة وتفاعلية، تتوفر فيها لغة JavaScript تُستخدم في صقل بعض الحواف الخشنة.

ضبط البيانات التي أدخلها المستخدم

يحتوي هذا التصميم على نموذج واحد بطريقتين مختلفتين لتقديم المدخلات، وهي يجب عدم تسلسل نَفْس باستخدام بعض JavaScript، يمكننا تسوية البيانات.

لقطة شاشة لوحدة تحكّم JavaScript في &quot;أدوات مطوري البرامج&quot;
  تعرض الهدف ونتائج البيانات التي تمت تسويتها.

اخترتُ محاذاة بنية بيانات عنصر <select> مع مربّعات الاختيار المجمّعة. البنية. للقيام بذلك، input تتم إضافة أداة معالجة الحدث إلى العنصر <select>، وعندها تتم selectedOptions تعيينها.

document.querySelector('select').addEventListener('input', event => {
  // make selectedOptions iterable then reduce a new array object
  let selectData = Array.from(event.target.selectedOptions).reduce((data, opt) => {
    // parent optgroup label and option value are added to the reduce aggregator
    data.push([opt.parentElement.label.toLowerCase(), opt.value])
    return data
  }, [])
})

يمكنك الآن إرسال النموذج بأمان، أو إرشاد Isotope في حالة هذا العرض التوضيحي بشأن ما تتم تصفيته.

إنهاء عنصر دور الحالة

يحتسب العنصر عدد الفلاتر فقط ويعلن عنه بناءً على مربع الاختيار التفاعل ولكنني شعرت أنها فكرة جيدة أن تشارك أيضًا عدد والتأكد من احتساب خيارات عناصر <select> أيضًا.

انعكاس اختيار العنصر <select> في counter()

في قسم تسوية البيانات، تم بالفعل إنشاء مستمع عند الإدخال. علامة @ في نهاية هذه الدالة، عدد الفلاتر المختارة وعدد النتائج لهذه الفلاتر. يمكن تمرير القيم إلى عنصر الدور الخاص بالولاية هكذا.

let statusRoleElement = document.querySelector('#applied-filters')
statusRoleElement.style.counterSet = selectData.length

تظهر النتائج في العنصر role="status"

:checked توفر طريقة مدمجة لتمرير عدد الفلاتر المحددة إلى عنصر دور الحالة، ولكنه يفتقر إلى رؤية لعدد النتائج التي تمت تصفيتها. بإمكان جافا سكريبت مراقبة التفاعل مع مربعات الاختيار وبعد تصفية الشبكة، أضف textContent كما فعل العنصر <select>.

document
  .querySelector('aside form')
  .addEventListener('input', e => {
    // isotope demo code
    let filterResults = IsotopeGrid.getFilteredItemElements().length
    document.querySelector('#applied-filters').textContent = `giving ${filterResults} results`
})

وبالتعاون، يُكمل هذا العمل الإشعار "فلتران يقدّمان 25 نتيجة".

لقطة شاشة لقارئ الشاشة في نظام التشغيل MacOS للإعلان عن النتائج

سيتم الآن تسليم خبرتنا الممتازة في استخدام التكنولوجيا المساعدة إلى جميع المستخدمين، بصرف النظر عن طريقة تفاعلهم معها.

الخاتمة

الآن بعد أن تعرّفت على كيفية إجراء ذلك، كيف يمكنك‽ 🙂

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

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

ما من محتوى جديد حتى الآن.