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