1. Web Design
  2. HTML/CSS
  3. HTML

Как создать адаптивные вкладки (табы) с помощью CSS и JavaScript

Scroll to top

Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)

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

Вот что мы собираемся сделать в несколько больших шагов:

Please accept marketing cookies to load this content.

Примечание: Это руководство не нацелено на то, как сделать вкладки доступными, поэтому это безусловно, будет правильным следующим шагом.

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 пикселей, она должна коллапсировать и выглядеть следующим образом:

How the tab component looks like on small screensHow the tab component looks like on small screensHow the tab component looks like on small screens

Поскольку мы используем 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.

Please accept marketing cookies to load this content.

Заключение

В этом кратком руководстве нам удалось создать полезный адаптивный компонент Вкладки с HTML, CSS и JavaScript. Опять же, этот компонент имеет не очень хорошую доступность, но если вы хотите улучшить его функциональность, это будет хорошим следующим шагом. Хорошего кода!