Используйте поток чтения CSS для логической последовательной навигации по фокусу. Используйте поток чтения CSS для логической последовательной навигации по фокусу. Используйте поток чтения CSS для логической последовательной навигации по фокусу. Используйте поток чтения CSS для логической последовательной навигации по фокусу.

Опубликовано: 1 мая 2025 г.

Свойства reading-flow и reading-order CSS доступны в Chrome 137. В этом посте объясняются причины создания этих свойств и некоторые краткие сведения, которые помогут вам начать с ними работать.

Такие методы компоновки, как сетка и гибкая система, изменили разработку внешнего интерфейса, однако их гибкость может вызвать проблемы у некоторых пользователей. Очень легко создать ситуацию, когда визуальный порядок не соответствует исходному порядку в дереве DOM. Поскольку браузер следует этому исходному порядку, если вы перемещаетесь по сайту с помощью клавиатуры, некоторые пользователи могут столкнуться с неожиданными прыжками при навигации по странице.

Свойства reading-flow и reading-order были разработаны и добавлены в спецификацию CSS Display , чтобы попытаться решить эту давнюю проблему.

reading-flow

Свойство CSS reading-flow управляет порядком, в котором элементы в гибком, сеточном или блочном макете подвергаются воздействию инструментов специальных возможностей, а также то, как они фокусируются с помощью методов линейной последовательной навигации.

Он принимает одно значение ключевого слова со значением по умолчанию normal , которое сохраняет поведение упорядочивания элементов в порядке DOM. Чтобы использовать его внутри гибкого контейнера, установите для него значение flex-visual или flex-flow . Чтобы использовать его внутри контейнера сетки, установите его значение либо в grid-rows , либо grid-columns , либо grid-order .

reading-order

Свойство CSS reading-order позволяет вручную переопределить порядок элементов в контейнере потока чтения. Чтобы использовать это свойство внутри контейнера сетки, гибкого или блочного контейнера, установите для значения reading-flow в контейнере значение source-order , а для reading-order отдельного элемента — целочисленное значение.

Пример во флексбоксе

Например, у вас может быть контейнер гибкого макета с тремя элементами в обратном порядке строк, и вы также хотите использовать свойство 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;
}

Порядок фокуса теперь обратный порядок гибкости: два, три, один. В обоих случаях учитывается свойство order CSS.

Пример с сеткой

Чтобы увидеть, как это работает в сетке, представьте, что вы создаете макет с автоматически размещаемыми элементами 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 .

Взаимодействие с табиндексом

Исторически разработчики использовали глобальный атрибут HTML tabindex , чтобы сделать HTML-элементы фокусируемыми и определить относительный порядок для последовательной навигации по фокусу. Однако этот атрибут имеет множество недостатков и проблем с доступностью. Основная проблема заключается в том, что навигация по фокусу, упорядоченная по tabindex, созданная с использованием положительного tabindex, не распознается деревом доступности. При неправильном использовании вы можете получить неровный порядок фокусировки, который не будет соответствовать восприятию программы чтения с экрана. Чтобы это исправить, отслеживайте порядок с помощью 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 становится владельцем области фокуса. Это означает, что область навигации с последовательным фокусом ограничивается посещением каждого элемента внутри контейнера перед переходом к следующему фокусируемому элементу в веб-документе. Кроме того, его прямые дочерние элементы упорядочиваются с использованием свойства read-flow, а положительный tabindex игнорируется в целях упорядочения. Все еще возможно установить положительный tabindex для потомков элемента потока чтения.

Обратите внимание, что элемент с display: contents , который наследует свойство reading-flow от своего родителя макета, также будет допустимым контейнером потока чтения. Помните об этом при разработке вашего сайта. Подробнее об этом читайте в нашем запросе на отзыв о reading-flow и display: contents .

Дайте нам знать

Попробуйте примеры из этого поста и примеры reading-flow на chrome.dev и используйте эти свойства CSS на своих сайтах. Если у вас есть какие-либо отзывы, сообщите об этом как о проблеме в репозитории Рабочей группы CSS на GitHub . Если у вас есть отзывы конкретно о табиндексе и поведении области действия фокуса, сообщите об этом как о проблеме в репозитории HTML WHATNOT GitHub . Мы будем рады вашим отзывам об этой функции.

,

Опубликовано: 1 мая 2025 г.

Свойства reading-flow и reading-order CSS доступны в Chrome 137. В этом посте объясняются причины создания этих свойств и некоторые краткие сведения, которые помогут вам начать с ними работать.

Такие методы компоновки, как сетка и гибкая система, изменили разработку внешнего интерфейса, однако их гибкость может вызвать проблемы у некоторых пользователей. Очень легко создать ситуацию, когда визуальный порядок не соответствует исходному порядку в дереве DOM. Поскольку браузер следует этому исходному порядку, если вы перемещаетесь по сайту с помощью клавиатуры, некоторые пользователи могут столкнуться с неожиданными прыжками при навигации по странице.

Свойства reading-flow и reading-order были разработаны и добавлены в спецификацию CSS Display , чтобы попытаться решить эту давнюю проблему.

reading-flow

Свойство CSS reading-flow управляет порядком, в котором элементы в гибком, сеточном или блочном макете подвергаются воздействию инструментов специальных возможностей, а также то, как они фокусируются с помощью методов линейной последовательной навигации.

Он принимает одно значение ключевого слова со значением по умолчанию normal , которое сохраняет поведение упорядочивания элементов в порядке DOM. Чтобы использовать его внутри гибкого контейнера, установите для него значение flex-visual или flex-flow . Чтобы использовать его внутри контейнера сетки, установите его значение либо в grid-rows , либо grid-columns , либо grid-order .

reading-order

Свойство CSS reading-order позволяет вручную переопределить порядок элементов в контейнере потока чтения. Чтобы использовать это свойство внутри контейнера сетки, гибкого или блочного контейнера, установите для значения reading-flow в контейнере значение source-order , а для reading-order отдельного элемента — целочисленное значение.

Пример во флексбоксе

Например, у вас может быть контейнер гибкого макета с тремя элементами в обратном порядке строк, и вы также хотите использовать свойство 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;
}

Порядок фокуса теперь обратный порядок гибкости: два, три, один. В обоих случаях учитывается свойство order CSS.

Пример с сеткой

Чтобы увидеть, как это работает в сетке, представьте, что вы создаете макет с автоматически размещаемыми элементами 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 .

Взаимодействие с табиндексом

Исторически разработчики использовали глобальный атрибут HTML tabindex , чтобы сделать HTML-элементы фокусируемыми и определить относительный порядок для последовательной навигации по фокусу. Однако этот атрибут имеет множество недостатков и проблем с доступностью. Основная проблема заключается в том, что навигация по фокусу, упорядоченная по tabindex, созданная с использованием положительного tabindex, не распознается деревом доступности. При неправильном использовании вы можете получить неровный порядок фокусировки, который не будет соответствовать восприятию программы чтения с экрана. Чтобы это исправить, отслеживайте порядок с помощью 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 становится владельцем области фокуса. Это означает, что область навигации с последовательным фокусом ограничивается посещением каждого элемента внутри контейнера перед переходом к следующему фокусируемому элементу в веб-документе. Кроме того, его прямые дочерние элементы упорядочиваются с использованием свойства read-flow, а положительный tabindex игнорируется в целях упорядочения. Все еще возможно установить положительный tabindex для потомков элемента потока чтения.

Обратите внимание, что элемент с display: contents , который наследует свойство reading-flow от своего родителя макета, также будет допустимым контейнером потока чтения. Помните об этом при разработке вашего сайта. Подробнее об этом читайте в нашем запросе на отзыв о reading-flow и display: contents .

Дайте нам знать

Попробуйте примеры из этого поста и примеры reading-flow на chrome.dev и используйте эти свойства CSS на своих сайтах. Если у вас есть какие-либо отзывы, сообщите об этом как о проблеме в репозитории Рабочей группы CSS на GitHub . Если у вас есть отзывы конкретно о табиндексе и поведении области действия фокуса, сообщите об этом как о проблеме в репозитории HTML WHATNOT GitHub . Мы будем рады вашим отзывам об этой функции.

,

Опубликовано: 1 мая 2025 г.

Свойства reading-flow и reading-order CSS доступны в Chrome 137. В этом посте объясняются причины создания этих свойств и некоторые краткие сведения, которые помогут вам начать с ними работать.

Такие методы компоновки, как сетка и гибкая система, изменили разработку внешнего интерфейса, однако их гибкость может вызвать проблемы у некоторых пользователей. Очень легко создать ситуацию, когда визуальный порядок не соответствует исходному порядку в дереве DOM. Поскольку браузер следует этому исходному порядку, если вы перемещаетесь по сайту с помощью клавиатуры, некоторые пользователи могут столкнуться с неожиданными прыжками при навигации по странице.

Свойства reading-flow и reading-order были разработаны и добавлены в спецификацию CSS Display , чтобы попытаться решить эту давнюю проблему.

reading-flow

Свойство CSS reading-flow управляет порядком, в котором элементы в гибком, сеточном или блочном макете подвергаются воздействию инструментов специальных возможностей, а также то, как они фокусируются с помощью методов линейной последовательной навигации.

Он принимает одно значение ключевого слова со значением по умолчанию normal , которое сохраняет поведение упорядочивания элементов в порядке DOM. Чтобы использовать его внутри гибкого контейнера, установите для него значение flex-visual или flex-flow . Чтобы использовать его внутри контейнера сетки, установите его значение либо в grid-rows , либо grid-columns , либо grid-order .

reading-order

Свойство CSS reading-order позволяет вручную переопределить порядок элементов в контейнере потока чтения. Чтобы использовать это свойство внутри контейнера сетки, гибкого или блочного контейнера, установите для значения reading-flow в контейнере значение source-order , а для reading-order отдельного элемента — целочисленное значение.

Пример во флексбоксе

Например, у вас может быть контейнер гибкого макета с тремя элементами в обратном порядке строк, и вы также хотите использовать свойство 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;
}

Порядок фокуса теперь обратный порядок гибкости: два, три, один. В обоих случаях учитывается свойство order CSS.

Пример с сеткой

Чтобы увидеть, как это работает в сетке, представьте, что вы создаете макет с автоматически размещаемыми элементами 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 .

Взаимодействие с табиндексом

Исторически разработчики использовали глобальный атрибут HTML tabindex , чтобы сделать HTML-элементы фокусируемыми и определить относительный порядок для последовательной навигации по фокусу. Однако этот атрибут имеет множество недостатков и проблем с доступностью. Основная проблема заключается в том, что навигация по фокусу, упорядоченная по tabindex, созданная с использованием положительного tabindex, не распознается деревом доступности. При неправильном использовании вы можете получить неровный порядок фокусировки, который не будет соответствовать восприятию программы чтения с экрана. Чтобы это исправить, отслеживайте порядок с помощью 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 становится владельцем области фокуса. Это означает, что область навигации с последовательным фокусом ограничивается посещением каждого элемента внутри контейнера перед переходом к следующему фокусируемому элементу в веб-документе. Кроме того, его прямые дочерние элементы упорядочиваются с использованием свойства read-flow, а положительный tabindex игнорируется в целях упорядочения. Все еще возможно установить положительный tabindex для потомков элемента потока чтения.

Обратите внимание, что элемент с display: contents , который наследует свойство reading-flow от своего родителя макета, также будет допустимым контейнером потока чтения. Помните об этом при разработке вашего сайта. Подробнее об этом читайте в нашем запросе на отзыв о reading-flow и display: contents .

Дайте нам знать

Попробуйте примеры из этого поста и примеры reading-flow на chrome.dev и используйте эти свойства CSS на своих сайтах. Если у вас есть какие-либо отзывы, сообщите об этом как о проблеме в репозитории Рабочей группы CSS на GitHub . Если у вас есть отзывы конкретно о табиндексе и поведении области действия фокуса, сообщите об этом как о проблеме в репозитории HTML WHATNOT GitHub . Мы будем рады вашим отзывам об этой функции.

,

Опубликовано: 1 мая 2025 г.

Свойства reading-flow и reading-order CSS доступны в Chrome 137. В этом посте объясняются причины создания этих свойств и некоторые краткие сведения, которые помогут вам начать с ними работать.

Такие методы компоновки, как сетка и гибкая система, изменили разработку внешнего интерфейса, однако их гибкость может вызвать проблемы у некоторых пользователей. Очень легко создать ситуацию, когда визуальный порядок не соответствует исходному порядку в дереве DOM. Поскольку браузер следует этому исходному порядку, если вы перемещаетесь по сайту с помощью клавиатуры, некоторые пользователи могут столкнуться с неожиданными прыжками при навигации по странице.

Свойства reading-flow и reading-order были разработаны и добавлены в спецификацию CSS Display , чтобы попытаться решить эту давнюю проблему.

reading-flow

Свойство CSS reading-flow управляет порядком, в котором элементы в гибком, сеточном или блочном макете подвергаются воздействию инструментов специальных возможностей, а также то, как они фокусируются с помощью методов линейной последовательной навигации.

Он принимает одно значение ключевого слова со значением по умолчанию normal , которое сохраняет поведение упорядочивания элементов в порядке DOM. Чтобы использовать его внутри гибкого контейнера, установите для него значение flex-visual или flex-flow . Чтобы использовать его внутри контейнера сетки, установите его значение либо в grid-rows , либо grid-columns , либо grid-order .

reading-order

Свойство CSS reading-order позволяет вручную переопределить порядок элементов в контейнере потока чтения. Чтобы использовать это свойство внутри контейнера сетки, гибкого или блочного контейнера, установите для значения reading-flow в контейнере значение source-order , а для reading-order отдельного элемента — целочисленное значение.

Пример во флексбоксе

Например, у вас может быть контейнер гибкого макета с тремя элементами в обратном порядке строк, и вы также хотите использовать свойство 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;
}

Порядок фокуса теперь обратный порядок гибкости: два, три, один. В обоих случаях учитывается свойство order CSS.

Пример с сеткой

Чтобы увидеть, как это работает в сетке, представьте, что вы создаете макет с автоматически размещаемыми элементами 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 .

Взаимодействие с табиндексом

Исторически разработчики использовали глобальный атрибут HTML tabindex , чтобы сделать HTML-элементы фокусируемыми и определить относительный порядок для последовательной навигации по фокусу. Однако этот атрибут имеет множество недостатков и проблем с доступностью. Основная проблема заключается в том, что навигация по фокусу, упорядоченная по tabindex, созданная с использованием положительного tabindex, не распознается деревом доступности. При неправильном использовании вы можете получить неровный порядок фокусировки, который не будет соответствовать восприятию программы чтения с экрана. Чтобы это исправить, отслеживайте порядок с помощью 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 становится владельцем области фокуса. Это означает, что область навигации с последовательным фокусом ограничивается посещением каждого элемента внутри контейнера перед переходом к следующему фокусируемому элементу в веб-документе. Кроме того, его прямые дочерние элементы упорядочиваются с использованием свойства read-flow, а положительный tabindex игнорируется в целях упорядочения. Все еще возможно установить положительный tabindex для потомков элемента потока чтения.

Обратите внимание, что элемент с display: contents , который наследует свойство reading-flow от своего родителя макета, также будет допустимым контейнером потока чтения. Помните об этом при разработке вашего сайта. Узнайте больше об этом в нашем запросе обратной связи по reading-flow и display: contents .

Дайте нам знать

Попробуйте примеры в этом посте и в примерах reading-flow на Chrome.dev и используйте эти свойства CSS на ваших сайтах. Если у вас есть какие -либо отзывы, поднимите ее в качестве проблемы в рабочей группе CSS Github Repo . Если у вас есть обратная связь специально для табдекса и поведения фокусировки, поднимите ее как проблему с HTML GitHub Repo . Нам бы понравились ваши отзывы об этой функции.