Простые табы

Написал класс для создания/добавления табов на страницу. Разметка с .tabs__control и .tabs__content.

Обращения скрипта идет посредством [data-control] и [data-content].

При создании экземпляра класса сразу происходит инициализация табов.

Можно передавать либо селектор (например ".tabs"), либо в цикле передавать элементы (в случае, если планируется несколько блоков с табами на странице).

HTML
<div class="page">
	<div class="container">
		<div class="tabs">
			<div class="tabs__control">
				<ul class="tabs__control-list">
					<li class="tabs__control-item active" data-control="1">Tab 1</li>
					<li class="tabs__control-item" data-control="2">Tab 2</li>
					<li class="tabs__control-item" data-control="3">Tab 3</li>
					<li class="tabs__control-item" data-control="4">Tab 4</li>
				</ul>
			</div>
			<div class="tabs__content">
				<ul class="tabs__content-list">
					<li class="tabs__content-item active" data-content="1">
						<h2>Tab 1</h2>
						<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatem corporis rerum dolorem laborum fuga in fugiat molestiae, ullam beatae doloribus quidem reprehenderit quasi adipisci provident optio sint eius sequi minus. Laborum explicabo repellendus eveniet quibusdam esse officiis ea voluptatibus nobis dignissimos reprehenderit, rerum optio totam autem quasi. Nisi repudiandae, molestiae aliquam veritatis unde quidem aspernatur. Dolorem maiores expedita facilis itaque dolores unde quas, quasi praesentium, debitis cupiditate enim molestias atque nesciunt illum tenetur adipisci architecto dicta asperiores neque esse culpa? Placeat, omnis nesciunt iure, consequatur, corporis totam voluptas adipisci autem assumenda qui sequi? Voluptatem, illo vitae odio porro molestias nesciunt.</p>
					</li>
					<li class="tabs__content-item" data-content="2" hidden>
						<h2>Tab 2</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum perferendis illum ducimus doloremque pariatur deserunt, aspernatur quo veritatis nihil vero optio quibusdam aperiam, nostrum corporis. Minima suscipit libero, reiciendis repellat excepturi asperiores quaerat repellendus enim similique sequi optio? Et exercitationem perferendis earum, tenetur consequuntur esse libero! Veritatis ut sapiente molestiae voluptatum cum corporis impedit optio et laudantium doloremque aperiam perferendis harum deleniti, hic nam officiis voluptatem reiciendis excepturi ab! Necessitatibus fugiat vel, explicabo beatae ullam enim reiciendis architecto incidunt ratione odit repellendus! Deleniti eum maxime atque earum sint nostrum, qui illo unde, quibusdam velit, in voluptates perferendis impedit? Modi optio voluptatibus omnis facilis maxime minus deleniti sit velit recusandae repellat.</p>
					</li>
					<li class="tabs__content-item" data-content="3" hidden>
						<h2>Tab 3</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Optio debitis tempore voluptate quam ipsam architecto inventore ea cumque aliquid unde animi odit esse officiis, eligendi repellat autem dicta id temporibus perferendis ut. Aperiam, repellendus delectus ullam, earum ut ratione quod consectetur nobis adipisci molestiae beatae vero sed quis est tenetur maxime eligendi soluta odit itaque eaque voluptates. Delectus id repudiandae maxime, earum error blanditiis? Veniam error mollitia voluptas vel iste ducimus tenetur maiores quam minus ex. Autem magnam doloribus, quibusdam, natus veritatis perspiciatis expedita blanditiis placeat vel numquam nesciunt facere.</p>
					</li>
					<li class="tabs__content-item" data-content="4" hidden>
						<h2>Tab 4</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Exercitationem rerum autem sapiente! Eligendi alias, ullam magnam dignissimos exercitationem corporis consequuntur debitis eum at! Odio, enim eos. Inventore voluptatem eligendi totam nobis corrupti animi doloremque, laudantium impedit! Itaque assumenda saepe omnis odio corporis unde et accusamus, tempora ab earum! Doloremque incidunt, earum quis aspernatur harum alias asperiores molestias cum praesentium optio, distinctio eum? Nisi fuga aut quaerat qui corporis recusandae doloremque, facilis quia, inventore consectetur error! Repudiandae blanditiis sint natus vitae nulla unde possimus rerum eaque commodi voluptates provident aliquid voluptatem consequatur rem aut, earum reprehenderit animi nisi temporibus suscipit ex.</p>
					</li>
				</ul>
			</div>
		</div>
		<div class="tabs">
			<div class="tabs__control">
				<ul class="tabs__control-list">
					<li class="tabs__control-item active" data-control="1">Tab 1</li>
					<li class="tabs__control-item" data-control="2">Tab 2</li>
					<li class="tabs__control-item" data-control="3">Tab 3</li>
					<li class="tabs__control-item" data-control="4">Tab 4</li>
				</ul>
			</div>
			<div class="tabs__content">
				<ul class="tabs__content-list">
					<li class="tabs__content-item active" data-content="1">
						<h2>Tab 1</h2>
						<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatem corporis rerum dolorem laborum fuga in fugiat molestiae, ullam beatae doloribus quidem reprehenderit quasi adipisci provident optio sint eius sequi minus. Laborum explicabo repellendus eveniet quibusdam esse officiis ea voluptatibus nobis dignissimos reprehenderit, rerum optio totam autem quasi. Nisi repudiandae, molestiae aliquam veritatis unde quidem aspernatur. Dolorem maiores expedita facilis itaque dolores unde quas, quasi praesentium, debitis cupiditate enim molestias atque nesciunt illum tenetur adipisci architecto dicta asperiores neque esse culpa? Placeat, omnis nesciunt iure, consequatur, corporis totam voluptas adipisci autem assumenda qui sequi? Voluptatem, illo vitae odio porro molestias nesciunt.</p>
					</li>
					<li class="tabs__content-item" data-content="2" hidden>
						<h2>Tab 2</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum perferendis illum ducimus doloremque pariatur deserunt, aspernatur quo veritatis nihil vero optio quibusdam aperiam, nostrum corporis. Minima suscipit libero, reiciendis repellat excepturi asperiores quaerat repellendus enim similique sequi optio? Et exercitationem perferendis earum, tenetur consequuntur esse libero! Veritatis ut sapiente molestiae voluptatum cum corporis impedit optio et laudantium doloremque aperiam perferendis harum deleniti, hic nam officiis voluptatem reiciendis excepturi ab! Necessitatibus fugiat vel, explicabo beatae ullam enim reiciendis architecto incidunt ratione odit repellendus! Deleniti eum maxime atque earum sint nostrum, qui illo unde, quibusdam velit, in voluptates perferendis impedit? Modi optio voluptatibus omnis facilis maxime minus deleniti sit velit recusandae repellat.</p>
					</li>
					<li class="tabs__content-item" data-content="3" hidden>
						<h2>Tab 3</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Optio debitis tempore voluptate quam ipsam architecto inventore ea cumque aliquid unde animi odit esse officiis, eligendi repellat autem dicta id temporibus perferendis ut. Aperiam, repellendus delectus ullam, earum ut ratione quod consectetur nobis adipisci molestiae beatae vero sed quis est tenetur maxime eligendi soluta odit itaque eaque voluptates. Delectus id repudiandae maxime, earum error blanditiis? Veniam error mollitia voluptas vel iste ducimus tenetur maiores quam minus ex. Autem magnam doloribus, quibusdam, natus veritatis perspiciatis expedita blanditiis placeat vel numquam nesciunt facere.</p>
					</li>
					<li class="tabs__content-item" data-content="4" hidden>
						<h2>Tab 4</h2>
						<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Exercitationem rerum autem sapiente! Eligendi alias, ullam magnam dignissimos exercitationem corporis consequuntur debitis eum at! Odio, enim eos. Inventore voluptatem eligendi totam nobis corrupti animi doloremque, laudantium impedit! Itaque assumenda saepe omnis odio corporis unde et accusamus, tempora ab earum! Doloremque incidunt, earum quis aspernatur harum alias asperiores molestias cum praesentium optio, distinctio eum? Nisi fuga aut quaerat qui corporis recusandae doloremque, facilis quia, inventore consectetur error! Repudiandae blanditiis sint natus vitae nulla unde possimus rerum eaque commodi voluptates provident aliquid voluptatem consequatur rem aut, earum reprehenderit animi nisi temporibus suscipit ex.</p>
					</li>
				</ul>
			</div>
		</div>
	</div>
</div>
CSS
.tabs__control-list {
  display: flex;
  align-items: center;
  padding: 0;
  margin: 0;
  gap: 16px;
  list-style: none;
}
.tabs__control-item {
  padding: 4px 8px;
  border: 1px solid #00000033;
  border-radius: 4px;
  opacity: 0.6;
  transition: 200ms;
  cursor: pointer;
}
.tabs__control-item.active {
  opacity: 1;
  background-color: #00000011;
}
.tabs__control-item:hover {
  opacity: 1;
}
.tabs__content-list {
  padding: 0;
  margin: 0;
  list-style: none;
}
.tabs__content-item {
  opacity: 0;
  transition: 200ms;
}
.tabs__content-item.active {
  opacity: 1;
}
JavaScript
class Tabs {
	constructor(selector) {
		this.selector;
		if (typeof selector == "string") {
			this.selector = document.querySelector(selector);
		} else {
			this.selector = selector;
		}
		this.controls = this.selector.querySelectorAll("[data-control]");
		this.contentItems = this.selector.querySelectorAll("[data-content]");
		this.init();
	}
	init() {
		this.controls.forEach((tabControl) => {
			tabControl.addEventListener("click", (e) => {
				this.deactivateAll();
				this.activate(e);
			});
		});
	}
	activate(e) {
		e.target.closest("[data-control]").classList.add("active");
		this.contentItems.forEach((tabContent) => {
			if (
				tabContent.dataset.content ==
				e.target.closest("[data-control]").dataset.control
			) {
				tabContent.removeAttribute("hidden");
				setTimeout(() => {
					tabContent.classList.add("active");
				}, 10);
			}
		});
	}
	deactivateAll() {
		this.controls.forEach((tabControl) => {
			tabControl.classList.remove("active");
		});
		this.contentItems.forEach((tabContent) => {
			tabContent.classList.remove("active");
			tabContent.setAttribute("hidden", "");
		});
	}
}

document.querySelectorAll(".tabs").forEach((el) => {
	new Tabs(el);
});

Рабочий вариант всегда можно посмотреть на CodePen