Skip to content

Instantly share code, notes, and snippets.

@risuvoo
Created December 8, 2025 07:10
Show Gist options
  • Select an option

  • Save risuvoo/0bb137a73093bae40464cb0ef67e20cb to your computer and use it in GitHub Desktop.

Select an option

Save risuvoo/0bb137a73093bae40464cb0ef67e20cb to your computer and use it in GitHub Desktop.
Tab Feature Html, JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Tabs Demo</title>
</head>
<body>
<section data-tab-section="demo-tabs">
<div>
<ul>
<li><button type="button" data-tab-btn="one">Tab One</button></li>
<li><button type="button" data-tab-btn="two">Tab Two</button></li>
<li><button type="button" data-tab-btn="three">Tab Three</button></li>
</ul>
</div>
<div data-tab-content="one">
<p>Content for Tab One.</p>
</div>
<div data-tab-content="two">
<p>Content for Tab Two.</p>
</div>
<div data-tab-content="three">
<p>Content for Tab Three.</p>
</div>
</section>
<script>
function initTabs() {
const tabSections = document.querySelectorAll("[data-tab-section]");
tabSections.forEach((section) => {
const tabButtons = section.querySelectorAll("[data-tab-btn]");
const tabContents = section.querySelectorAll("[data-tab-content]");
// Apply opacity transition to contents
tabContents.forEach((content) => {
content.style.transition = "opacity 0.2s ease-in-out";
content.style.opacity = "0";
content.style.display = "none";
});
const activateTab = (tabValue) => {
// Deactivate buttons
tabButtons.forEach((btn) => btn.classList.remove("active"));
// Fade out current content (if any)
const currentContent = Array.from(tabContents).find(
(c) => c.style.display !== "none"
);
const targetContent = section.querySelector(
`[data-tab-content="${tabValue}"]`
);
// Activate button
const activeButton = section.querySelector(
`[data-tab-btn="${tabValue}"]`
);
if (activeButton) activeButton.classList.add("active");
// If switching between different contents, fade out then in
if (targetContent && targetContent !== currentContent) {
if (currentContent) {
currentContent.style.opacity = "0";
setTimeout(() => {
currentContent.style.display = "none";
}, 200);
}
targetContent.style.display = "block";
// Force reflow for transition
targetContent.getBoundingClientRect();
targetContent.style.opacity = "1";
}
};
// Hook up clicks
tabButtons.forEach((button) => {
button.addEventListener("click", () => {
const tabValue = button.getAttribute("data-tab-btn");
activateTab(tabValue);
});
});
// Activate first tab by default
if (tabButtons.length > 0) {
const firstTabValue = tabButtons[0].getAttribute("data-tab-btn");
// Show first content immediately (no fade delay on init)
const firstContent = section.querySelector(
`[data-tab-content="${firstTabValue}"]`
);
if (firstContent) {
firstContent.style.display = "block";
firstContent.style.opacity = "1";
}
tabButtons[0].classList.add("active");
}
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initTabs);
} else {
initTabs();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment