تنسيق القوائم وقوائم التنقل
لماذا يهم تنسيق القوائم
تعد قوائم HTML من أكثر العناصر الهيكلية تنوعا على الويب. تظهر القوائم غير المرتبة (<ul>) والقوائم المرتبة (<ol>) وقوائم الوصف (<dl>) في كل مكان -- من النقاط البسيطة والتعليمات المرقمة إلى قوائم التنقل ومسارات التصفح وعناصر التحكم في الترقيم وسحب العلامات. التنسيق الافتراضي للمتصفح للقوائم وظيفي لكنه بسيط بصريا: رمز قرص بسيط أو رقم عشري مع حشوة يسرى كبيرة. إتقان تنسيق قوائم CSS يتيح لك تحويل هذه العناصر الأساسية إلى مكونات واجهة مستخدم مصقولة واحترافية مع الحفاظ على HTML الأساسي دلاليا وسهل الوصول.
في هذا الدرس، ستتعلم كل خاصية CSS متعلقة بتنسيق القوائم، وستستكشف العنصر الزائف القوي ::marker، وستبني عدادات مخصصة لأنظمة ترقيم معقدة، وستنشئ أنماط تنقل واقعية بالكامل من قوائم HTML. بنهاية الدرس، ستتمكن من أخذ <ul> أو <ol> عادي وتحويله إلى أي مكون تنقلي أو معلوماتي يتطلبه تصميمك.
خاصية list-style-type
تتحكم خاصية list-style-type في العلامة (الرمز أو الرقم) التي تظهر قبل كل عنصر قائمة. تنطبق هذه الخاصية على العناصر ذات display: list-item، والتي تشمل عناصر <li> افتراضيا. تقبل مجموعة واسعة من القيم الكلمية لكل من القوائم المرتبة وغير المرتبة، ويمكنك حتى توفير سلسلة نصية مخصصة.
القيم الشائعة للقوائم غير المرتبة
تستخدم القوائم غير المرتبة علامات رمزية. القيم الأكثر شيوعا هي disc (دائرة مملوءة، الافتراضية)، وcircle (دائرة مجوفة)، وsquare (مربع مملوء)، وnone (بدون علامة على الإطلاق). تغطي هذه العلامات البسيطة معظم الاحتياجات الأساسية.
أنواع علامات القائمة غير المرتبة
/* دائرة مملوءة افتراضية */
ul.default {
list-style-type: disc;
}
/* دائرة مجوفة */
ul.hollow {
list-style-type: circle;
}
/* مربع مملوء */
ul.square {
list-style-type: square;
}
/* بدون علامة */
ul.clean {
list-style-type: none;
}
القيم الشائعة للقوائم المرتبة
تدعم القوائم المرتبة مجموعة أكبر بكثير من أنظمة الترقيم. الافتراضي هو decimal (1، 2، 3...)، لكن CSS يوفر عشرات البدائل. إليك أكثرها فائدة:
أنظمة ترقيم القوائم المرتبة
/* أرقام قياسية: 1، 2، 3... */
ol.numbers {
list-style-type: decimal;
}
/* أصفار بادئة: 01، 02، 03... */
ol.padded {
list-style-type: decimal-leading-zero;
}
/* أحرف صغيرة: a، b، c... */
ol.alpha {
list-style-type: lower-alpha;
}
/* أحرف كبيرة: A، B، C... */
ol.upper-alpha {
list-style-type: upper-alpha;
}
/* أرقام رومانية صغيرة: i، ii، iii... */
ol.roman {
list-style-type: lower-roman;
}
/* أرقام رومانية كبيرة: I، II، III... */
ol.upper-roman {
list-style-type: upper-roman;
}
/* يونانية صغيرة: α، β، γ... */
ol.greek {
list-style-type: lower-greek;
}
علامات السلسلة النصية المخصصة
واحدة من أكثر ميزات list-style-type مرونة هي القدرة على توفير سلسلة نصية مخصصة كعلامة. تلف السلسلة بعلامات اقتباس وتظهر قبل كل عنصر قائمة. هذا مثالي لإضافة علامات إيموجي أو أسهم أو علامات تحقق أو أي حرف آخر.
استخدام علامات السلسلة النصية المخصصة
/* علامة سهم */
ul.arrows {
list-style-type: "→ ";
}
/* علامة تحقق */
ul.checks {
list-style-type: "✓ ";
}
/* علامة نجمة */
ul.stars {
list-style-type: "★ ";
}
/* علامة شرطة */
ul.dashes {
list-style-type: "– ";
}
"→ " بدلا من "→") لإنشاء فصل بصري بين العلامة ونص عنصر القائمة. بدون هذه المسافة، ستلتصق العلامة مباشرة بالنص.خاصية list-style-position
تتحكم خاصية list-style-position في مكان وضع العلامة بالنسبة لصندوق محتوى عنصر القائمة. تقبل قيمتين: outside (الافتراضية) وinside.
مع outside، تجلس العلامة في منطقة الهامش على يسار صندوق المحتوى. هذا يعني أن النص متعدد الأسطر يلتف بشكل أنيق، مع محاذاة الأسطر اللاحقة تحت السطر الأول من النص بدلا من تحت العلامة. مع inside، توضع العلامة داخل صندوق المحتوى كما لو كانت أول عنصر سطري. يلتف النص متعدد الأسطر تحت العلامة، مما قد يبدو غير مرتب للعناصر الأطول لكنه مفيد عندما تحتاج إلى العلامة داخل حاوية ذات حدود أو لون خلفية.
موضع العلامة: خارجي مقابل داخلي
/* الافتراضي: العلامة خارج صندوق المحتوى */
ul.outside-markers {
list-style-position: outside;
padding-left: 2rem;
}
/* العلامة داخل صندوق المحتوى */
ul.inside-markers {
list-style-position: inside;
padding-left: 0;
}
/* الداخلي مفيد مع الحدود أو الخلفيات */
ul.boxed-list {
list-style-position: inside;
padding: 0;
}
ul.boxed-list li {
background-color: var(--bg-light);
border: 1px solid var(--border-light);
padding: 0.75rem 1rem;
margin-bottom: 0.5rem;
border-radius: 4px;
}
خاصية list-style-image
تتيح لك خاصية list-style-image استبدال العلامة بصورة مخصصة. تقدم url() يشير إلى ملف صورة. بينما هذه طريقة سريعة لإضافة علامات رسومية، لها قيود: لا يمكنك التحكم في حجم الصورة، والمحاذاة قد تكون صعبة. لمعظم المشاريع الحديثة، استخدام ::marker أو صور الخلفية على <li> يمنحك تحكما أكبر.
استخدام صورة كعلامة قائمة
/* استبدال الرموز بأيقونة مخصصة */
ul.custom-icon {
list-style-image: url("/images/icons/arrow-right.svg");
}
/* احتياطي: إذا فشل تحميل الصورة يستخدم القرص */
ul.with-fallback {
list-style-type: disc; /* احتياطي */
list-style-image: url("/images/icons/check.svg");
}
list-style-image لها الأولوية على list-style-type. إذا تم تعيين كليهما وتم تحميل الصورة بنجاح، يتم استخدام الصورة. إذا فشل تحميل الصورة، يعود المتصفح إلى قيمة list-style-type. عين دائما list-style-type ذا معنى كاحتياطي عند استخدام list-style-image.الاختصار list-style
يجمع اختصار list-style بين list-style-type وlist-style-position وlist-style-image في تصريح واحد. يمكن أن تظهر القيم بأي ترتيب، ويمكنك حذف أي منها. يحدد المتصفح أي قيمة تقابل أي خاصية بناء على نوع القيمة.
اختصار list-style في العمل
/* النوع والموضع */
ul {
list-style: square inside;
}
/* صورة مع نوع احتياطي */
ul.icons {
list-style: disc url("/images/bullet.svg") outside;
}
/* إزالة جميع العلامات (الاستخدام الأكثر شيوعا) */
ul.nav,
ul.clean {
list-style: none;
}
/* تغيير النوع فقط */
ol.legal {
list-style: upper-roman;
}
العنصر الزائف ::marker
يمنحك العنصر الزائف ::marker وصولا مباشرا لتنسيق صندوق العلامة لعنصر القائمة. قبل وجود ::marker، كان تنسيق الرمز أو الرقم يتطلب حلولا بديلة مثل إخفاء العلامة واستخدام العناصر الزائفة ::before. الآن يمكنك تغيير اللون والحجم والخط ومحتوى العلامات مباشرة. يعمل هذا العنصر الزائف على أي عنصر بـ display: list-item، وكذلك على عناصر <summary>.
الخصائص التي يمكنك تعيينها على ::marker
يدعم العنصر الزائف ::marker مجموعة محدودة لكن مفيدة من الخصائص: جميع خصائص font، وcolor، وtext-combine-upright، وunicode-bidi، وdirection، وcontent، وجميع خصائص الحركة والانتقال. جدير بالذكر أنه لا يمكنك تعيين background أو padding أو border أو width/height على ::marker.
تنسيق العلامات باستخدام ::marker
/* تغيير لون العلامة */
li::marker {
color: var(--primary);
}
/* علامات أكبر وعريضة */
ol li::marker {
font-size: 1.2em;
font-weight: 700;
color: var(--primary);
}
/* محتوى مخصص في العلامات */
ul.custom li::marker {
content: "▸ ";
color: var(--primary);
font-size: 1.1em;
}
/* علامات مختلفة لكل عنصر */
li.complete::marker {
content: "✅ ";
}
li.in-progress::marker {
content: "🔄 ";
}
li.pending::marker {
content: "⏳ ";
}
استخدام content مع ::marker
خاصية content على ::marker تتيح لك تجاوز العلامة الافتراضية بأي نص، بما في ذلك قيم العداد. هذا قوي بشكل خاص في القوائم المرتبة حيث يمكنك دمج الترقيم التلقائي مع التنسيق المخصص.
علامات مرقمة مخصصة
/* مرقمة بأقواس: 1) 2) 3) */
ol.paren li::marker {
content: counter(list-item) ") ";
color: var(--primary);
font-weight: bold;
}
/* مرقمة بنقطة وشرطة: 1 – 2 – 3 – */
ol.dash li::marker {
content: counter(list-item) " – ";
}
/* ترقيم الخطوات: Step 1: Step 2: Step 3: */
ol.steps li::marker {
content: "الخطوة " counter(list-item) ": ";
font-weight: 600;
color: var(--text-light);
}
list-item المدمج يتم صيانته تلقائيا بواسطة القوائم المرتبة، لذا لا تحتاج إلى إعداد counter-reset أو counter-increment يدويا عند استخدامه مع ::marker. هذا العداد متاح على عناصر قوائم <ol> و<ul> افتراضيا.عدادات CSS
عدادات CSS هي متغيرات يحافظ عليها CSS ويمكن زيادة قيمها أو إنقاصها وعرضها باستخدام المحتوى المولد. هي المحرك وراء الترقيم التلقائي في CSS وهي أكثر مرونة بكثير من عداد list-item المدمج. مع عدادات CSS، يمكنك ترقيم أي عنصر -- وليس فقط عناصر القوائم -- وإنشاء أنظمة ترقيم هرمية معقدة مثل "1.1" و"1.2.3" وما إلى ذلك.
counter-reset
خاصية counter-reset تنشئ أو تعيد تعيين عداد. تضبط العداد على صفر (أو قيمة أخرى محددة) على العنصر الذي تطبق عليه. عادة ما تضعها على العنصر الأب الذي يحتوي على العناصر التي تريد ترقيمها.
counter-increment
خاصية counter-increment تزيد (أو تنقص) قيمة العداد. توضع على كل عنصر يجب أن يتقدم في العد. افتراضيا تزيد بمقدار 1، لكن يمكنك تحديد قيمة زيادة مختلفة.
دالتا counter() و counters()
دالة counter() تخرج القيمة الحالية لعداد مسمى. دالة counters() تستخدم للعدادات المتداخلة، وتخرج جميع القيم في مكدس تداخل العداد مفصولة بسلسلة نصية تحددها أنت.
إعداد عداد CSS أساسي
/* إعادة تعيين العداد على الأب */
.numbered-sections {
counter-reset: section;
}
/* زيادة لكل عنوان قسم */
.numbered-sections h2 {
counter-increment: section;
}
/* عرض العداد قبل كل عنوان */
.numbered-sections h2::before {
content: "القسم " counter(section) ": ";
color: var(--primary);
font-weight: 700;
}
/* يمكنك إعادة التعيين إلى قيمة محددة */
.start-at-five {
counter-reset: item 4; /* يبدأ من 5 بعد أول زيادة */
}
/* زيادة بمقادير مخصصة */
.even-numbers h3 {
counter-increment: item 2;
}
العدادات المتداخلة للترقيم الهرمي
القوة الحقيقية لعدادات CSS تتألق مع القوائم المتداخلة. بإعادة تعيين عداد على كل <ol> أو <ul>، ينشئ المتصفح مثيلا جديدا من ذلك العداد لكل مستوى تداخل. ثم تربط دالة counters() جميع المستويات بفاصل، منتجة ترقيما مثل "1.1" و"1.2" و"2.1" و"2.1.1" وما إلى ذلك.
الترقيم الهرمي باستخدام counters()
/* كل ol يعيد التعيين وينشئ مثيل عداد جديد */
ol.hierarchical {
counter-reset: item;
list-style-type: none;
padding-left: 1.5rem;
}
/* كل li يزيد ويعرض جميع المستويات المتداخلة */
ol.hierarchical li {
counter-increment: item;
}
ol.hierarchical li::before {
content: counters(item, ".") " ";
color: var(--primary);
font-weight: 700;
margin-right: 0.5rem;
}
/* بنية HTML:
<ol class="hierarchical">
<li>مقدمة -- 1
<ol class="hierarchical">
<li>الخلفية -- 1.1
<li>الغرض -- 1.2
</ol>
<li>المنهجيات -- 2
<ol class="hierarchical">
<li>جمع البيانات -- 2.1
<ol class="hierarchical">
<li>الاستبيانات -- 2.1.1
<li>المقابلات -- 2.1.2
</ol>
<li>التحليل -- 2.2
</ol>
</ol>
*/
counters() وسيطتين مطلوبتين: اسم العداد وسلسلة الفاصل. كما تقبل وسيطة ثالثة اختيارية لنمط العداد (مثل counters(item, ".", upper-roman) ستنتج "I.I" و"I.II" إلخ). هذا يتيح لك الجمع بين البنية الهرمية وأي نظام ترقيم.أنماط العداد في counter()
كل من counter() وcounters() تقبلان معامل نمط اختياري يغير كيفية عرض الرقم. يقبل معامل النمط هذا نفس قيم list-style-type.
أنماط عرض العداد
/* عرض كأرقام رومانية كبيرة */
.roman-sections h2::before {
content: counter(section, upper-roman) ". ";
}
/* عرض كأحرف صغيرة */
.alpha-steps li::before {
content: counter(step, lower-alpha) ") ";
}
/* عرض بأصفار بادئة */
.padded-list li::before {
content: counter(item, decimal-leading-zero) ". ";
}
بناء شريط تنقل أفقي
واحد من أكثر استخدامات القوائم المنسقة شيوعا هو بناء شريط تنقل أفقي. النمط بسيط: ابدأ بعنصر <nav> دلالي يحتوي على <ul>، أزل تنسيق القائمة الافتراضي، واستخدم Flexbox لترتيب العناصر أفقيا.
تنقل أفقي من قائمة
/* بنية HTML:
<nav aria-label="التنقل الرئيسي">
<ul class="navbar">
<li><a href="/">الرئيسية</a></li>
<li><a href="/about">عنا</a></li>
<li><a href="/services">الخدمات</a></li>
<li><a href="/contact">اتصل بنا</a></li>
</ul>
</nav>
*/
.navbar {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 0;
background-color: var(--bg-white);
border-bottom: 2px solid var(--border-light);
}
.navbar li a {
display: block;
padding: 1rem 1.5rem;
text-decoration: none;
color: var(--text-dark);
font-weight: 500;
transition: background-color 0.2s, color 0.2s;
}
.navbar li a:hover,
.navbar li a:focus-visible {
background-color: var(--primary-light);
color: var(--primary);
}
.navbar li a[aria-current="page"] {
color: var(--primary);
border-bottom: 3px solid var(--primary);
}
قوائم التنقل المنسدلة
تمتد القوائم المنسدلة من نمط التنقل الأفقي بتداخل <ul> ثانية داخل عنصر قائمة. القائمة المتداخلة مخفية افتراضيا وتظهر عند تمرير الماوس فوق العنصر الأب أو تركيز عليه. إمكانية الوصول عبر لوحة المفاتيح أمر حاسم: يجب أن تكون القائمة المنسدلة قابلة للوصول عبر مفتاح Tab، وليس فقط عبر تمرير الماوس.
قائمة منسدلة CSS
/* بنية HTML:
<ul class="nav-dropdown">
<li>
<a href="/services">الخدمات</a>
<ul class="submenu">
<li><a href="/web-design">تصميم الويب</a></li>
<li><a href="/seo">تحسين محركات البحث</a></li>
<li><a href="/marketing">التسويق</a></li>
</ul>
</li>
</ul>
*/
.nav-dropdown {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
.nav-dropdown > li {
position: relative;
}
.nav-dropdown a {
display: block;
padding: 1rem 1.25rem;
text-decoration: none;
color: var(--text-dark);
white-space: nowrap;
}
/* القائمة الفرعية المخفية */
.submenu {
list-style: none;
margin: 0;
padding: 0.5rem 0;
position: absolute;
top: 100%;
left: 0;
min-width: 200px;
background: var(--bg-white);
border: 1px solid var(--border-light);
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
opacity: 0;
visibility: hidden;
transform: translateY(-8px);
transition: opacity 0.2s, visibility 0.2s, transform 0.2s;
}
/* إظهار عند التمرير */
.nav-dropdown > li:hover > .submenu,
.nav-dropdown > li:focus-within > .submenu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.submenu a {
padding: 0.5rem 1.25rem;
}
.submenu a:hover,
.submenu a:focus-visible {
background-color: var(--bg-light);
color: var(--primary);
}
:focus-within على عنصر <li> الأب ضروري لإمكانية الوصول عبر لوحة المفاتيح. بدونه، لن يتمكن المستخدمون الذين يتنقلون بمفتاح Tab من الوصول أبدا إلى عناصر القائمة المنسدلة. الصنف الزائف :focus-within يبقي القائمة المنسدلة مرئية عندما يكون أي عنصر فرعي بداخلها في حالة تركيز، مما يتيح التنقل الكامل عبر لوحة المفاتيح في القائمة.تنقل مسار التصفح
مسار التصفح يعرض موقع المستخدم ضمن تسلسل الموقع الهرمي. يبنى بقائمة مرتبة داخل عنصر <nav> مع aria-label="Breadcrumb". تضاف فواصل CSS بين العناصر باستخدام العنصر الزائف ::before أو ::after، بحيث يبقى HTML نظيفا ودلاليا.
نمط تنقل مسار التصفح
/* بنية HTML:
<nav aria-label="مسار التصفح">
<ol class="breadcrumb">
<li><a href="/">الرئيسية</a></li>
<li><a href="/products">المنتجات</a></li>
<li><a href="/products/laptops">أجهزة اللابتوب</a></li>
<li aria-current="page">ماك بوك برو</li>
</ol>
</nav>
*/
.breadcrumb {
list-style: none;
margin: 0;
padding: 0.75rem 1rem;
display: flex;
flex-wrap: wrap;
align-items: center;
background-color: var(--bg-light);
border-radius: 4px;
font-size: 0.9rem;
}
/* إضافة فاصل بين العناصر */
.breadcrumb li + li::before {
content: "/";
margin: 0 0.5rem;
color: var(--text-light);
}
.breadcrumb a {
color: var(--primary);
text-decoration: none;
}
.breadcrumb a:hover {
text-decoration: underline;
}
/* الصفحة الحالية (بدون رابط) */
.breadcrumb li[aria-current="page"] {
color: var(--text-light);
font-weight: 500;
}
تنقل الشريط الجانبي
تنقل الشريط الجانبي هو قائمة عمودية من الروابط، غالبا مع أقسام فرعية متداخلة يمكن توسيعها وطيها. الأساس هو <ul> منسق بسيط مع مؤشرات بصرية للعنصر النشط وحالات التمرير. تداخل قوائم إضافية ينشئ بنية شجرية للتنقل متعدد المستويات.
تنقل الشريط الجانبي مع مستويات متداخلة
/* بنية HTML:
<nav class="sidebar-nav" aria-label="التوثيق">
<ul>
<li><a href="#" class="active">البداية</a></li>
<li>
<a href="#">المكونات</a>
<ul>
<li><a href="#">الأزرار</a></li>
<li><a href="#">البطاقات</a></li>
<li><a href="#">النوافذ المنبثقة</a></li>
</ul>
</li>
<li><a href="#">الأدوات المساعدة</a></li>
</ul>
</nav>
*/
.sidebar-nav ul {
list-style: none;
margin: 0;
padding: 0;
}
.sidebar-nav a {
display: block;
padding: 0.6rem 1rem;
text-decoration: none;
color: var(--text-dark);
border-left: 3px solid transparent;
transition: all 0.2s;
}
.sidebar-nav a:hover,
.sidebar-nav a:focus-visible {
background-color: var(--bg-light);
color: var(--primary);
border-left-color: var(--primary-light);
}
.sidebar-nav a.active {
color: var(--primary);
background-color: var(--primary-light);
border-left-color: var(--primary);
font-weight: 600;
}
/* مسافة بادئة للقائمة المتداخلة */
.sidebar-nav ul ul {
padding-left: 1rem;
}
.sidebar-nav ul ul a {
font-size: 0.9rem;
padding: 0.4rem 1rem;
}
الترقيم الصفحي
عناصر التحكم في الترقيم الصفحي هي نمط واجهة مستخدم كلاسيكي آخر مبني على القوائم. يستخدم النمط قائمة غير مرتبة مع كل رقم صفحة كعنصر قائمة، منسق أفقيا باستخدام Flexbox. حالات النشط والمعطل والتمرير تكمل تصميم التفاعل.
مكون الترقيم الصفحي
/* بنية HTML:
<nav aria-label="الترقيم الصفحي">
<ul class="pagination">
<li><a href="#" aria-label="الصفحة السابقة">«</a></li>
<li><a href="#">1</a></li>
<li><a href="#" aria-current="page">2</a></li>
<li><a href="#">3</a></li>
<li><span class="ellipsis">...</span></li>
<li><a href="#">12</a></li>
<li><a href="#" aria-label="الصفحة التالية">»</a></li>
</ul>
</nav>
*/
.pagination {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 4px;
}
.pagination a,
.pagination .ellipsis {
display: flex;
align-items: center;
justify-content: center;
min-width: 2.5rem;
height: 2.5rem;
padding: 0 0.75rem;
text-decoration: none;
color: var(--text-dark);
border: 1px solid var(--border-light);
border-radius: 4px;
font-size: 0.9rem;
transition: all 0.2s;
}
.pagination a:hover,
.pagination a:focus-visible {
background-color: var(--bg-light);
border-color: var(--primary);
color: var(--primary);
}
.pagination a[aria-current="page"] {
background-color: var(--primary);
border-color: var(--primary);
color: white;
font-weight: 600;
}
.pagination .ellipsis {
border: none;
color: var(--text-light);
}
قوائم العلامات والشرائح
العلامات (تسمى أيضا الشرائح أو الشارات) هي تسميات مضغوطة غالبا ما تعرض كقائمة أفقية. تستخدم للفئات والمهارات والفلاتر أو العناصر المحددة. توفر القائمة تجميعا دلاليا بينما يحول CSS العناصر إلى أزرار على شكل حبة دواء أو مستطيلات دائرية.
مكون قائمة العلامات/الشرائح
/* بنية HTML:
<ul class="tag-list" aria-label="التقنيات">
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
<li><a href="#">React</a></li>
</ul>
*/
.tag-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag-list a {
display: inline-block;
padding: 0.35rem 0.85rem;
text-decoration: none;
font-size: 0.85rem;
color: var(--primary);
background-color: var(--primary-light);
border-radius: 999px;
transition: background-color 0.2s, color 0.2s;
}
.tag-list a:hover,
.tag-list a:focus-visible {
background-color: var(--primary);
color: white;
}
أنماط القوائم والتنقل سهلة الوصول
إمكانية الوصول ليست اختيارية عند بناء التنقل من القوائم. إليك الممارسات الأساسية التي يجب على كل مطور اتباعها:
- استخدم
<nav>معaria-label-- غلف قوائم التنقل في عنصر<nav>معaria-labelوصفي. إذا كانت الصفحة تحتوي على عناصر<nav>متعددة، يجب أن يكون لكل منها تسمية فريدة حتى يتمكن مستخدمو قارئات الشاشة من التمييز بينها (مثل "التنقل الرئيسي"، "تنقل التذييل"، "مسار التصفح"). - استخدم
aria-current="page"-- حدد رابط الصفحة الحالية بـaria-current="page"حتى تعلن قارئات الشاشة أي رابط يتوافق مع الصفحة الحالية. - التنقل عبر لوحة المفاتيح -- تأكد من أن جميع العناصر التفاعلية قابلة للوصول بمفتاح
Tab. للقوائم المنسدلة، استخدم:focus-withinلإبقاء القوائم الفرعية مرئية عند التنقل بلوحة المفاتيح. - مؤشرات التركيز المرئية -- لا تزل أبدا مخطط التركيز بدون توفير بديل. استخدم
:focus-visibleلتنسيق مؤشرات التركيز التي تظهر فقط أثناء التنقل بلوحة المفاتيح. - لا تزل دلالات القائمة بلا مبالاة -- تعيين
list-style: noneيجعل VoiceOver في Safari يتوقف عن الإعلان عن العناصر كقائمة. للحفاظ على دلالات القائمة، أضفrole="list"إلى<ul>عندما تزيل العلامات الافتراضية.
الحفاظ على دلالات القائمة في Safari VoiceOver
<!-- أضف role="list" عند استخدام list-style: none -->
<nav aria-label="التنقل الرئيسي">
<ul class="navbar" role="list">
<li><a href="/" aria-current="page">الرئيسية</a></li>
<li><a href="/about">عنا</a></li>
<li><a href="/contact">اتصل بنا</a></li>
</ul>
</nav>
list-style: none. هذا قرار تصميم متعمد من Apple لتقليل ضوضاء الإعلانات في قوائم التنقل. إذا كنت تحتاج إلى أن تعلن القائمة كقائمة (مثل في مناطق المحتوى حيث يهم العدد)، أضف role="list" إلى عنصر <ul> أو <ol>. ومع ذلك، لقوائم التنقل حيث يوفر معلم <nav> سياقا كافيا بالفعل، عادة ما تكون دلالات القائمة المفقودة مقبولة.مثال عملي: تنقل توثيق متعدد المستويات
دعنا نجمع كل شيء معا في مثال شامل يجمع العدادات والقوائم المتداخلة وأنماط التنقل في شريط جانبي للتوثيق مع ترقيم هرمي.
تنقل التوثيق الكامل
/* بنية HTML:
<nav class="docs-nav" aria-label="التوثيق">
<ol>
<li>
<a href="#intro">المقدمة</a>
<ol>
<li><a href="#what">ما هو CSS؟</a></li>
<li><a href="#why">لماذا تتعلم CSS؟</a></li>
</ol>
</li>
<li>
<a href="#selectors">المحددات</a>
<ol>
<li><a href="#basic">المحددات الأساسية</a></li>
<li><a href="#combinator">المجمعات</a></li>
</ol>
</li>
</ol>
</nav>
*/
.docs-nav ol {
counter-reset: doc-section;
list-style: none;
margin: 0;
padding: 0;
}
.docs-nav > ol > li {
counter-increment: doc-section;
margin-bottom: 0.5rem;
}
.docs-nav > ol > li > a {
display: block;
padding: 0.6rem 1rem;
font-weight: 700;
color: var(--text-dark);
text-decoration: none;
border-radius: 4px;
}
.docs-nav > ol > li > a::before {
content: counter(doc-section) ". ";
color: var(--primary);
}
.docs-nav > ol > li > a:hover {
background-color: var(--bg-light);
}
/* المستوى المتداخل */
.docs-nav ol ol {
padding-left: 1.5rem;
margin-top: 0.25rem;
}
.docs-nav ol ol li {
counter-increment: doc-section;
}
.docs-nav ol ol a {
display: block;
padding: 0.35rem 0.75rem;
font-size: 0.9rem;
color: var(--text-light);
text-decoration: none;
border-radius: 3px;
}
.docs-nav ol ol a::before {
content: counters(doc-section, ".") " ";
color: var(--primary);
font-weight: 600;
}
.docs-nav ol ol a:hover {
background-color: var(--bg-light);
color: var(--text-dark);
}
تمرين عملي
ابنِ نظام تنقل كامل لموقع ويب يتضمن جميع المكونات التالية: أولا، أنشئ شريط تنقل أفقي بخمسة روابط وتأثير تمرير ومؤشر صفحة نشطة باستخدام aria-current="page". ثانيا، أضف قائمة منسدلة لأحد عناصر التنقل بثلاثة روابط فرعية على الأقل، مع التأكد من أن القائمة المنسدلة سهلة الوصول عبر كل من تمرير الماوس وتركيز لوحة المفاتيح باستخدام :focus-within. ثالثا، ابنِ مسار تصفح بأربعة مستويات على الأقل (الرئيسية، الفئة، الفئة الفرعية، الصفحة الحالية) باستخدام فواصل CSS المولدة. رابعا، أنشئ تنقل شريط جانبي بمستويين من التداخل، باستخدام عدادات CSS لإنتاج ترقيم هرمي (1.1، 1.2، 2.1، إلخ). خامسا، أضف مكون ترقيم صفحي بأزرار السابق/التالي وصفحات مرقمة وعلامة حذف للصفحات المحذوفة. أخيرا، أضف قائمة علامات بست علامات على شكل حبة دواء على الأقل. تأكد من أن كل مكون تنقل مغلف في <nav> مع aria-label فريد، وأن جميع حالات التركيز مرئية، وأن دلالات القائمة محفوظة حيث تحتاج مع role="list".