Visibility и display

Библиотека Tabbable используется для определения элементов на странице, доступных для фокусировки с помощью клавиши Tab. Основной задачей является фильтрация элементов DOM по их фокусируемости, что позволяет строить интерфейсы с корректной навигацией. Ключевым аспектом здесь является правильная обработка стилей элементов, особенно свойств visibility и display.


Свойство visibility

Свойство CSS visibility контролирует видимость элемента без удаления его из потока документа:

  • visible — элемент видим и доступен для взаимодействия.
  • hidden — элемент скрыт, но занимает место в потоке документа.
  • collapse — в контексте таблиц скрывает строку или столбец, как если бы их не существовало.

Для Tabbable visibility: hidden является критическим: такие элементы не добавляются в список табулируемых элементов, даже если у них есть атрибут tabindex или они являются стандартными фокусируемыми элементами (<input>, <button> и т.д.).

Важно отметить, что Tabbable проверяет не только стиль самого элемента, но и наследуемые свойства. Если родительский контейнер имеет visibility: hidden, все дочерние элементы также считаются недоступными для табуляции.

Пример:

<div style="visibility: hidden;">
  <button>Кнопка</button>
</div>

В этом случае библиотека не включит кнопку в результат функции tabbable().


Свойство display

Свойство CSS display определяет, как элемент размещается на странице. На поведение Tabbable это влияет сильнее, чем visibility, поскольку элементы с определёнными значениями полностью исключаются из потока и фокусировки.

  • display: none — элемент полностью удалён из визуального потока и недоступен для взаимодействия. Tabbable игнорирует такие элементы.
  • display: contents — элемент не создает собственного контейнера, но сохраняет фокусируемость дочерних элементов. Tabbable учитывает их при построении списка.
  • Любые блочные или строчные значения (block, inline, inline-block) сохраняют фокусируемость, если элемент сам по себе фокусируемый.

Особенности работы:

  1. Tabbable проверяет вычисленные стили элемента (window.getComputedStyle), чтобы определить display.
  2. Если элемент скрыт через display: none, Tabbable также проверяет, есть ли дочерние элементы, которые могли бы быть фокусируемыми. Если все дочерние элементы также скрыты — элемент полностью исключается.

Пример:

<div style="display: none;">
  <a href="#">Ссылка</a>
</div>

Ссылка не будет включена в список tabbable().

<div style="display: contents;">
  <a href="#">Ссылка</a>
</div>

Здесь ссылка будет корректно обнаружена и включена, так как её контейнер не мешает фокусировке.


Взаимодействие visibility и display

При комбинировании этих свойств нужно учитывать иерархию DOM и вычисленные стили:

display visibility Доступность для Tab
none visible нет
block/inline hidden нет
block/inline visible да
contents hidden нет
contents visible да

Вывод: Tabbable ориентируется на комбинацию этих двух свойств, игнорируя элементы, которые скрыты хотя бы одним из них.


Практическое использование

При построении динамических интерфейсов важно учитывать:

  1. Скрытие элементов через display полностью убирает их из навигации с клавиатуры.
  2. Скрытие через visibility сохраняет место, но делает элементы недоступными для Tab.
  3. Использование display: contents позволяет оставить фокусируемые дочерние элементы доступными, даже если контейнер не визуализируется.
  4. Tabbable корректно работает с вложенными скрытыми элементами — проверяется цепочка родительских стилей.

Пример с проверкой функций:

import { tabbable } from 'tabbable';

const container = document.querySelector('#form');
const focusableElements = tabbable(container);

console.log(focusableElements); // список элементов, доступных для Tab

В этом списке будут только элементы, у которых display не none и visibility не hidden, включая проверку родительских контейнеров.


Оптимизация интерфейсов

Использование visibility и display в сочетании с Tabbable позволяет:

  • Контролировать последовательность табуляции в сложных формах.
  • Исключать временно скрытые поля без удаления из DOM.
  • Разделять визуальное скрытие и доступность для фокуса, что полезно для ARIA-совместимых интерфейсов.

Эти аспекты делают работу с Tabbable гибкой, позволяя строить интерфейсы с корректной доступностью и предсказуемым поведением клавиатурной навигации.