Обновлено 2026/05/14
Вкладки (Tabs) — популярный элемент интерфейса, который позволяет компактно отображать контент без перегрузки страницы. Они используются в документации, карточках товаров, настройках, FAQ-блоках и административных панелях.
Ранее для создания вкладок часто использовали jQuery-плагины. Сегодня большинство задач решается средствами нативного JavaScript и современного CSS без подключения сторонних библиотек.
В этой статье рассмотрим два актуальных способа создания вкладок:
Современные вкладки:
Vanilla JS позволяет создавать гибкие вкладки без внешних зависимостей и полностью контролировать логику интерфейса.
<div class="js-tabs">
<div class="js-tabs-nav"
role="tablist">
<button
class="js-tab-button active"
data-tab="content-1"
role="tab"
aria-selected="true">
HTML
</button>
<button
class="js-tab-button"
data-tab="content-2"
role="tab"
aria-selected="false">
CSS
</button>
<button
class="js-tab-button"
data-tab="content-3"
role="tab"
aria-selected="false">
JavaScript
</button>
</div>
<div id="content-1"
class="js-tab-content active"
role="tabpanel">
<h3>HTML-разметка</h3>
<p>Содержимое первой вкладки.</p>
</div>
<div id="content-2"
class="js-tab-content"
role="tabpanel">
<h3>CSS</h3>
<p>Содержимое второй вкладки.</p>
</div>
<div id="content-3"
class="js-tab-content"
role="tabpanel">
<h3>JavaScript</h3>
<p>Содержимое третьей вкладки.</p>
</div>
</div>
.js-tabs {
border: 1px solid #dee2e6;
border-radius: 8px;
overflow: hidden;
background: #ffffff;
}
.js-tabs-nav {
display: flex;
flex-wrap: wrap;
gap: 0;
border-bottom: 1px solid #dee2e6;
background: #f8f9fa;
}
.js-tab-button {
padding: 14px 20px;
border: none;
background: transparent;
cursor: pointer;
font-weight: 600;
transition:
background .3s ease,
color .3s ease;
}
.js-tab-button:hover {
background: #e9ecef;
}
.js-tab-button.active {
background: #ffffff;
color: #0d6efd;
border-bottom: 2px solid #0d6efd;
}
.js-tab-content {
display: none;
padding: 20px;
}
.js-tab-content.active {
display: block;
}
document.addEventListener('DOMContentLoaded', function () {
const buttons =
document.querySelectorAll('.js-tab-button');
const contents =
document.querySelectorAll('.js-tab-content');
buttons.forEach(function(button) {
button.addEventListener('click', function() {
buttons.forEach(function(btn) {
btn.classList.remove('active');
btn.setAttribute(
'aria-selected',
'false'
);
});
contents.forEach(function(content) {
content.classList.remove('active');
});
button.classList.add('active');
button.setAttribute(
'aria-selected',
'true'
);
document
.getElementById(button.dataset.tab)
.classList.add('active');
});
});
});
При клике на кнопку JavaScript:
Такой подход работает во всех современных браузерах и не требует сторонних библиотек.
Для улучшения доступности используются ARIA-атрибуты:
role="tablist" — контейнер вкладок;role="tab" — кнопка вкладки;role="tabpanel" — содержимое вкладки;aria-selected — состояние активной вкладки.Это улучшает работу экранных дикторов и соответствует современным требованиям Accessibility.
Для простых интерфейсов вкладки можно реализовать полностью на CSS без JavaScript.
<div class="tabs-component">
<div class="tabs-nav"
role="tablist">
<input
type="radio"
name="tabs"
id="tab-1"
checked>
<label
for="tab-1"
role="tab">
HTML
</label>
<input
type="radio"
name="tabs"
id="tab-2">
<label
for="tab-2"
role="tab">
CSS
</label>
<input
type="radio"
name="tabs"
id="tab-3">
<label
for="tab-3"
role="tab">
JavaScript
</label>
</div>
<div class="tabs-content">
<section
class="tab-panel panel-1"
role="tabpanel">
<h3>HTML</h3>
<p>Содержимое первой вкладки.</p>
</section>
<section
class="tab-panel panel-2"
role="tabpanel">
<h3>CSS</h3>
<p>Содержимое второй вкладки.</p>
</section>
<section
class="tab-panel panel-3"
role="tabpanel">
<h3>JavaScript</h3>
<p>Содержимое третьей вкладки.</p>
</section>
</div>
</div>
.tabs-component {
border: 1px solid #dee2e6;
border-radius: 8px;
overflow: hidden;
background: #ffffff;
}
.tabs-nav {
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid #dee2e6;
background: #f8f9fa;
}
.tabs-nav input {
display: none;
}
.tabs-nav label {
padding: 14px 20px;
cursor: pointer;
font-weight: 600;
transition:
background .3s ease,
color .3s ease;
margin: 0;
}
.tabs-nav label:hover {
background: #e9ecef;
}
.tab-panel {
display: none;
padding: 20px;
}
#tab-1:checked ~ .tabs-content .panel-1,
#tab-2:checked ~ .tabs-content .panel-2,
#tab-3:checked ~ .tabs-content .panel-3 {
display: block;
}
#tab-1:checked + label,
#tab-2:checked + label,
#tab-3:checked + label {
background: #ffffff;
color: #0d6efd;
border-bottom: 2px solid #0d6efd;
}
Механика основана на скрытых radio-кнопках.
<input type="radio">
При выборе radio input CSS показывает соответствующую панель:
#tab-1:checked ~ .tabs-content .panel-1 {
display: block;
}
Такой подход хорошо подходит для простых интерфейсов без сложной логики.
На смартфонах горизонтальные вкладки могут занимать слишком много места.
Для адаптации используется media query:
@media (max-width: 576px) {
.js-tabs-nav,
.tabs-nav {
flex-direction: column;
}
.js-tab-button,
.tabs-nav label {
width: 100%;
text-align: left;
border-bottom: 1px solid #dee2e6;
}
}
На небольших экранах вкладки будут отображаться вертикально.
| Сценарий | CSS | Vanilla JS |
|---|---|---|
| Простые вкладки | Да | Да |
| Сложная логика | Нет | Да |
| Динамическая загрузка контента | Нет | Да |
| Максимальная производительность | Да | Да |
| Минимум кода | Да | Нет |
| Гибкость интерфейса | Ограничена | Высокая |
Современные поисковые системы индексируют контент внутри вкладок, если:
Для создания вкладок сегодня чаще всего используются:
По сравнению со старыми jQuery-плагинами современные решения: