⚙️
Front-end patterns
  • Введение
  • Шаблоны
    • Эффекты CSS
      • Overlay
      • Анимация display:none
      • Текст
        • Фон текста градиент с анимацией
      • Элементы формы
        • Вертикальное выравнивание placeholder по вертикали
      • Ссылки
        • Градиент как основной цвет
        • Линия под ссылкой ездит слева направо при наведении
      • Скрывать блок .clipped
    • Модальное окно
      • Dialog
    • Элементы формы
      • Select
      • Radio
      • CheckBox
      • Ввод текста (input)
        • Телефон (tel)
        • Почта (email)
      • Кнопка
    • Вкладки/Списки
      • Вкладки или Табы (tabs)
      • Аккордеон (Accordion)
    • Навигация
      • Основная и дополнительная навигация на сайте
        • Анимирование основной навигации
      • Пропустить навигацию
      • Хлебные крошки (Breadcrumbs)
      • Кнопка основной навигации (Бургер)
    • Структуры
      • Контейнер
      • Столбцы
      • Прогресс
      • Горизонтальная прокрутка карточек
      • Цитата
    • Тэги (семантика)
      • Текст
      • Логика
    • Увеличить скорость загрузки страницы
    • Шрифты
  • JS
    • Прокрутка страницы
    • Анимация элементов
  • A11Y
    • Фокус с клавиатуры
    • No sort
  • WordPress
    • Решения и подсказки
    • Плагины
    • Натягиваем сайт
      • Пустая тема
      • Делаем главную (пустую) страницу
      • Подключаем стили и js
      • Заменяем содержимое файлов (header, footer, page)
    • Свой плагин
      • Шаблон
      • Административная часть
      • Пользовательская часть
      • Локализация плагина
  • Ghost
    • Создание своей темы
      • Фалы шаблона
        • Partials
          • footer.hbs
          • header.hbs
          • post_card.hbs
        • index.hbs
        • default.hbs
        • post.hbs
      • Переменные
      • Циклы, условия и функции
  • Visual Studio
  • Gulp
    • Deploy on GitHub
    • Плагин
    • Моя сборка
      • Изображения
  • Регулярные выражения
  • Алгоритмы
    • Поиск
    • Сортировка
    • Поиск в ширину (глубину)
    • Типы данных
  • Конструкторы сайтов
Powered by GitBook
On this page
  • Основные данные
  • Терминология
  • Параметры
  • Лучшая практика
  • Интерактивный дизайн
  • Управление клавиатурой
  • Screenreader
  • Руководство для разработчиков
  • Content (HTML)
  • Checkpoint
  • Presentation (CSS)
  • Checkpoint
  • Behaviour (JS)
  • Plugin Boilerplate
  • ARIA Roles
  • Удалить поведение ссылки
  • ARIA States
  • ARIA Properties
  • Roving Tabindex
  • State Management
  • Prevent Page Scroll
  • Widget Init
  • Utilities

Was this helpful?

  1. Шаблоны
  2. Вкладки/Списки

Вкладки или Табы (tabs)

PreviousВкладки/СпискиNextАккордеон (Accordion)

Last updated 9 months ago

Was this helpful?

Основные данные

Основной ресурс откуда взята информация -

Вкладка — это элемент управления, который позволяет пользователю выбирать и отображать одну панель содержимого из группы вариантов. Упрощая таким образом пользовательский интерфейс, что следуют принципу постепенного раскрытия информации.

Выбор вкладки должен обновить видимую панель без полной перезагрузки страницы.

Терминология

  • tabs: шаблон в целом, содержащие список таблиц, вкладки и панели вкладок

  • menu: заголовок, который непосредственно предшествует виджету вкладок

  • tab list: содержит две или более вкладок

  • tab: тип кнопки, которая отображает связанную с ней вкладку

  • selected tab: выбранная в данный момент вкладка

  • tab panel: содержит все, связанное с вкладкой

  • tab heading: заголовок за кадром, сохраняющий правильную структуру заголовка

Параметры

  • autoSelect: для пользователей клавиатуры выбор вкладки может либо следовать за фокусом клавиатуры (известный как автоматический выбор), либо требовать дополнительного нажатия клавиши ВВОД или ПРОБЕЛ для установки выбора (известный как ручной выбор).

Лучшая практика

Список вкладок должен предваряться заголовком. Все вкладки должны быть тематически связаны с этим заголовком. Например, набор вкладок «Службы доставки» может содержать вкладку для USPS, FedEx и UPS.

Чтобы поддерживать правильную структуру заголовков, панели вкладок должны содержать заголовок за пределами экрана. Уровень заголовка этой панели должен быть ровно на один уровень ниже заголовка, предшествующего табличному списку. Текст заголовка должен совпадать с соответствующим текстом вкладки.

В списке вкладок должна быть ровно одна выбранная вкладка.

Если все содержимое панели вкладок отображается при загрузке страницы, вкладки должны быть настроены с включенным автовыбором.

Если все содержимое панели вкладок загружается на клиенте "лениво" (т. е. с использованием вызова AJAX), вкладки должны быть настроены с отключенным автовыбором.

Интерактивный дизайн

Управление клавиатурой

Только одна вкладка может быть активна с клавиатуры в любой момент времени. Это называется передвижным индексом вкладок.

Для вкладок с включенным автовыбором клавиши СТРЕЛКИ перемещают фокус клавиатуры на следующую/предыдущую вкладку и выбирают эту вкладку (например, aria-selected="true").

Для вкладок без включенного автовыбора клавиши СТРЕЛКИ перемещают фокус клавиатуры на следующую/предыдущую вкладку, но для установки вкладки в выбранное состояние требуется клавиша ВВОД или ПРОБЕЛ.

Если панель вкладок содержит элемент(ы) с фокусом, клавиша TAB на выбранной вкладке должна переместить фокус на первый элемент на панели вкладок, на который можно сделать фокус.

Если панель вкладок не содержит фокусируемых элементов, клавиша TAB на выбранной вкладке должна переместить фокус на следующий фокусируемый элемент на странице.

Screenreader

Вкладка должна быть объявлена как «Вкладка».

Метка вкладки должна быть объявлена, например, «Выберите доставку для меня».

Состояние выбора вкладки должно быть объявлено.

Навигация с виртуальным курсором может перемещаться от вкладки к вкладке без изменения выбора активной вкладки.

Руководство для разработчиков

В нашем первом примере реализации будет создан виджет вкладок с включенной конфигурацией автовыбора. Все содержимое панели вкладок будет отображаться в DOM при загрузке на стороне сервера.

Образец соответствует стратегии прогрессивного улучшения; мы строим послойно, что позволяет каждому получить доступ к основному содержанию и функциям веб-страницы.

Три слоя:

Content (HTML)

Presentation (CSS)

Behaviour (JS)

Вкладки и связанные с ними элементы содержимого могут быть полностью видны и доступны без CSS и JavaScript в виде простых гиперссылок и привязок страниц соответственно.

Для виджета вкладок, содержимое которого не отображается при первой загрузке на стороне сервера, использование этого подхода с прогрессивным улучшением неприменимо.

Content (HTML)

Цель нашего слоя контента — добавить на страницу все наши вкладки и соответствующие им панели. Для целей этого примера все содержимое панели будет отображаться на стороне сервера. Вы можете рассмотреть возможность ленивой загрузки содержимого каждой панели с помощью AJAX. Если вы используете отложенную загрузку, имейте в виду, что ваш контент будет недоступен в сценарии, отличном от JavaScript.

Ссылки

Вкладки начинают свою жизнь как простые навигационные ссылки на той же странице, ссылаясь на якоря контента (панели) под ними на той же странице:

<div class="tabs tabs--horizontal">
    <h2>My eBay</h2>
    <ul class="tabs__items">
        <li class="tabs__item"><a href="#buying">Buying</a></li>
        <li class="tabs__item"><a href="#bought">Bought</a></li>
        <li class="tabs__item"><a href="#selling">Selling</a></li>
        <li class="tabs__item"><a href="#sold">Sold</a></li>
    </ul>
    <div class="tabs__content">
        <div class="tabs__panel" id="buying" tabindex="-1">
            <h3>...</h3>
            <p>...</p>
        </div>
        <div class="tabs__panel" id="bought" tabindex="-1">
            <h3>...</h3>
            <p>...</p>
        </div>
        <div class="tabs__panel" id="selling" tabindex="-1">
            <h3>...</h3>
            <p>...</p>
        </div>
        <div class="tabs__panel" id="sold" tabindex="-1">
            <h3>...</h3>
            <p>...</p>
        </div>
    </div>
</div>

Мы называем эту структуру разметки нашими костями; наши CSS и JavaScript будут ожидать именно этого соглашения о структуре DOM.

Эта структура была выбрана тщательно. Это позволяет нам отображать вкладки горизонтально и вертикально, просто изменив второй класс (на вкладки - горизонтальные или вкладки - вертикальные).

Checkpoint

Вот и все! Наш контент доступен и доступен любому, кто не использует CSS или JS.

Presentation (CSS)

Цель нашего слоя представления — стилизовать ссылки, чтобы они выглядели как вкладки в стиле папок. То, как вы решите стилизовать ссылки, выходит за рамки этого документа, потому что каждый веб-сайт любит, чтобы его вкладки выглядели немного по-разному!

Flash of Unstyled Content (FOUC)

FOUC может произойти до того, как JavaScript инициализирует виджет, т. е. все содержимое панели может быть видно на короткое время. Один из способов облегчить это — установить фиксированную высоту контейнера панели вкладок:

/* before js init */
.tabs__content {
    height: 150px;
    overflow-y: auto;
}
/* after js init */
.tabs--js .tabs__content {
    height: auto;
}

Для нашего примера мы выбрали произвольное значение 150 пикселей. После того, как наш JavaScript инициализирует виджет, его высота будет увеличиваться или уменьшаться в соответствии с содержимым текущей выбранной панели. Конечно, если вам нужна фиксированная высота, вы можете оставить фиксированное значение на месте.

Checkpoint

Наши вкладки теперь выглядят как вкладки, а содержимое панели по-прежнему полностью работоспособно без JavaScript (хотя и с уродливыми вертикальными полосами прокрутки).

Behaviour (JS)

Цель нашего JavaScript — реализовать наш дизайн взаимодействия.

Plugin Boilerplate

Начнем с кэширования ссылок на самые важные элементы:

module.exports = class {
    constructor(widgetEl) {
        this._el = widgetEl;

        const tabList = this._el.querySelector('.tabs__items', this._el);
        const tabs = Util.querySelectorAllToArray('.tabs__item', this._el);
        const panels = Util.querySelectorAllToArray('.tabs__panel', this._el);
        const links = Util.querySelectorAllToArray('a', tabList);
    }
}

ARIA Roles

Как программа чтения с экрана узнает, что это виджет вкладок? Мы должны добавить роли ARIA в список вкладок, вкладки и панели.

tabList.setAttribute('role', 'tablist');
tabs.forEach(el => el.setAttribute('role', 'tab'));
panels.forEach(el => el.setAttribute('role', 'tabpanel'));

Удалить поведение ссылки

В настоящее время у нас есть ссылки, вложенные в наши элементы вкладок. Чтобы избежать конфликтов с нашими вкладками, мы должны удалить любую семантику и поведение, эффективно превратив их в теги span.

function removeLink(el) {
    el.setAttribute('role', 'presentation');
    el.removeAttribute('href');
}

ARIA States

Как средство чтения с экрана узнает, какая вкладка выбрана в данный момент и какая панель видна? Мы должны добавить состояния aria-selected и hidden.

let initialIndex = this._options.initialIndex;

tabs[initialIndex].setAttribute('aria-selected', 'true');

// hide all unselected panels
panels.filter((el, i) => i !== initialIndex).forEach(el => el.hidden = true);

ARIA Properties

Как средство чтения с экрана узнает, какая панель принадлежит какой вкладке, и метку каждой панели? Мы должны добавить свойства aria-controls и aria-labelledby.

function linkTabToPanel(widgetID, el, i) {
    el.setAttribute('id', widgetID + '-tab-' + i);
    el.setAttribute('aria-controls', widgetID + '-panel-' + i);
}

function linkPanelToTab(widgetID, el, i) {
    el.setAttribute('id', widgetID + '-panel-' + i);
    el.setAttribute('aria-labelledby', widgetID + '-tab-' + i);
}

Roving Tabindex

Если есть много вкладок, потребуется много нажатий клавиши TAB для перехода мимо виджета, поэтому вместо этого навигация по вкладкам должна осуществляться с помощью клавиш со стрелками. Только одна вкладка может быть сфокусирована в любой момент времени. Это всегда "выбранная" вкладка. Когда пользователь отходит от виджета, а затем снова возвращается, фокус возвращается на эту «выбранную» вкладку. Такое поведение известно как блуждающий tabindex. Этот функционал не подкреплен примером.

State Management

При изменении перемещаемого tabindex мы должны обновить состояния aria-selected и hidden

this._el.addEventListener('rovingTabindexChange', function (e) {
    tabs[e.detail.fromIndex].setAttribute('aria-selected', 'false');
    panels[e.detail.fromIndex].hidden = true;

    tabs[e.detail.toIndex].setAttribute('aria-selected', 'true');
    panels[e.detail.toIndex].hidden = false;
});

Prevent Page Scroll

Когда выбранная вкладка имеет фокус, мы должны запретить клавишам со стрелками и пробелу прокручивать страницу. Мы предоставляем еще один модуль, make-prevent-scroll-keys, чтобы сделать это тривиальным.

const ScrollKeyPreventer = require('makeup-prevent-scroll-keys');

ScrollKeyPreventer.add(tabList);

Widget Init

Наконец, мы можем пометить наш виджет как инициализированный. Теперь вступят в силу наши правила CSS для нашего прогрессивно улучшаемого виджета.

this._el.classList.add('tabs--js');

Мы улучшили нашу разметку с помощью ролей, состояний и свойств ARIA для пользователей программ чтения с экрана, а также реализовали поведение клавиатуры.

Utilities

У нас есть несколько экспериментальных модулей JavaScript, которые могут помочь вам в создании виджета вкладок со специальными возможностями:

- Полезно для реализации поведения клавиши со стрелкой для смены вкладок.

- Полезно для предотвращения прокрутки страницы клавишами, когда фокус находится на виджете.

makeup-roving-tabindex
makeup-prevent-scroll-keys
https://ebay.gitbook.io/mindpatterns/disclosure/tabs