Табы (вкладки) для сайта на CSS и JavaScript – 3 способа

Александр Мальцев
Александр Мальцев
64K
57
Табы (вкладки) для сайта на CSS и JavaScript – 3 способа
Содержание:
  1. Что такое табы
  2. Вкладки на чистом CSS
  3. Табы с использованием JavaScript
  4. Комментарии

В этой статье рассмотрим примеры вкладок для сайта, выполненных как с использованием только CSS, так и с применением JavaScript.

Что такое табы

На странице очень часто бывает необходимо вывести большое количество информации.

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

Табы (вкладки) – это как раз и есть тот элемент интерфейса, который позволяет пользователю переключаться между контентом, разбитым на несколько определённых частей.

В вебе табы – это просто набор ссылок или других HTML элементов, которые визуально можно представить по-разному: в виде вкладок, группы кнопок и другими способами. По сути, они просто включают видимость какого-то одного блока с контентом, скрывая при этом другие.

Табы предназначены для экономии места и более удобного представления информации на сайте (по названию вкладки можно определить какой контент отобразится на странице, если нажать на неё).

Вкладки на чистом CSS

Рассмотрим несколько способов создания табов на CSS.

Первый способ построен на радиокнопках (input с type="radio") и CSS селекторе checked.

HTML и CSS код таба:

<style>
.tabs {
font-size: 0;
}

.tabs>input[type="radio"] {
display: none;
}

.tabs>div {
/* скрыть контент по умолчанию */
display: none;
border: 1px solid #e0e0e0;
padding: 10px 15px;
font-size: 16px;
}

/* отобразить контент, связанный с вабранной радиокнопкой (input type="radio") */
#tab-btn-1:checked~#content-1,
#tab-btn-2:checked~#content-2,
#tab-btn-3:checked~#content-3 {
display: block;
}

.tabs>label {
display: inline-block;
text-align: center;
vertical-align: middle;
user-select: none;
background-color: #f5f5f5;
border: 1px solid #e0e0e0;
padding: 2px 8px;
font-size: 16px;
line-height: 1.5;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out;
cursor: pointer;
position: relative;
top: 1px;
}

.tabs>label:not(:first-of-type) {
border-left: none;
}

.tabs>input[type="radio"]:checked+label {
background-color: #fff;
border-bottom: 1px solid #fff;
}
</style>

<div class="tabs">
<input type="radio" name="tab-btn" id="tab-btn-1" value="" checked>
<label for="tab-btn-1">Вкладка 1</label>
<input type="radio" name="tab-btn" id="tab-btn-2" value="">
<label for="tab-btn-2">Вкладка 2</label>
<input type="radio" name="tab-btn" id="tab-btn-3" value="">
<label for="tab-btn-3">Вкладка 3</label>

<div id="content-1">
  Содержимое 1...
</div>
<div id="content-2">
  Содержимое 2...
</div>
<div id="content-3">
  Содержимое 3...
</div>
</div>
Табы для сайта на чистом CSS

Посмотреть

В этом варианте радиокнопки связаны с определённым label. Связь элемента label с input выполнена через атрибут for. Это действие необходимо для того, чтобы можно было скрыть элементы input, а управление ими (установку checked) выполнять через клики по элементам label.

Стилизация выбранного элемента label в этом примере выполнена с использованием селектора input[type="radio"]:checked+label. Этот селектор выбирает элемент label, который расположен сразу же после элемента input[type="radio"], находящимся в состоянии checked.

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

#tab-btn-1:checked~#content-1,
#tab-btn-2:checked~#content-2,
#tab-btn-3:checked~#content-3 {
display: block;
}

Отобразить вкладки можно по-разному. В следующем примере они визуально отображаются как кнопки.

CSS код для создания адаптивных вкладок в виде кнопок:

.tabs>input[type="radio"] {
display: none;
}

.tabs>input[type="radio"]:checked+label {
background-color: #bdbdbd;
}

.tabs>div {
/* скрыть контент по умолчанию */
display: none;
border: 1px solid #eee;
padding: 10px 15px;
border-radius: 4px;
}

/* отобразить контент, связанный с вабранной радиокнопкой (input type="radio") */
#tab-btn-1:checked~#content-1,
#tab-btn-2:checked~#content-2,
#tab-btn-3:checked~#content-3 {
display: block;
}

.tabs>label {
display: inline-block;
text-align: center;
vertical-align: middle;
user-select: none;
background-color: #eee;
border: 1px solid transparent;
padding: 2px 8px;
font-size: 16px;
line-height: 1.5;
border-radius: 4px;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
margin-right: 6px;
cursor: pointer;
margin-bottom: 10px;
}

.tabs>label:first-of-type {
margin-left: 0;
}
Табы для сайта на чистом CSS

Посмотреть

В этом примере вкладки визуально представлены в виде хэштегов:

.tabs>input[type="radio"] {
display: none;
}

.tabs>input[type="radio"]:checked+label {
font-weight: bold;
cursor: default;
}

.tabs>div {
display: none;
border-top: 1px solid #eee;
padding: 10px 15px;
}

#tab-btn-1:checked~#content-1,
#tab-btn-2:checked~#content-2,
#tab-btn-3:checked~#content-3 {
display: block;
}

.tabs>label {
display: inline-block;
text-align: center;
vertical-align: middle;
user-select: none;
padding: 2px 8px;
font-size: 14px;
line-height: 1.5;
transition: color 0.15s ease-in-out;
margin-left: 6px;
cursor: pointer;
margin-bottom: 4px;
}

.tabs>label:first-of-type {
margin-left: 0;
}
Табы для сайта на чистом CSS

Посмотреть

Второй способ основывается на использовании псевдокласса :target.

Пример HTML и CSS кода для создания адаптивных вкладок, механизм работы которых организован через :target:

<style>
.tabs {
  display: flex;
  flex-direction: column;
}

.tabs__links {
  display: flex;
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 10px;
  order: 0;
  white-space: nowrap;
  background-color: #fff;
  border: 1px solid #e3f2fd;
  box-shadow: 0 2px 4px 0 #e3f2fd;
}

.tabs__links>a {
  display: inline-block;
  text-decoration: none;
  padding: 6px 10px;
  text-align: center;
  color: #1976d2;
}

.tabs__links>a:hover {
  background-color: rgba(227, 242, 253, 0.3);
}

.tabs>#content-1:target~.tabs__links>a[href="#content-1"],
.tabs>#content-2:target~.tabs__links>a[href="#content-2"],
.tabs>#content-3:target~.tabs__links>a[href="#content-3"] {
  background-color: #bbdefb;
  cursor: default;
}

.tabs>div:not(.tabs__links) {
  display: none;
  order: 1;
}

.tabs>div:target {
  display: block;
}
</style>

<div class="tabs">
<div id="content-1">
  Содержимое 1...
</div>
<div id="content-2">
  Содержимое 2...
</div>
<div id="content-3">
  Содержимое 3...
</div>

<div class="tabs__links">
  <a href="#content-1">Вкладка 1</a>
  <a href="#content-2">Вкладка 2</a>
  <a href="#content-3">Вкладка 3</a>
</div>
</div>
Табы для сайта на чистом CSS

Посмотреть

Логика этих табов основана на следующих моментах. Первый момент заключается в добавлении хэша к URL-адресу страницы при нажатии на ссылку (вкладку). Второй – это стилизация элементов, выбор которых осуществляется в зависимости от хэша в URL-адресе. Выбрать элемент, идентификатор которого соответствует хэшу в URL-адресе в CSS можно выполнить посредством псевдокласса :target. С помощью него мы можем написать селектор не только для получения элемента, на который он указывает, но и для выбора других элементов, которые каким-то определённым образом связаны с ним.

Например, выбрать вкладку, которая должна быть активной для элемента на который указывает :target можно так:

.tabs>#content-1:target~.tabs__links>a[href="#content-1"],
.tabs>#content-2:target~.tabs__links>a[href="#content-2"],
.tabs>#content-3:target~.tabs__links>a[href="#content-3"] {
background-color: #bbdefb;
cursor: default;
}

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

Например, чтобы сделать вкладки вертикальными их код можно изменить на следующий:

.tabs {
display: flex;
flex-direction: column;
}

.tabs__links {
display: flex;
flex-direction: row;
order: 0;
white-space: nowrap;
margin-bottom: 15px;
background-color: #fff;
border: 1px solid #e3f2fd;
box-shadow: 0 2px 4px 0 #e3f2fd;
}

.tabs__links>a {
display: inline-block;
text-decoration: none;
color: #1976d2;
padding: 6px 10px;
text-align: center;
}

.tabs__links>a:hover {
background-color: rgba(227, 242, 253, 0.3);
}

.tabs>#content-1:target~.tabs__links>a[href="#content-1"],
.tabs>#content-2:target~.tabs__links>a[href="#content-2"],
.tabs>#content-3:target~.tabs__links>a[href="#content-3"] {
background-color: #bbdefb;
cursor: default;
}

.tabs>div:not(.tabs__links) {
display: none;
order: 1;
flex-grow: 1;
}

@media (min-width: 576px) {
.tabs {
  flex-direction: row;
}

.tabs__links {
  flex-direction: column;
  border: none;
  box-shadow: none;
}

.tabs__links>a {
  border: 1px solid #e3f2fd;
  box-shadow: 0 2px 4px 0 #e3f2fd;
  margin-bottom: 8px;
}

.tabs__links>a:last-child {
  margin-bottom: 0;
}

.tabs>div:not(.tabs__links) {
  padding-left: 15px;
}
}

.tabs>div:target {
display: block;
}
Табы для сайта на чистом CSS

Посмотреть

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

Табы с использованием JavaScript

В этом разделе разберём как можно создать табы на чистом JavaScript (без использования библиотеки jQuery).

Способ реализации вкладок с использованием JavaScript может потребоваться, когда в них нужно, например показывать динамический контент, получаемый через AJAX.

HTML и CSS код вкладок:

<style>
.tabs {
  border: 1px solid lightgray;
}

.tabs__nav {
  display: flex;
  flex-wrap: wrap;
  list-style-type: none;
  background: #f8f8f8;
  margin: 0;
  border-bottom: 1px solid lightgray;
}

.tabs__link {
  padding: 0.5rem 0.75rem;
  text-decoration: none;
  color: black;
  text-align: center;
  flex-shrink: 0;
  flex-grow: 1;
}

.tabs__link_active {
  background: lightgray;
  cursor: default;
}

.tabs__link:not(.tabs__link_active):hover,
.tabs__link:not(.tabs__link_active):focus {
  background-color: #efefef;
}

.tabs__content {
  padding: 1rem;
}

.tabs__pane {
  display: none;
}

.tabs__pane_show {
  display: block;
}
</style>

<div class="tabs">
<div class="tabs__nav">
  <a class="tabs__link tabs__link_active" href="#content-1">Вкладка 1</a>
  <a class="tabs__link" href="#content-2">Вкладка 2</a>
  <a class="tabs__link" href="#content-3">Вкладка 3</a>
</div>
<div class="tabs__content">
  <div class="tabs__pane tabs__pane_show" id="content-1">
    Содержимое 1...
  </div>
  <div class="tabs__pane" id="content-2">
    Содержимое 2...
  </div>
  <div class="tabs__pane" id="content-3">
    Содержимое 3...
  </div>
</div>
</div>

JavaScript код:

var $tabs = function (target) {
var
  _elemTabs = (typeof target === 'string' ? document.querySelector(target) : target),
  _eventTabsShow,
  _showTab = function (tabsLinkTarget) {
    var tabsPaneTarget, tabsLinkActive, tabsPaneShow;
    tabsPaneTarget = document.querySelector(tabsLinkTarget.getAttribute('href'));
    tabsLinkActive = tabsLinkTarget.parentElement.querySelector('.tabs__link_active');
    tabsPaneShow = tabsPaneTarget.parentElement.querySelector('.tabs__pane_show');
    // если следующая вкладка равна активной, то завершаем работу
    if (tabsLinkTarget === tabsLinkActive) {
      return;
    }
    // удаляем классы у текущих активных элементов
    if (tabsLinkActive !== null) {
      tabsLinkActive.classList.remove('tabs__link_active');
    }
    if (tabsPaneShow !== null) {
      tabsPaneShow.classList.remove('tabs__pane_show');
    }
    // добавляем классы к элементам (в завимости от выбранной вкладки)
    tabsLinkTarget.classList.add('tabs__link_active');
    tabsPaneTarget.classList.add('tabs__pane_show');
    document.dispatchEvent(_eventTabsShow);
  },
  _switchTabTo = function (tabsLinkIndex) {
    var tabsLinks = _elemTabs.querySelectorAll('.tabs__link');
    if (tabsLinks.length > 0) {
      if (tabsLinkIndex > tabsLinks.length) {
        tabsLinkIndex = tabsLinks.length;
      } else if (tabsLinkIndex < 1) {
        tabsLinkIndex = 1;
      }
      _showTab(tabsLinks[tabsLinkIndex - 1]);
    }
  };

_eventTabsShow = new CustomEvent('tab.show', { detail: _elemTabs });

_elemTabs.addEventListener('click', function (e) {
  var tabsLinkTarget = e.target;
  // завершаем выполнение функции, если кликнули не по ссылке
  if (!tabsLinkTarget.classList.contains('tabs__link')) {
    return;
  }
  // отменяем стандартное действие
  e.preventDefault();
  _showTab(tabsLinkTarget);
});

return {
  showTab: function (target) {
    _showTab(target);
  },
  switchTabTo: function (index) {
    _switchTabTo(index);
  }
}

};

$tabs('.tabs');
Адаптивные вкладки на CSS и JavaScript

Посмотреть

Инициализация табов на странице осуществляется с помощью вызова функции $tabs и передаче ей в качестве аргумента CSS селектора или DOM-элемента, содержащего вкладки:

$tabs('.tabs');

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

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

var listTabs = document.querySelectorAll('.tabs');
for (var i = 0, length = listTabs.length; i < length; i++) {
$tabs(listTabs[i]);
}

Кроме этого, если результат вызова функции $tabs сохранить в переменную, то можно использовать методы, которые она представляет.

Например:

var tabs1 = $tabs('.tabs');
// программно переключиться на 2 вкладку (2 – номер вкладки, на которую нужно перейти)
tabs1.switchToTab(2);

Примеры

1. Пример, в котором данные о последней открытой вкладки таба будем сохранять в LocalStorage, а затем использовать эту информацию при открытии страницы для переключения на неё:

...
var mytabs = $tabs('.tabs');
if (localStorage.getItem('mytabs')) {
mytabs.showTab(document.querySelector('[href="' + localStorage.getItem('mytabs') + '"]'));
}

document.addEventListener('tab.show', function (e) {
localStorage.setItem('mytabs', e.detail.querySelector('.tabs__link_active').getAttribute('href'));
});

2. Пример синхронизации вкладок на разных открытых страницах, относящихся к одному источнику (через LocalStorage):

window.onstorage = function (e) {
mytabs.showTab(document.querySelector('[href="' + e.newValue + '"]'));
};

3. Пример, в котором показано как на одной странице можно вывести несколько табов с сохранением их состояний (активных вкладок) в LocalSorage:

<div class="tabs" id="tabs-1">...</div>
<div class="tabs" id="tabs-2">...</div>

<script>
var
nameKey = 'mytabs2',
mytabs = {},
mytabsStorage = {},
listTabs = document.querySelectorAll('.tabs');

for (var i = 0, length = listTabs.length; i < length; i++) {
if (listTabs[i].id) {
  mytabs[listTabs[i].id] = $tabs(listTabs[i]);
}
}
if (localStorage.getItem(nameKey)) {
mytabsStorage = JSON.parse(localStorage.getItem(nameKey));
for (var key in mytabsStorage) {
  if (mytabs.hasOwnProperty(key)) {
    mytabs[key].showTab(document.querySelector('[href="' + mytabsStorage[key] + '"]'));
  }
}
}
document.addEventListener('tab.show', function (e) {
mytabsStorage[e.detail.closest('.tabs').getAttribute('id')] = e.detail.querySelector('.tabs__link_active').getAttribute('href');
localStorage.setItem(nameKey, JSON.stringify(mytabsStorage));
})
</script>

4. Табы, содержащие видео с YouTube. При переходе на другую вкладку будет приостанавливаться воспроизведение текущего видеофайла.

Табы, содержащие YouTube видео

Контент вкладок:

<div class="tabs__content">
  <div class="tabs__pane tabs__pane_show" id="content-1">
    <!-- Контент 1 вкладки -->
    <div class="iframe">
      <div class="player" id="player-1" data-video-id="5NTvXKUXEX4" data-width="560" data-height="315"></div>
    </div>
  </div>
  <div class="tabs__pane" id="content-2">
    <!-- Контент 2 вкладки -->
    <div class="iframe">
      <div class="player" id="player-2" data-video-id="Cy35h6DF8hY" data-width="560" data-height="315"></div>
    </div>
  </div>
  <div class="tabs__pane" id="content-3">
    <!-- Контент 3 вкладки -->
    <div class="iframe">
      <div class="player" id="player-3" data-video-id="6tyB97J1cVA" data-width="560" data-height="315"></div>
    </div>
  </div>
</div>

Во элементах .player атрибут data-video-id определяет videoId ролика, а data-width и data-height - ширину и высоту iframe.

Загрузку API IFrame Player будем выполнять асинхронно. Для этого напишем следующий код:

const tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

Создание <iframe> и проигрывателя YouTube будем выполнять после загрузки кода API посредством функции onYouTubeIframeAPIReady:

const players = {};
function onYouTubeIframeAPIReady() {
  for (let i = 0, length = document.querySelectorAll('.player').length; i < length; i++) {
    const player = document.querySelectorAll('.player')[i];
    players[player.id] = new YT.Player(player.id, {
      height: player.dataset.height,
      width: player.dataset.width,
      videoId: player.dataset.videoId
    });
  }
}

Приостанавливает воспроизведение видео будем посредством метода pauseVideo, а выполнять это после переключения вкладки (используя для этого событие tab.show):

document.addEventListener('tab.show', function (e) {
  const from = e.detail.from;
  if (from) {
    const player = from.querySelector('.player');
    if (player) {
      players[player.id].pauseVideo();
    }
  }
});

Открыть пример

Описание исходного JavaScript кода

Исходный JavaScript код состоит из функции $tabs. Внутри этой функции имеется переменная _elemTabs и функции _showTab, _switchTabTo. Переменная _elemTabs хранит DOM-элемент, предоставляющий собой контейнер с вкладками. Метод _showTab предназначен для скрытия текущей (активной) вкладки и отображения другой в зависимости от переданной ему ссылки. Метод _switchTabTo используется для переключения вкладки по её порядковому номеру. Установка обработчиков событий для вкладок определяется с помощью addEventListener и выполняется в момент вызова $tabs.

Вне функции доступен только методы showTab и switchTabTo. Первый метод позволяет программно перейти на вкладку через передачу ему ссылки на DOM-элемент (ссылки), а второй - по её порядковому номеру.

Комментарии:

  1. Aleks
    Aleks
    19.10.2021, 03:49
    Я пытаюсь добавить два слайдера через шорткод в разные табы. После перезагрузки один работает (группа из 5 картинок, опционально вывожу только 3 с возможностью их прокручивать), а при переходе в следующий таб второй — нет (отображается только одна картинка из группы в увеличенном виде и не реагирует прокрутка). Причём, как только меняется разрешение экрана (через responsive в инспекторе) оба слайдера начинают работать прекрасно (если быть точнее, то тот, который во втором табе), но при очередной перезагрузке опять один работает, второй — нет. В чём может быть причина?
    1. Александр Мальцев
      Александр Мальцев
      20.10.2021, 13:18
      Тут нужно разбираться со слайдерами, и скорее всего слайдер, который расположен во вкладке, содержимое которого сейчас не показывается, нужно активировать в момент перехода на неё.
    2. vlad
      vlad
      10.09.2021, 23:12
      Здравствуйте, допустим на сайте есть блок с карточками товаров. Как при нажатии на таб показывать не одну карточку, а несколько? пока только смог реализовать через дублировании html-кода, но это наверное такой себе вариант…
      1. sprigan
        sprigan
        07.08.2021, 12:33
        Добрый день, Александр

        Подскажите, столкнулся с такой проблемой.
        Взял пример реализации через JS.

        Если кликаю на свободное место вкладки, то работает, если кликаю к примеру по тексту вкладки, то нет.
        Как реализовать, чтобы по клику на любой элемент внутри родителя сработало переключение?

        <img
        src=«https://itchief.ru/assets/uploadify/f/8/6/f86bf8fc0c6125d9dd8f5f48a2490897s.jpg» class=«fancybox thumbnail center»>
        1. Александр Мальцев
          Александр Мальцев
          08.08.2021, 10:05
          Привет! Код JavaScript поправил в примере: tabs-v1
          1. sprigan
            sprigan
            08.08.2021, 12:25
            Большое спасибо!
        2. Primerio
          Primerio
          12.07.2021, 13:00
          Есть баг с табами, если рядом с названием вкладки будет картинка, про нажатие на нее таб не открывается, только если нажать на текст
          1. Александр Мальцев
            Александр Мальцев
            08.08.2021, 10:10
            Поправил код JavaScript в примере: tabs-v1
          2. Alex Maker
            Alex Maker
            31.05.2021, 13:18
            Здравствуйте, скажите что из выше перечисленного может помочь в решении моей проблемы?
            Есть табы с категориями, в каждой из категорий есть табы с товаром, переключение между категориями и товарами написано на чистом Javascript, а теперь проблема. Необходимо чтобы по ссылке с другой страницы открывалась необходимая категория и товар. Дайте пример пожалуйста, я не силен в js((
            1. Александр Мальцев
              Александр Мальцев
              08.08.2021, 10:36
              Привет! Для этого можно, например, передавать в составе URL номер вкладки, которую нужно открыть:
              Эта ссылка (https://itchief.ru/examples/lab.php?topic=javascript&file=tabs-08&tab=2) откроет вторую вкладку, а эта (https://itchief.ru/examples/lab.php?topic=javascript&file=tabs-08&tab=3) — третью.

              Сам код тут будет простой, нужно получить значение GET-параметра tab и передать его значение функции которая переключает вкладки:
              
              const tabs = $tabs('.tabs');
              const urlParams = new URLSearchParams(location.search);
              const tabTo = urlParams.get('tab');
              if (tabTo) {
                tabs.switchTabTo(tabTo);
              }
              
            2. Олег
              Олег
              19.05.2021, 09:42
              Доброго времени суток друзья.
              Очень интересные и полезные примеры работы скриптов, но к сожалению для решения свой задачи ничего подходящего не нашёл.
              Возможно похожее есть решение с синхронизацией табов на разных страница как на примере itchief.ru/examples/lab.php?topic=javascript&file=tabs-v3, но немного не то что надо.
              Александр, может Вы как мастер сможете помочь с реализацией моей задачи.
              У меня на сайте есть 2 отдельный блока div.
              В одном блоке содержится информация от квадроциклах, те. Есть цена и характеристики, а во втором блоке есть табы, в которых есть информация о предоставляемых услугах, в каждом табе разная услуга.
              Зада состоит в том, чтобы при клике на каждом табе справа менялась цена.
              Например:
              Клик по табу №1 справа менялась цена в левом блоке и так при нажатии на каждый таб. пример на картинке


              Буду очень признателен за помощь.
              1. Александр Мальцев
                Александр Мальцев
                08.08.2021, 11:11
                Привет! Можно добавить к вкладкам data-атрибут с ценой:
                
                <div class="tabs">
                  <div class="tabs__nav">
                    <a class="tabs__link tabs__link_active" href="#content-1" data-price="100">Вкладка 1</a>
                    <a class="tabs__link" href="#content-2" data-price="200">Вкладка 2</a>
                    <a class="tabs__link" href="#content-3" data-price="300">Вкладка 3</a>
                  </div>
                  <div class="tabs__content">...</div>
                </div>
                
                После этого добавить скрипт, который будет при переключении вкладки изменять цену:
                
                const tabs = $tabs('.tabs');
                function updatePrice(tabsLink) {
                  const price = tabsLink.dataset.price;
                  document.querySelector('.price').textContent = price;
                }
                updatePrice(document.querySelector('.tabs__link_active'));
                document.addEventListener('tab.show', function(e) {
                  updatePrice(e.detail.querySelector('.tabs__link_active'));
                });
                
                Пример: https://itchief.ru/examples/lab.php?topic=javascript&file=tabs-09
              2. Siarhei
                Siarhei
                14.04.2021, 15:26
                То что надо. Спасибо автору большое!
                Ребят. Использую Табы с использованием JavaScript. Главный код сначала в посте. Без дополнений.

                У меня важный вопрос:
                У меня табы с плеерами (iframe).
                Так вот, как остановить подзагрузку и воспроизведение видео, при переходе на другую вкладку.
                А то открываю другую, а на первой идет все и не останавливается. И соответственно грузятся сразу все вкладки.


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

                Заранее благодарю, если есть решение!
                1. Александр Мальцев
                  Александр Мальцев
                  20.04.2021, 09:23
                  Пожалуйста!
                  Добавил в статью пример табов, содержащие YouTube видео. При переключении видео приостанавливается.
                  Открыть пример
                  1. Siarhei
                    Siarhei
                    30.04.2021, 20:05
                    Просто красавчик!
                    Спасибо огромное!!!
                2. Александр Сидоров
                  Александр Сидоров
                  01.04.2021, 14:58
                  Добрый день Александр!

                  Вопрос такой: не подскажите как можно задействовать табы в вопросе, когда необходимо сделать подобный блок:

                  — листающийся слайдер с категориями товара;
                  — ниже блок с первым товаром из выбранной категории товаров и в этом блоке без перезагрузки страницы можно выбрать другой товар (торговое предложение по типу SKU битрикс), с другой ценой и например расцветкой, но относящийся к основному товару.
                  Меняются фото, цена и описание.

                  Пример блока:
                  prnt.sc/10xv629
                  sklad-kuhni.moscow/

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

                  Как копать в сторону аякса — это тоже на данный момент по знаниям проблематично…
                  1. Дмитрий
                    Дмитрий
                    19.03.2021, 17:10
                    Здравствуйте! Подскажите как сделать несколько блоков с табами на одной странице их мне нужно 4 (https://itchief.ru/assets/uploadify/9/8/8/9889f32d8a70fb4e1dc8bd505ace4887.jpg). Пробую вариант с отображением как кнопки. У меня только две вкладки, в каждом блоке разное содержание, название вкладок одинаковое.
                    1. Александр Мальцев
                      Александр Мальцев
                      20.03.2021, 15:14
                      Привет! Связывание вкладок с содержимым выполняется через id, название может быть любым. Тут всё просто, проблем не должно быть. Как сделать: пример.
                      1. Дмитрий
                        Дмитрий
                        21.03.2021, 07:49
                        Просто огромное спасибо, все работает как надо.
                    2. ofam
                      ofam
                      15.12.2020, 06:12
                      Здравствуйте.
                      Подскажите, пожалуйста, как реализовать возможность переключения сразу нескольких табов кнопкой?
                      Для примера: у меня 5 блоков, в каждом по 2 вкладке. Над ними 2 кнопки, которые должны переключить сразу все табы.
                      1. Александр Мальцев
                        Александр Мальцев
                        17.12.2020, 13:24
                        Привет!
                        Можно например так (открыть пример):
                        <!-- Добавить к кнопкам или ссылкам атрибут data-switch-to, в котором указать номер открываемых вкладок для табов -->
                        <a href="#" data-switch-to="1">1</a>
                        <a href="#" data-switch-to="2">2</a>
                        
                        <script>
                        // ...
                        // массив, в который будем помещать табы
                        let tabs = [];
                        // переберём все табы, инициализируем их, и поместим результат в массив tabs
                        document.querySelectorAll('.tabs').forEach(function ($element) {
                          tabs.push($tabs($element));
                        });
                        
                        // при клике будем определять имеет ли цель data-switch-to и если да, то выполнять переключение вкладок
                        document.onclick = function (e) {
                          if (e.target.dataset.switchTo) {
                            e.preventDefault();
                            // получим номер вкладки
                            const index = +e.target.dataset.switchTo;
                            // переберём все табы
                            tabs.forEach(function ($tab) {
                              // переключим вкладку на нужную
                              $tab.switchTabTo(index);
                            })
                          }
                        }
                        </script>
                      2. Илья
                        Илья
                        05.12.2020, 18:02
                        А как сделать кнопку «Добавить новую вкладку»? К примеру, чтобы скопировало содержание вкладки с чистым независимым input от копируемой вкладки
                        1. Александр Мальцев
                          Александр Мальцев
                          06.12.2020, 16:15
                          Лучше наверно не копировать, а самостоятельно определять контент, например, с помощью функции getTabsPaneContent.
                          Для этого необходимо (открыть пример):
                          1. Добавить кнопку:
                          <button id="add-new-tab" type="button">Добавить новую вкладку:</button>
                          
                          2. Создать функцию getTabsPaneContent, которая должна будет возвращать то, что мы хотим увидеть в новой вкладке:
                          <code>const getTabsPaneContent = (counter) => {
                            return `<div class="tabs__pane" id="content-${counter}">
                                <p>Содержимое ${counter}...</p>
                                <input type="text" id="content-${counter}-input" value="">
                              </div>`;
                          }
                          3. Получить в JavaScript саму кнопку и привязать к ней обработчик события click, который будет добавлять новую вкладку с контентом, определяемым функцией getTabsPaneContent:
                          const $addNewTab = document.querySelector('#add-new-tab');
                          $addNewTab.onclick = function () {
                            const $tabsNav = document.querySelector('.tabs__nav');
                            const counter = $tabsNav.children.length + 1;
                            // вставляем новый tabs__link
                            const $tabsLink = `<a class="tabs__link" href="#content-${counter}">Вкладка ${counter}</a>`
                            $tabsNav.insertAdjacentHTML('beforeend', $tabsLink);
                            // вставляем новый tabs__content
                            const $tabsContent = document.querySelector('.tabs__content');
                            $tabsContent.insertAdjacentHTML('beforeend', getTabsPaneContent(counter));
                          }
                        2. Ola
                          Ola
                          05.10.2020, 18:31
                          Супер! как всегда просто и понятно! Спасибо!
                          1. Александр Мальцев
                            Александр Мальцев
                            08.10.2020, 13:19
                            Пожалуйста!
                          2. Владимир
                            Владимир
                            26.08.2020, 18:09
                            еще есть вопросик, при нажатии на вкладку страница прокручивается к началу вкладку сверху alutat.com.ua/ а как отменить это?
                            1. Александр Мальцев
                              Александр Мальцев
                              02.09.2020, 14:19
                              Так вы это реализовали в виде отдельных страниц, а не на одной странице. А новая страница по умолчанию всегда открывается сначала. Чтобы это реализовать, вам нужно дополнительно добавить скрипт на страницу, который будет её прокручивать до этого состояния.
                            2. Владимир
                              Владимир
                              19.08.2020, 18:09
                              Здравствуйте, Александр!

                              Сперва, спасибо за полезную статью )

                              Хочу использовать вот эти вертикальные табы itchief.ru/examples/lab.php?topic=css&file=tabs-v4 <itchief.ru/examples/lab.php?topic=css&file=tabs-v4> на сайте, но не могу решить вопрос с отображением сразу контента первой вкладки. Знаю, что можно страницу itchief.ru/examples/output.php#content-1 <itchief.ru/examples/output.php#content-1> открывать, но они у меня на главной будут сразу и нужно чтобы сразу была активна первая вкладка.

                              Как такое можно реализовать?

                              Буду признателен за ответ.
                              1. Александр Мальцев
                                Александр Мальцев
                                20.08.2020, 04:01
                                Здравствуйте! На сколько понимаю вы хотите без JavaScript. На CSS это можно выполнить, если только разместить содержимое вкладки, которая по умолчанию должна быть открытой, после остальных.
                                <div id="content-3">
                                  Содержимое 3...
                                <div>
                                <div id="content-2">
                                  Содержимое 2...
                                </div>
                                <div id="content-1">
                                  Содержимое 1...
                                </div>
                                
                                А также внести необходимые изменения в CSS. Готовый пример можно посмотреть здесь.
                                1. Владимир
                                  Владимир
                                  20.08.2020, 08:18
                                  супер! спасибо большое!
                              2. Nik
                                Nik
                                11.04.2020, 20:36
                                Доброго времени Александр! Подскажите как в данном скрипте добавить localStorage или cookie или sessionStorage, чтобы при F5 остаться на той же самой вкладке?
                                1. Александр Мальцев
                                  Александр Мальцев
                                  12.04.2020, 08:32
                                  Привет! Пример как это сделать с помощью localStorage добавил в статью.
                                  1. Nik
                                    Nik
                                    12.04.2020, 20:47
                                    А для двух табов подряд на странице не работает почему-то, код инициализации сразу всех вкладок делает нерабочим скрипт. Только если убрать один из двух табов, тогда да, сохранение в LocalStorage отрабатывает великолепно!
                                    1. Nik
                                      Nik
                                      13.04.2020, 13:28
                                      Разобрался, все работает!
                                      1. Александр Мальцев
                                        Александр Мальцев
                                        13.04.2020, 14:16
                                        Отлично!
                                        1. Nik
                                          Nik
                                          13.04.2020, 14:30
                                          Правда как-то очень интересно работает))) Пока еще не понял, но вроде «через раз»
                                          1. Александр Мальцев
                                            Александр Мальцев
                                            13.04.2020, 14:41
                                            Может что-то не учёл. Пример как это можно сделать для нескольких вкладок в статью добавил.
                                            1. Nik
                                              Nik
                                              14.04.2020, 02:25
                                              Нашел одну причину, почему скрипт «ломало», банальная невнимательность, лишний раз обернул в дивы tabs, то, что вообще не надо было оборачивать.
                                              Остальные примеры в статье разобрал, проверил на своем сайте, все работает как положено, кроме одного загадочного для меня явления))) Одни табы с одним контентом у меня на одной странице, другие с другим контентом на совершенно другой странице. Футер где скрипт, на всем сайте один и тот же. Табы работают, но допустим в хроме на одной странице с табами вкладка остаётся после F5 которую открыл, на другой local storage не срабатывает. В мозилле наоборот, та которая не работала в хроме, работает. «Мудрый» код скрипта покажу завтра
                                              1. Nik
                                                Nik
                                                14.04.2020, 02:50
                                                Код скрипта такой:
                                                 <script>
                                                    var $tabs = function (target) {
                                                      var
                                                        _elemTabs = (typeof target === 'string' ? document.querySelector(target) : target),
                                                        _eventTabsShow,
                                                        _showTab = function (tabsLinkTarget) {
                                                          var tabsPaneTarget, tabsLinkActive, tabsPaneShow;
                                                          tabsPaneTarget = document.querySelector(tabsLinkTarget.getAttribute('href'));
                                                          tabsLinkActive = tabsLinkTarget.parentElement.querySelector('.tabs__link_active');
                                                          tabsPaneShow = tabsPaneTarget.parentElement.querySelector('.tabs__pane_show');
                                                          // если следующая вкладка равна активной, то завершаем работу
                                                          if (tabsLinkTarget === tabsLinkActive) {
                                                            return;
                                                          }
                                                          // удаляем классы у текущих активных элементов
                                                          if (tabsLinkActive !== null) {
                                                            tabsLinkActive.classList.remove('tabs__link_active');
                                                          }
                                                          if (tabsPaneShow !== null) {
                                                            tabsPaneShow.classList.remove('tabs__pane_show');
                                                          }
                                                          // добавляем классы к элементам (в завимости от выбранной вкладки)
                                                          tabsLinkTarget.classList.add('tabs__link_active');
                                                          tabsPaneTarget.classList.add('tabs__pane_show');
                                                          document.dispatchEvent(_eventTabsShow);
                                                        },
                                                        _switchTabTo = function (tabsLinkIndex) {
                                                          var tabsLinks = _elemTabs.querySelectorAll('.tabs__link');
                                                          if (tabsLinks.length > 0) {
                                                            if (tabsLinkIndex > tabsLinks.length) {
                                                              tabsLinkIndex = tabsLinks.length;
                                                            } else if (tabsLinkIndex < 1) {
                                                              tabsLinkIndex = 1;
                                                            }
                                                            _showTab(tabsLinks[tabsLinkIndex - 1]);
                                                          }
                                                        };
                                                
                                                      _eventTabsShow = new CustomEvent('tab.show', { detail: _elemTabs });
                                                
                                                      _elemTabs.addEventListener('click', function (e) {
                                                        var tabsLinkTarget = e.target;
                                                        // завершаем выполнение функции, если кликнули не по ссылке
                                                        if (!tabsLinkTarget.classList.contains('tabs__link')) {
                                                          return;
                                                        }
                                                        // отменяем стандартное действие
                                                        e.preventDefault();
                                                        _showTab(tabsLinkTarget);
                                                      });
                                                
                                                      return {
                                                        showTab: function (target) {
                                                          _showTab(target);
                                                        },
                                                        switchTabTo: function (index) {
                                                          _switchTabTo(index);
                                                        }
                                                      }
                                                
                                                    };
                                                //Инициализация всех вкладок иначе не работает
                                                var listTabs = document.querySelectorAll('.tabs');
                                                for (var i = 0, length = listTabs.length; i < length; i++) {
                                                  $tabs(listTabs[i]);
                                                }
                                                //Сохраняем в  LocalStorage
                                                    var mytabs = $tabs('.tabs');
                                                    if (localStorage.getItem('mytabs')) {
                                                      mytabs.showTab(document.querySelector('[href="' + localStorage.getItem('mytabs') + '"]'));
                                                    }
                                                
                                                    document.addEventListener('tab.show', function (e) {
                                                      localStorage.setItem('mytabs', e.detail.querySelector('.tabs__link_active').getAttribute('href'));
                                                    })
                                                    
                                                  </script>
                                                
                                                1. Александр Мальцев
                                                  Александр Мальцев
                                                  14.04.2020, 16:36
                                                  Так корректно работать не будет. В mytabs будет находится результат вызова функции $tabs('.tabs') для первого таба. Кроме этого в этом случае в LocalStorage нужно сохранять не просто href ссылку, а, например, их в виде некоторого объекта, как в этом примере.
                                                  Как этот пример работает? В этом примере к табам добавляется id:
                                                  <div class="tabs" id="tabs-1">...</div>
                                                  <div class="tabs" id="tabs-2">...</div>
                                                  
                                                  Они нужны чтобы определить какой это таб.
                                                  Далее выполняем их инициализацию следующим образом
                                                  var
                                                    mytabs = {
                                                      'tabs-1': $tabs('#tabs-1'),
                                                      'tabs-2': $tabs('#tabs-2')
                                                    },
                                                    ...
                                                  Теперь у нас в mytabs['tabs-1'] и mytabs['tabs-2'] находятся результаты соответственно вызова $tabs для первого и второго tabs.
                                                  Сохранение данных в LocalStorage в этом примере выполняется в таком формате:
                                                  {"tabs-2":"#content-6","tabs-1":"#content-2"}
                                                  
                                                  Вам нужно написать что-то подобное.
                                                  1. Nik
                                                    Nik
                                                    14.04.2020, 17:13
                                                    Наверно я что-то не недопонимаю, когда мы вызываем функцию $tabs('.tabs') и происходит инициализация определенного id с помощью:
                                                    var
                                                      mytabs = {
                                                        'tabs-1': $tabs('#tabs-1'),
                                                        'tabs-2': $tabs('#tabs-2')
                                                      }
                                                    
                                                    такая конструкция отлично работает, если табы на одной и той же странице. но если они расположены на разных страницах, то не работает, пробовал по разному ничего пока не получается.
                                                    1. Александр Мальцев
                                                      Александр Мальцев
                                                      15.04.2020, 04:07
                                                      В этом случае его можно сделать более динамичным (пример обновил в статье). Теперь он будет сохранять состояния в LocalStorage и восстанавливать открытые вкладки только для тех табов, которые имеют id.
                                                      1. Nik
                                                        Nik
                                                        16.04.2020, 11:43
                                                        Да, теперь табы работают на любых страницах, спасибо за наглядный пример!
                                              2. Nik
                                                Nik
                                                13.04.2020, 14:44
                                                Сейчас проанализирую, сравню
                                      2. Nik
                                        Nik
                                        12.04.2020, 13:09
                                        Благодарю!
                                    2. Vlad
                                      Vlad
                                      30.01.2020, 12:22
                                      как во втором способе сделать, чтобы первая вкладка была уже активной?
                                      1. Александр Мальцев
                                        Александр Мальцев
                                        30.01.2020, 14:45
                                        Для этого нужно добавить к URL страницы соответствующий хэш.
                                        Например:
                                        // content-1 - хэш URL
                                        https://myblog.ru/post-7#content-1
                                        
                                        1. Петр
                                          Петр
                                          14.08.2020, 21:57
                                          Александр помоги.
                                          Не срабатывает указанный метод.
                                          Необходимо перейти на определенную вкладку с другой страницы.
                                          index.html — products.html#content-2 например
                                          1. Александр Мальцев
                                            Александр Мальцев
                                            16.08.2020, 12:21
                                            А вы их как выполнили? С использованием псевдокласса :target или с использованием JavaScript. Если они у вас организованы на JavaScript, то это необходимо дополнительно прописать в коде.
                                            1. Петр
                                              Петр
                                              16.08.2020, 13:17
                                              С использованием javascripta. В ie 11 он не работает, даже разрешая заблокированные сценарии.
                                      2. Vlad
                                        Vlad
                                        28.01.2020, 16:14
                                        не так подключаю что ли на вордпрессе? кроме первой вкладки не открываются.
                                        itchief.ru/assets/uploadify/4/5/3/453a9690d5d48b71c6bbf050a7894874.jpg
                                        1. Александр Мальцев
                                          Александр Мальцев
                                          28.01.2020, 16:24
                                          Необходимо js-файл подключать после HTML-кода вкладок или поместить код в обработчик события DOMContentLoaded, чтобы он выполнился после загрузки DOM-документа:
                                          document.addEventListener('DOMContentLoaded', function() {
                                            // ...
                                          });
                                          
                                          1. Vlad
                                            Vlad
                                            28.01.2020, 16:47
                                            Здорово сработало )
                                        2. Vlad
                                          Vlad
                                          28.01.2020, 10:21
                                          Здравствуйте, автор! А вы платные услуги не оказываете? Мне нужно сделать табы, и внутри у каждого карусель.
                                          1. Александр Мальцев
                                            Александр Мальцев
                                            28.01.2020, 13:43
                                            Здравствуйте! Карусель можно взять отсюда, после этого нужно будет просто вставить карусель в каждую вкладку.
                                          2. Nik
                                            Nik
                                            07.12.2019, 18:12
                                            Александр подскажите а как использовать табы два раза подряд на одной странице? Те которые с использованием java script. Сделал форму авторизации/регистрации во всплывающем окне, разместил в хэдере, форма с применением табов. Соответственно размещая табы уже в теле, получается они используются два раза подряд. И не работают которые вторые, после хэдера. Пробовал менять id, не выходит. Похоже для одновременного использования скрипт должен быть другой…
                                            1. Nik
                                              Nik
                                              07.12.2019, 21:39
                                              Не внимательно прочёл статью до конца, все работает, все табы на странице!
                                              var listTabs = document.querySelectorAll('.tabs');
                                              for (var i = 0; i <= listTabs.length; i++) {
                                                tabs(listTabs[i]);
                                              } 
                                               
                                            2. Nik
                                              Nik
                                              06.12.2019, 12:44
                                              Отличные табы! Уже применил для авторизации, и в личном кабинете. Все работает супер, Спасибо!
                                              1. Александр Мальцев
                                                Александр Мальцев
                                                06.12.2019, 13:24
                                                Рад, что понравились!
                                              Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.