Как создать адаптивные вкладки (табы) с помощью CSS и JavaScript
Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)
В этом руководстве мы узнаем, как создать отзывчивые вкладки с помощью CSS и немного JavaScript. Вполне возможно создавать вкладки на чистом CSS, но для этого примера давайте на практике наработаем наши навыки JavaScript.
Вот что мы собираемся сделать в несколько больших шагов:
Примечание: Это руководство не нацелено на то, как сделать вкладки доступными, поэтому это безусловно, будет правильным следующим шагом.
1. HTML
Для начала рассмотрим требуемую разметку. У нас есть контейнер, который включает сами вкладки (элементы списка), а также содержимое каждой вкладки (панель вкладок). Чтобы связать вкладку с соответствующей панелью, мы используем пользовательский атрибут data-index, который содержит уникальное значение для каждой панели вкладок. Тем не менее, из-за нумерации, начинающейся с нуля, панель с data-index = 0 связана с первой вкладкой, панель с data-index = 1 связана со второй и так далее.
Вот разметка HTML:
1 |
<div class="tabs-container"> |
2 |
<ul class="tabs"> |
3 |
<li class="active"> |
4 |
<a href="">Part 1</a> |
5 |
</li>
|
6 |
<li>
|
7 |
<a href="">Part 2</a> |
8 |
</li>
|
9 |
<li>
|
10 |
<a href="">Part 3</a> |
11 |
</li>
|
12 |
</ul>
|
13 |
<div class="tabs-content"> |
14 |
<div class="tabs-panel active" data-index="0"> |
15 |
<!-- content here -->
|
16 |
</div>
|
17 |
<div class="tabs-panel" data-index="1"> |
18 |
<!-- content here -->
|
19 |
</div>
|
20 |
<div class="tabs-panel" data-index="2"> |
21 |
<!-- content here -->
|
22 |
</div>
|
23 |
</div>
|
24 |
</div>
|
2. CSS
В качестве следующего шага давайте укажем несколько правил CSS для нашего компонента. Ничего особенного, просто некоторые основные стили. Следует отметить, что мы не используем никаких переходов (например, fade, slide) для переключения между вкладками; вместо этого они появляются и исчезают с помощью простого переключателя on/off.
Вот начальные стили:
1 |
.tabs-container { |
2 |
max-width: 1000px; |
3 |
margin: 50px auto; |
4 |
padding: 25px; |
5 |
}
|
6 |
|
7 |
.tabs { |
8 |
display: flex; |
9 |
}
|
10 |
|
11 |
.tabs li:not(:last-child) { |
12 |
margin-right: 7px; |
13 |
}
|
14 |
|
15 |
.tabs li a { |
16 |
display: block; |
17 |
position: relative; |
18 |
top: 4px; |
19 |
padding: 10px 25px; |
20 |
border-radius: 2px 2px 0 0; |
21 |
background: white; |
22 |
opacity: 0.7; |
23 |
transition: all 0.1s ease-in-out; |
24 |
}
|
25 |
|
26 |
.tabs li.active a, |
27 |
.tabs li a:hover { |
28 |
opacity: 1; |
29 |
top: 0; |
30 |
}
|
31 |
|
32 |
.tabs-content { |
33 |
position: relative; |
34 |
z-index: 2; |
35 |
padding: 25px; |
36 |
border-radius: 0 4px 4px 4px; |
37 |
background: white; |
38 |
}
|
39 |
|
40 |
.tabs-panel { |
41 |
display: none; |
42 |
}
|
43 |
|
44 |
.tabs-panel.active { |
45 |
display: block; |
46 |
}
|
3. JavaScript
HTML и CSS на месте, теперь пришло время посмотреть на требуемый код JavaScript.
Каждый раз, когда мы нажимаем на вкладку, мы делаем следующее:
- Удаляем класс
activeс соответствующей вкладки (по умолчанию первой) и с соответствующей панели вкладки (по умолчанию первой). - Находим родительский элемент
liэтой вкладки, добавляем к нему классactiveи возвращаем его индекс. - Находим панель вкладок, значение атрибута которой (для атрибута
data-index) соответствует указанному выше значению индекса и присваивает ей классactive.
Вот результат кода JavaScript:
1 |
const tabLinks = document.querySelectorAll(".tabs a"); |
2 |
const tabPanels = document.querySelectorAll(".tabs-panel"); |
3 |
|
4 |
for(let el of tabLinks) { |
5 |
el.addEventListener("click", e => { |
6 |
e.preventDefault(); |
7 |
|
8 |
document.querySelector('.tabs li.active').classList.remove("active"); |
9 |
document.querySelector('.tabs-panel.active').classList.remove("active"); |
10 |
|
11 |
const parentListItem = el.parentElement; |
12 |
parentList.classList.add("active"); |
13 |
const index = [...parentListItem.parentElement.children].indexOf(parentListItem); |
14 |
|
15 |
const panel = [...tabPanels].filter(el => el.getAttribute("data-index") == index); |
16 |
panel[0].classList.add("active"); |
17 |
});
|
18 |
}
|
4. Делаем адаптивность
Наш компонент почти готов! Последнее, что нам нужно сделать, это сделать компонент адаптивным. Так, например, когда область просмотра имеет максимальную ширину 600 пикселей, она должна коллапсировать и выглядеть следующим образом:



Поскольку мы используем desktop-first подход, вот правила CSS, которые мы должны перезаписать:
1 |
@media screen and (max-width: 600px) { |
2 |
.tabs { |
3 |
flex-direction: column; |
4 |
}
|
5 |
|
6 |
.tabs li { |
7 |
width: 100%; |
8 |
}
|
9 |
|
10 |
.tabs li:not(:last-child) { |
11 |
margin-right: 0; |
12 |
}
|
13 |
|
14 |
.tabs li a { |
15 |
border-radius: 0; |
16 |
opacity: 1; |
17 |
top: 0; |
18 |
}
|
19 |
|
20 |
.tabs li.active a::before { |
21 |
content: '•'; |
22 |
padding-right: 5px; |
23 |
}
|
24 |
|
25 |
.tabs-content { |
26 |
border-radius: 0; |
27 |
}
|
28 |
}
|
5. Поддерживаемые браузеры
Наше демо хорошо работает во всех последних браузерах и устройствах. Как обычно, в моих руководствах мы используем Babel для компиляции кода ES6 до ES5.
Заключение
В этом кратком руководстве нам удалось создать полезный адаптивный компонент Вкладки с HTML, CSS и JavaScript. Опять же, этот компонент имеет не очень хорошую доступность, но если вы хотите улучшить его функциональность, это будет хорошим следующим шагом. Хорошего кода!


Веб Доступность (Accessibility)Руководство для начинающих по Веб ДоступностиJohn Hartley

Доступность (Accessibility)Создание инклюзивного веба: Почему Важна ДоступностьSami Keijonen

Доступность (Accessibility)3 совета по Доступности, которые я хотел бы знать раньшеJoanna Ngai

Доступность (Accessibility)Основы Доступности: дизайн для людей с проблемами зренияGraeme Fulton



