استخدام مسار القراءة في CSS للتنقّل المنطقي التسلسلي في التركيز

تاريخ النشر: 1 أيار (مايو) 2025

تتوفّر السمتَان reading-flow وreading-order في CSS اعتبارًا من الإصدار 137 من Chrome. توضّح هذه المشاركة الأسباب وراء تصميم هذه السمات وبعض التفاصيل الموجزة لمساعدتك في البدء باستخدامها.

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

تم تصميم سمتَي reading-flow وreading-order وإضافتهما إلى مواصفات CSS Display، لمحاولة حلّ هذه المشكلة المستمرة منذ فترة طويلة.

reading-flow

تتحكّم سمة reading-flow في CSS بترتيب عرض العناصر في تنسيق مرن أو شبكة أو تنسيق كتل أمام أدوات تسهيل الاستخدام وكيفية التركيز عليها باستخدام طرق التنقّل التسلسلي الخطي.

يأخذ هذا المقياس قيمة كلمة رئيسية واحدة، مع قيمة normalتلقائية، ما يحافظ على سلوك ترتيب العناصر بترتيب نموذج DOM. لاستخدامها داخل حاوية مرنة، اضبط قيمتها على flex-visual أو flex-flow. لاستخدامها داخل حاوية شبكة، اضبط قيمتها على grid-rows أو grid-columns أو grid-order.

reading-order

تتيح لك خاصية CSS‏ reading-order إلغاء ترتيب العناصر يدويًا داخل حاوية مسار القراءة. لاستخدام هذه السمة داخل حاوية شبكة أو حاوية مرنة أو حاوية عنصر، اضبط قيمة reading-flow في الحاوية على source-order واضبط reading-order للعنصر الفردي على قيمة عددية.

مثال في المربّع المرن

على سبيل المثال، قد يكون لديك حاوية تصميم مرن تحتوي على ثلاثة عناصر في ترتيب الصفوف العكسي، وتريد أيضًا استخدام سمة الترتيب لإعادة ترتيب هذا الترتيب.

<div class="box">
 <a href="#">One</a>
 <a href="#">Two</a>
 <a href="#">Three</a>
</div>
.box {
  display: flex;
  flex-direction: row-reverse;
}

.box :nth-child(1) {
  order: 2;
}

يمكنك محاولة التنقّل في هذه العناصر باستخدام مفتاح TAB للعثور على العنصر التالي الذي يمكن التركيز عليه ومفتاحَي TAB+SHIFT للعثور على العنصر السابق الذي يمكن التركيز عليه. يتبع ذلك العناصر بترتيب المصدر: واحد، اثنان، ثلاثة.

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

لحلّ هذه المشكلة، اضبط السمة reading-flow:

.box {
  reading-flow: flex-visual;
}

ترتيب التركيز الآن هو: واحد، ثلاثة، اثنان. وهذا هو الترتيب المرئي نفسه الذي ستحصل عليه إذا كنت تقرأ باللغة الإنجليزية من اليسار إلى اليمين.

إذا كنت تفضّل بدلاً من ذلك الحفاظ على ترتيب التركيز كما كان مقصودًا في الأصل، في الترتيب العكسي، يمكنك ضبط ما يلي:

.box {
  reading-flow: flex-flow;
}

أصبح ترتيب التركيز الآن هو الترتيب العكسي للترتيب المرن: اثنان، ثلاثة، واحد. في كلا الحالتَين، يتم احتساب موقع CSS order.

مثال على تنسيق الشبكة

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

<div class="wrapper">
 <a href="#">One</a>
 <a href="#">Two</a>
 <a href="#">Three</a>
 <a href="#">Four</a>
 <a href="#">Five</a>
 <a href="#">Six</a>
 <a href="#">Seven</a>
 <a href="#">Eight</a>
 <a href="#">Nine</a>
 <a href="#">Ten</a>
 <a href="#">Eleven</a>
 <a href="#">Twelve</a>
</div>

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

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
}
.wrapper a:nth-child(2) {
  grid-column: 3;
  grid-row: 2 / 4;
}
.wrapper a:nth-child(5) {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}

حاوِل التنقّل بين هذه العناصر باستخدام مفتاح TAB للعثور على العنصر التالي قابل للتركيز ومفتاحَي TAB+SHIFT للعثور على العنصر السابق قابل للتركيز. يتبع ذلك العناصر بترتيب المصدر: من واحد إلى اثني عشر.

لحلّ هذه المشكلة، اضبط السمة reading-flow:

.wrapper {
  reading-flow: grid-rows;
}

ترتيب التركيز الآن هو: خمسة، واحد، ثلاثة، اثنان، أربعة، ستة، سبعة، ثمانية، تسعة، عشرة، أحد عشر، اثنا عشر. وتتّبع الترتيب المرئي، صفًا تلو الآخر.

إذا كنت تريد أن يتّبع مسار القراءة ترتيب الأعمدة بدلاً من ذلك، يمكنك استخدام قيمة الكلمة الرئيسية grid-columns بدلاً من ذلك. يصبح ترتيب التركيز بعد ذلك خمسة، ستة، تسعة، سبعة، عشرة، واحد، اثنان، أحد عشر، ثلاثة، أربعة، ثمانية، اثنا عشر.

.wrapper {
  reading-flow: grid-columns;
}

يمكنك أيضًا تجربة استخدام grid-order. يظلّ ترتيب التركيز من واحد إلى اثني عشر. ويعود السبب في ذلك إلى عدم ضبط طلب CSS على أي سلعة.

حاوية وحدات باستخدام reading-order

تتيح لك السمة reading-order تحديد وقت الانتقال إلى عنصر في عملية القراءة، ما يتجاهل الترتيب الذي تحدّده السمة reading-flow. ولا يتم تطبيقه إلا على حاوية مسار قراءة صالحة، عندما لا تكون قيمة السمة reading-flow هي normal.

.wrapper {
  display: block;
  reading-flow: source-order;
}

.top {
  reading-order: -1;
  inset-inline-start: 50px;
  inset-block-start: 50px;
}

تحتوي حاوية الكتل التالية على خمسة عناصر. لا تتوفّر قواعد تنسيق لإعادة ترتيب العناصر من ترتيبها المصدر، ولكن هناك عنصر واحد خارج تدفق العرض يجب الانتقال إليه أولاً.

<div class="wrapper">
  <a href="#">Item 1</a>
  <a href="#">Item 2</a>
  <a href="#">Item 3</a>
  <a href="#">Item 4</a>
  <a class="top" href="#">Item 5</a>
</div>

من خلال ضبط reading-order لهذا العنصر على -1، سينتقل إليه ترتيب التركيز أولاً قبل الرجوع إلى ترتيب المصدر لبقية عناصر مسار القراءة.

يمكنك العثور على المزيد من الأمثلة على موقع chrome.dev الإلكتروني.

التفاعل مع علامة tabindex

في السابق، كان المطوّرون يستخدمون السمة الشاملة tabindex في HTML لجعل عناصر HTML قابلة للتركيز وتحديد الترتيب النسبي للتنقّل التسلسلي بالتركيز. ومع ذلك، لهذه السمة العديد من العيوب والقلق بشأن تسهيل الاستخدام. تكمن المشكلة الرئيسية في أنّ شجرة تسهيل الاستخدام لا تتعرّف على التنقّل في التركيز الذي يتم ترتيبه حسب فهرس علامات التبويب والذي تم إنشاؤه باستخدام فهرس علامات التبويب الإيجابي. وعند استخدامها بشكلٍ غير صحيح، قد يؤدي ذلك إلى ترتيب تركيز متقطّع لا يتطابق مع تجربته على قارئ الشاشة. لحلّ هذه المشكلة، يمكنك تتبُّع الترتيب باستخدام سمة HTML aria-owns.

في مثال Flex السابق، للحصول على النتيجة نفسها التي تحصل عليها عند استخدام reading-flow: flex-visual، يمكنك إجراء ما يلي:

<div class="box" aria-owns="one three two">
  <a href="#" tabindex="1" id="one">One</a>
  <a href="#" tabindex="3" id="two">Two</a>
  <a href="#" tabindex="2" id="three">Three</a>
</div>

ولكن ماذا يحدث إذا كان هناك عنصر آخر خارج الحاوية يتضمّن tabindex=1 أيضًا؟ بعد ذلك، ستتم زيارة جميع العناصر التي تحتوي على tabindex=1 معًا، قبل الانتقال إلى قيمة tabindex المتزايدة التالية. سيؤدي هذا التنقّل التسلسلي المتقطع إلى تقديم تجربة سيئة للمستخدم. وبالتالي، ينصح خبراء تسهيل الاستخدام بعدم استخدام قيمة موجبة لسمة tabindex. لقد حاولنا إصلاح هذه المشكلة عند تصميم reading-flow.

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

يُرجى العِلم أنّ العنصر الذي يحتوي على display: contents والذي يكتسب السمة reading-flow من العنصر الرئيسي للتخطيط سيكون أيضًا حاوية صالحة لمسار القراءة. يُرجى مراعاة ذلك عند تصميم موقعك الإلكتروني. يمكنك الاطّلاع على مزيد من المعلومات حول هذا الموضوع في طلبنا للحصول على ملاحظات حول reading-flow وdisplay: contents.

أخبرنا برأيك

جرِّب الأمثلة الواردة في هذا المنشور وفي reading-flow أمثلة على chrome.dev، واستخدِم ملفّات CSS هذه على مواقعك الإلكترونية. إذا كانت لديك أي ملاحظات، يُرجى الإبلاغ عنها كمشكلة في مستودع GitHub الخاص بمجموعة عمل CSS. إذا كان لديك ملاحظات حول سلوك نطاق علامة التبويب والتركيز، يُرجى إبلاغنا بها على أنّها مشكلة في مستودع GitHub الخاص بمجموعة HTML WHATNOT. يسرّنا تلقّي ملاحظاتك بشأن هذه الميزة.