Создать вкладки (tabs) из свойств элемента инфоблока
Инструкция8 мин 38 Обновлено 22 июля Сложность: Средняя
TL;DR
- Контент вкладок берём из $arResult[DISPLAY_PROPERTIES] – там уже только заполненные свойства.
- Условия вида "!PROPERTY_X" бессмысленны: непустая строка в PHP всегда истинна.
- Разметка по паттерну W3C: role=tablist/tab/tabpanel, aria-selected, aria-controls.
- Вкладки – это button, а не ссылка-якорь; неактивные панели скрыты атрибутом hidden.
- Добавляем навигацию стрелками и Home/End – без неё вкладки недоступны с клавиатуры.
Вкладки удобно собирать прямо из свойств элемента инфоблока: одно свойство – одна вкладка. В исходной версии заметки для этого тянули jQuery и плагин Responsive-Tabs, а разметку строили на цепочке if/elseif с ошибочными условиями вроде "!PROPERTY_ANALYTICS" (строковый литерал всегда истинный – это ничего не проверяет). В 2026 всё делается чище: контент берём из DISPLAY_PROPERTIES в шаблоне компонента, а переключатель пишем на чистом JS по паттерну доступных вкладок W3C ARIA – с поддержкой клавиатуры и скринридеров.
Шаг 1. Выводим свойства как вкладки в шаблоне компонента
Скопируйте шаблон компонента (например, bitrix:news.detail) в свой и работайте в его template.php. Массив $arResult["DISPLAY_PROPERTIES"] содержит только заполненные свойства с готовыми к выводу значениями DISPLAY_VALUE, поэтому лишние проверки не нужны – Битрикс сам не кладёт сюда пустые свойства. Определим список свойств-вкладок и пройдёмся по нему:
<?php
$tabCodes = ['ANALYTICS', 'DESIGN', 'PROGRAMMING', 'TESTING', 'SUPPORT'];
$tabs = [];
foreach ($tabCodes as $code) {
if (!empty($arResult['DISPLAY_PROPERTIES'][$code])) {
$tabs[$code] = $arResult['DISPLAY_PROPERTIES'][$code];
}
}
?>
<?php if ($tabs): ?>
<div class="tabs">
<div class="tabs__list" role="tablist" aria-label="Информация о проекте">
<?php $i = 0; foreach ($tabs as $code => $prop): $i++; ?>
<button class="tabs__tab" role="tab"
id="tab-<?= mb_strtolower($code) ?>"
aria-controls="panel-<?= mb_strtolower($code) ?>"
aria-selected="<?= $i === 1 ? 'true' : 'false' ?>"
tabindex="<?= $i === 1 ? '0' : '-1' ?>">
<?= htmlspecialcharsbx($prop['NAME']) ?>
</button>
<?php endforeach; ?>
</div>
<?php $i = 0; foreach ($tabs as $code => $prop): $i++; ?>
<div class="tabs__panel" role="tabpanel"
id="panel-<?= mb_strtolower($code) ?>"
aria-labelledby="tab-<?= mb_strtolower($code) ?>"
<?= $i === 1 ? '' : 'hidden' ?>>
<?= $prop['DISPLAY_VALUE'] ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
Первая вкладка активна: у её кнопки aria-selected="true" и tabindex="0", у остальных – false и -1. Панели неактивных вкладок скрыты атрибутом hidden.
Шаг 2. Почему важна ARIA-разметка
Простое переключение display:none по клику «для зрячих» ломает доступность: скринридер не понимает, что это вкладки, и не сообщает, какая активна. Паттерн W3C решает это набором ролей и атрибутов:
role="tablist"– контейнер заголовков вкладок;role="tab"+aria-selected– сама вкладка и её состояние;role="tabpanel"+aria-labelledby– область контента, связанная со своей вкладкой;aria-controls– связь вкладки с панелью, которой она управляет.
Кнопки делаем настоящими <button>, а не <a href="#tab-1">: ссылки-якоря прыгают по странице и засоряют историю браузера.
Шаг 3. Доступный переключатель на чистом JS
Скрипт вешает клик и стрелочную навигацию с клавиатуры (влево/вправо, Home/End) – этого ждут пользователи скринридеров от вкладок:
document.querySelectorAll('.tabs').forEach(function (root) {
var tabs = Array.from(root.querySelectorAll('[role="tab"]'));
function activate(tab) {
tabs.forEach(function (t) {
var selected = t === tab;
t.setAttribute('aria-selected', selected);
t.tabIndex = selected ? 0 : -1;
document.getElementById(t.getAttribute('aria-controls')).hidden = !selected;
});
tab.focus();
}
root.addEventListener('click', function (e) {
var tab = e.target.closest('[role="tab"]');
if (tab) activate(tab);
});
root.addEventListener('keydown', function (e) {
var i = tabs.indexOf(document.activeElement);
if (i === -1) return;
if (e.key === 'ArrowRight') activate(tabs[(i + 1) % tabs.length]);
else if (e.key === 'ArrowLeft') activate(tabs[(i - 1 + tabs.length) % tabs.length]);
else if (e.key === 'Home') activate(tabs[0]);
else if (e.key === 'End') activate(tabs[tabs.length - 1]);
});
});Типичные ошибки
- Строковые «условия» вроде
"!PROPERTY_ANALYTICS". Непустая строка в PHP всегда истинна – такая проверка ничего не фильтрует. Проверяйте реальный ключ массиваDISPLAY_PROPERTIES. - Одинаковые id у разных вкладок. В исходнике два свойства вели на
#tab-4– id должны быть уникальны, иначе ломается связь tab↔panel. - Вкладки-ссылки вместо кнопок.
<a href="#">прыгает по странице; используйте<button>. - Нет навигации с клавиатуры. Без обработки стрелок вкладки недоступны части пользователей – это регресс по a11y.
- Забыли про кеш компонента. Правки в шаблоне могут не проявиться, пока не сброшен кеш компонента и страницы.
Похожие приёмы работы со свойствами инфоблока разобраны в гайдах «Как вывести определённое поле элемента инфоблока» и «Получить название свойства из типа Справочник». А если контент вкладок нужно показывать только на отдельных страницах – см. «Вывод блоков только на определённых страницах».
Частые вопросы
Нужен ли jQuery и плагин для вкладок в Битриксе?
Нет. Современные вкладки делаются на чистом JS по паттерну доступности W3C ARIA. Это легче, без внешних зависимостей и корректно работает со скринридерами.
Почему условие "!PROPERTY_ANALYTICS" в старом коде ничего не проверяло?
Это строковый литерал, а любая непустая строка в PHP приводится к true. Проверка всегда истинна и не фильтрует пустые свойства. Проверяйте реальный ключ массива DISPLAY_PROPERTIES через empty().
Какие ARIA-роли нужны для доступных вкладок?
Контейнер заголовков – role=tablist, каждая вкладка – role=tab с aria-selected и aria-controls, область контента – role=tabpanel с aria-labelledby. Это стандартный паттерн W3C.
Почему вкладки лучше делать кнопками, а не ссылками?
Ссылки-якоря вида a href=#tab прыгают по странице к элементу и засоряют историю браузера. Настоящий button переключает вкладку без скачков и корректно воспринимается как элемент управления.
Правки в шаблоне не видны на сайте – что делать?
Сбросьте кеш компонента и страницы в Битриксе (панель управления кешем или очистка каталога кеша). Пока действует старый кеш, изменения в template.php не отобразятся.
Материалы по теме
Что почитать дальше по этой теме