نظرة على بعض الطرق المفيدة والمبتكرة لتنسيق قائمة
ما الذي يتبادر إلى ذهنك عندما تفكر في قائمة؟ ولعلّ أبسط مثال على ذلك هو قائمة التسوّق، وهي أبسط القوائم، وهي مجموعة من السلع بدون ترتيب معيّن. ولكننا نستخدم القوائم بجميع أنواع الطرق على الويب. مجموعة من الحفلات الموسيقية القادمة في مكان معيّن؟ على الأرجح قائمة. هل عملية الحجز تتضمّن خطوات متعددة؟ من المحتمل أن تكون قائمة. هل تريد إنشاء معرض صور؟ ويمكن اعتبار ذلك أيضًا قائمة بالصور التي تتضمّن مقاطع ترجمة وشرح.
في هذه المقالة، سنوضّح أنواع قوائم HTML المختلفة المتاحة لنا على الويب وحالات استخدامها، بما في ذلك بعض السمات التي قد لا تكون مألوفة لك. سنلقي أيضًا نظرة على بعض الطرق المفيدة والمبتكرة لتطبيق أنماط CSS عليها.
حالات استخدام القائمة
يجب استخدام عنصر قائمة HTML عندما تحتاج إلى تجميع العناصر بشكل دلالي. ستُعلم التكنولوجيات المساعِدة (مثل برامج قراءة الشاشة) المستخدم بوجود قائمة وعدد العناصر. على سبيل المثال، إذا كنت تفكر في شبكة من المنتجات على موقع تسوّق، سيكون من المفيد جدًا معرفة هذه المعلومات. لذلك، قد يكون استخدام عنصر قائمة خيارًا جيدًا.
أنواع القوائم
في ما يتعلق بالترميز، يتوفّر لنا خيار من بين ثلاثة عناصر قوائم مختلفة:
- قائمة بدون ترتيب
- قائمة مع ترتيب
- قائمة الوصف
يعتمد اختيار الطريقة على حالة الاستخدام.
قائمة بدون ترتيب (ul)
يكون عنصر القائمة غير المُرتّبة (<ul>
) مفيدًا للغاية عندما لا تتطابق العناصر في القائمة مع أي ترتيب معيّن. سيتم عرض هذا تلقائيًا كقائمة بنقاط. على سبيل المثال، قائمة التسوّق، حيث لا يهمّ الترتيب.
ومن الأمثلة الأكثر شيوعًا على الويب قائمة التنقّل. عند إنشاء قائمة، من الممارسات الجيدة تضمين ul
في عنصر nav
وتحديد القائمة باستخدام تصنيف، وذلك لمساعدة التكنولوجيات المساعِدة. يجب أيضًا تحديد الصفحة الحالية في القائمة، ويمكننا إجراء ذلك باستخدام السمة aria-current
:
<nav aria-label="Main">
<ul>
<li>
<a href="/page-1" aria-current="page">Menu item 1</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
<li>
<a href="/page-2">Menu item 2</a>
</li>
…
</ul>
</nav>
توضّح هذه المقالة حول بنية القائمة عددًا من الاقتراحات لضمان إمكانية وصول الجميع إلى قوائم التنقّل.
قائمة بترتيب (ol)
عنصر القائمة المرتبة (<ol>
) هو الخيار الأفضل عندما يكون ترتيب العناصر مهمًا، مثل عملية متعددة الخطوات. يتم تلقائيًا ترقيم عناصر القائمة. يمكن أن يكون أحد الأمثلة مجموعة من التعليمات التي يجب إكمال الخطوات فيها بالترتيب.
يمكن أن يحتوي كلّ من العنصرَين <ol>
و<ul>
على عناصر <li>
فقط كعناصر ثانوية مباشرة.
قائمة الوصف (dl)
تحتوي قائمة الأوصاف على مصطلحات (عناصر <dt>
) وأوصاف (عناصر <dd>
). ويمكن أن يكون لكل مصطلح أكثر من وصف واحد. يمكن أن تشمل حالات الاستخدام المحتمَلة مسردًا للمصطلحات أو قائمة طعام في مطعم. لا يتم عرض قوائم الأوصاف مع أيّ علامات تلقائيًا، على الرغم من أنّ المتصفّحات تميل إلى تقديم مسافة بادئة للعنصر <dd>
.
في HTML، يُسمح بتجميع المصطلحات مع الأوصاف المصاحبة لها باستخدام <div>
. يمكن أن يكون ذلك مفيدًا لأغراض التصميم، كما سنرى لاحقًا.
<!-- This is valid -->
<dl>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</dl>
<!-- This is also valid -->
<dl>
<div>
<dt>Term 1</dt>
<dd>This is the first description of the first term in the list</dd>
<dd>This is the second description of the first term in the list</dd>
</div>
<div>
<dt>Term 2</dt>
<dd>This is the description of the second term in the list</dd>
</div>
</dl>
نمط قائمة بسيط
من أبسط استخدامات القائمة هو تضمينها في مجموعة من النصوص الأساسية. في أغلب الأحيان، لا تحتاج هذه القوائم البسيطة إلى تصميم مفصّل، ولكن قد نريد تخصيص علامات قائمة مرتبة أو غير مرتبة إلى حدّ ما، مثل استخدام لون العلامة التجارية أو باستخدام صورة مخصّصة للنقاط. يمكننا تنفيذ الكثير من الإجراءات باستخدام العنصر النائب list-style
و::marker
.
::marker
بالإضافة إلى منح علامات القوائم بعض الأنماط الأساسية، يمكننا إنشاء نقاط بيضاوية دورية. في ما يلي، نستخدم ثلاثة عناوين URL مختلفة للصور لقيمة content
للعنصر النائب ::marker
، ما يضيف إلى الشعور بالكتابة اليدوية في مثال قائمة التسوّق (بدلاً من استخدام صورة واحدة فقط للجميع):
::marker {
content: url("/marker-1.svg") ' ';
}
li:nth-child(3n)::marker {
content: url("/marker-2.svg") ' ';
}
li:nth-child(3n - 1)::marker {
content: url("/marker-3.svg") ' ';
}
العدّادات المخصّصة
بالنسبة إلى بعض القوائم المرتبة، قد نريد استخدام قيمة المعداد، ولكن مع إلحاق قيمة أخرى بها. يمكننا استخدام المُعدّر list-item
كقيمة لسمة content
في العلامة وإلحاق أي محتوى آخر بها:
::marker {
content: counter(list-item) '🐈 ';
}
تزداد العدادات تلقائيًا بمقدار واحد، ولكن يمكننا السماح لها بالزيادة بمقدار قيمة مختلفة إذا أردنا ذلك، وذلك من خلال ضبط السمة counter-increment
على عنصر القائمة. على سبيل المثال، سيؤدي ذلك إلى زيادة العدّادات بمقدار ثلاثة في كل مرة:
li {
counter-increment: list-item 3;
}
هناك الكثير من التفاصيل التي يمكننا التعمّق فيها بشأن العدّادات. توضّح المقالة قوائم CSS وعلاماتها وعداداتها بعض الاحتمالات بمزيد من التفصيل.
قيود تنسيق ::marker
في بعض الأحيان، قد نحتاج إلى التحكّم بشكل أكبر في موضع العلامات ونمطها. على سبيل المثال، لا يمكن تحديد موضع العلامة باستخدام المربّع المرن أو الشبكة، ما قد يشكّل عائقًا في بعض الأحيان إذا كنت بحاجة إلى محاذاة أخرى. ::marker
يعرِض عددًا محدودًا من سمات CSS لتحديد الأنماط. إذا كان تصميمنا يتطلّب أيّ شيء آخر غير التصميم الأساسي، قد يكون من الأفضل استخدام عنصر وهمي آخر.
تصميم قوائم لا تبدو كقوائم
قد نريد أحيانًا تصميم قوائمنا بطريقة مختلفة تمامًا عن التصميم التلقائي. ويكون هذا هو الحال غالبًا مع قائمة التنقّل، على سبيل المثال، حيث نريد عادةً إزالة جميع العلامات، وقد نعرض قائمتنا أفقيًا باستخدام flexbox. من الممارسات الشائعة ضبط السمة list-style
على none
. وهذا يعني أنّه لن يعود بالإمكان الوصول إلى العنصر النائب للعلامة في DOM.
محدّدات المواقع المخصّصة باستخدام ::before
كان تنسيق العنصر النائب ::before
طريقة شائعة لإنشاء علامات قوائم مخصّصة قبل ظهور ::marker
. وحتى الآن، يمكن أن يمنحنا هذا الأسلوب مرونة أكبر، عند الحاجة، لتصميم قوائم معقدة من الناحية المرئية.
مثل ::marker
، يمكننا إضافة أنماط الرموز النقطية المخصّصة باستخدام سمة content
. على عكس استخدام ::marker
، علينا إجراء بعض عمليات تحديد المواضع يدويًا، لأنّنا لا نحصل على المزايا التلقائية التي يوفّرها list-style-position
. ولكن يمكننا وضعه بسهولة نسبية باستخدام flexbox، ويفتح هذا الصندوق عددًا أكبر من الاحتمالات للمحاذاة. على سبيل المثال، يمكننا تبديل موضع العلامة:
إذا أردنا تصميم قائمة مرتبة باستخدام العنصر ::before
، قد نريد أيضًا استخدام العدّادات لإضافة العلامات الرقمية.
li::before {
counter-increment: list-item;
content: counter(list-item);
}
يتيح لنا استخدام ::before
بدلاً من ::marker
الوصول الكامل إلى خصائص CSS لتطبيق أسلوب مخصّص، بالإضافة إلى السماح بالحركات الانتقالية والرسوم المتحركة التي لا تتوفّر لها إمكانية استخدام ::marker
.
سمات البيانات
تقبل عناصر القوائم المرتبة بعض السمات الاختيارية، ما يمكن أن يساعدنا في مجموعة متنوعة من حالات الاستخدام.
القوائم المقلوبة
إذا كانت لدينا قائمة بأهم 10 ألبومات من العام الماضي، قد نريد العد التنازلي من 10 إلى 1. يمكننا استخدام عدادات مخصّصة لذلك، وزيادتها بشكل سلبي. أو يمكننا ببساطة استخدام السمة reversed
في ملف HTML. أعتقد أنّه من المنطقي بشكل عام استخدام السمة reversed
بدلاً من زيادة العداد بشكل سلبي في CSS، ما لم تكن العدادات مخصّصة للعرض فقط. إذا تعذّر تحميل CSS، سيستمر ظهور الأرقام التي تُحصى التنازليًا بشكل صحيح في رمز HTML. بالإضافة إلى ذلك، علينا مراعاة كيفية تفسير قارئ الشاشة للقائمة.
اطّلِع على هذا العرض التجريبي لأبرز 10 ألبومات من العام 2021. إذا تمّت زيادة العدّادات باستخدام CSS فقط، قد يعتقد أحد المستخدمين الذين يصلون إلى الصفحة باستخدام قارئ شاشة أنّ الأرقام يتم احتسابها من الأعلى إلى الأسفل، وبالتالي يكون الرقم 10 هو الرقم الأول.
يمكنك الاطّلاع في العرض الترويجي على أنّه باستخدام سمة reversed
، تحتوي العلامات على القيمة الصحيحة بدون أي جهد إضافي من جانبنا. ولكن إذا أردنا إنشاء علامات قوائم مخصّصة باستخدام العنصر النائب ::before
، علينا تعديل العدادات. ما عليك سوى توجيه عداد عناصر القائمة إلى الزيادة بشكل سلبي:
li::before {
counter-increment: list-item -1;
content: counter(list-item);
}
سيكون هذا كافيًا في Firefox، ولكن في Chrome وSafari سيتم العد التنازلي للعلامات من الصفر إلى -10. يمكننا حلّ هذه المشكلة من خلال إضافة السمة start
إلى القائمة.
قوائم مُقسَّمة
تسمح لنا سمة start
بتحديد القيمة الرقمية التي يجب أن تبدأ منها القائمة. يمكن أن يكون ذلك مفيدًا في الحالات التي تريد فيها تقسيم قائمة إلى مجموعات.
لنطّلِع على مثال على أهم 10 ألبومات. ربما نريد عرض أهم 20 ألبومًا، ولكن في مجموعات من 10 ألبومات. بين مجموعتَي المحتوى، يتوفّر بعض محتوى الصفحة الآخر.
سنحتاج إلى إنشاء قائمتَين منفصلتَين في ملف HTML، ولكن كيف يمكننا التأكّد من صحة العدادات؟ وفقًا لعلامات الترميز الحالية، سيتم العد التنازلي لكلتا القائمتَين من 10 إلى 1، وهذا ليس ما نريد. ومع ذلك، يمكننا تحديد قيمة سمة start
في ملف HTML. إذا أضفنا قيمة start
= 20 إلى قائمتنا الأولى، سيتم تعديل العلامات مرة أخرى تلقائيًا.
<ol reversed start="20">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
تنسيق قائمة متعددة الأعمدة
يمكن أن يكون التنسيق المتعدّد الأعمدة مناسبًا أحيانًا لقوائمنا، كما يمكنك الاطّلاع عليه من خلال العروض التوضيحية السابقة. من خلال ضبط عرض العمود، يمكننا التأكّد من أنّ قائمتنا تكون متجاوبة تلقائيًا، وتظهر على عمودَين أو أكثر فقط عندما تكون هناك مساحة كافية. يمكننا أيضًا ضبط فجوة بين الأعمدة، ولإضافة لمسة جمالية إضافية، يمكننا إضافة قاعدة عمود منمّقة (باستخدام اختصار مشابه للسمة border
):
ol {
columns: 25rem;
column-gap: 7rem;
column-rule: 4px dotted turquoise;
}
عند استخدام الأعمدة، قد يؤدي ذلك أحيانًا إلى ظهور فواصل غير مرغوب فيها في عناصر القائمة، ما قد لا يحقّق التأثير المطلوب دائمًا.
يمكننا منع هذه الفواصل القسرية باستخدام break-inside: avoid
على عناصر القائمة:
li {
break-inside: avoid;
}
الخصائص المخصّصة
توفّر السمات المخصّصة لتنسيق CSS مجموعة كاملة من الاحتمالات لتنسيق القوائم. إذا عرفنا فهرس عنصر القائمة، يمكننا استخدامه لحساب قيم السمات. لا تتوفّر حاليًا طريقة لتحديد فهرس العنصر (بطريقة قابلة للاستخدام على أي حال) في CSS وحدها. لا تسمح لنا العدادات باستخدام قيمها إلا في السمة content
، ولا تسمح بإجراء العمليات الحسابية.
ولكن يمكننا ضبط فهرس العنصر ضمن سمة style
في رمز HTML، ما يمكن أن يجعل العمليات الحسابية أكثر سهولة، خاصةً إذا كنا نستخدم لغة نماذج. يوضّح هذا المثال كيفية ضبط ذلك باستخدام Nunjucks:
<ol style="--length: items|length">
</ol>
Splitting.js هي مكتبة تؤدي وظيفة مشابهة من جهة العميل.
باستخدام قيمة السمة المخصّصة، يمكننا عرض مستوى التقدّم في قائمة بطرق مختلفة. يمكن أن تكون إحدى الطرق هي شريط تقدّم لقائمة الخطوات. في هذا المثال، نستخدم عنصرًا زائفًا مع تدرج خطي لإنشاء شريط لكل عنصر يعرض مدى تقدّم المستخدِم في القائمة.
li::before {
--stop: calc(100% / var(--length) * var(--i));
--color1: deeppink;
--color2: pink;
content: '';
background: linear-gradient(to right, var(--color1) var(--stop), var(--color2) 0);
}
يمكننا أيضًا تعديل درجة اللون أثناء تقدم القائمة، وذلك باستخدام دالة اللون hsl()
. يمكننا احتساب قيمة hue
باستخدام السمة المخصّصة.
تنسيق قائمة الوصف
كما ذكرنا سابقًا، يمكننا اختيار تضمين المصطلحات وتعريفاتها في div
ضمن dl
، ما يمنحنا المزيد من خيارات التصميم. على سبيل المثال، قد نريد عرض قائمتنا على شكل شبكة. سيؤدي ضبط display: grid
في القائمة بدون حاوية div
حول كل مجموعة إلى وضع البنود والأوصاف في خلايا شبكة مختلفة. يكون ذلك مفيدًا في بعض الأحيان، كما هو الحال في المثال التالي الذي يعرض قائمة بالفطائر مع أوصافها.
يمكننا تحديد شبكة في القائمة نفسها والتأكّد من أنّ المصطلحات والأوصاف ستترتب دائمًا في أعمدة، مع تحديد عرض العمود حسب أطول مصطلح.
من ناحية أخرى، إذا أردنا تجميع المصطلحات بشكلٍ واضح مع أوصافها على شكل بطاقة، يكون العنصر المُغلف <div>
مفيدًا جدًا.
الموارد
- القوائم: مقدّمة عن القوائم و::marker
- العلامات المخصّصة باستخدام ::marker
- قوائم CSS التي تتضمّن عدادات