123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- // Defining styles and script here for simplicity.
- ++++
- <style>
- .tabs {
- width: 100%;
- }
- [role="tablist"] {
- margin: 0 0 -0.1em;
- overflow: visible;
- }
- [role="tab"] {
- position: relative;
- padding: 0.3em 0.5em 0.4em;
- border: 1px solid hsl(219, 1%, 72%);
- border-radius: 0.2em 0.2em 0 0;
- overflow: visible;
- font-family: inherit;
- font-size: inherit;
- background: hsl(220, 20%, 94%);
- }
- [role="tab"]:hover::before,
- [role="tab"]:focus::before,
- [role="tab"][aria-selected="true"]::before {
- position: absolute;
- bottom: 100%;
- right: -1px;
- left: -1px;
- border-radius: 0.2em 0.2em 0 0;
- border-top: 3px solid hsl(219, 1%, 72%);
- content: '';
- }
- [role="tab"][aria-selected="true"] {
- border-radius: 0;
- background: hsl(220, 43%, 99%);
- outline: 0;
- }
- [role="tab"][aria-selected="true"]:not(:focus):not(:hover)::before {
- border-top: 5px solid hsl(218, 96%, 48%);
- }
- [role="tab"][aria-selected="true"]::after {
- position: absolute;
- z-index: 3;
- bottom: -1px;
- right: 0;
- left: 0;
- height: 0.3em;
- background: hsl(220, 43%, 99%);
- box-shadow: none;
- content: '';
- }
- [role="tab"]:hover,
- [role="tab"]:focus,
- [role="tab"]:active {
- outline: 0;
- border-radius: 0;
- color: inherit;
- }
- [role="tab"]:hover::before,
- [role="tab"]:focus::before {
- border-color: hsl(218, 96%, 48%);
- }
- [role="tabpanel"] {
- position: relative;
- z-index: 2;
- padding: 1em;
- border: 1px solid hsl(219, 1%, 72%);
- border-radius: 0 0.2em 0.2em 0.2em;
- box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
- background: hsl(220, 43%, 99%);
- margin-bottom: 1em;
- }
- [role="tabpanel"] p {
- margin: 0;
- }
- [role="tabpanel"] * + p {
- margin-top: 1em;
- }
- </style>
- <script>
- window.addEventListener("DOMContentLoaded", () => {
- const tabs = document.querySelectorAll('[role="tab"]');
- const tabList = document.querySelector('[role="tablist"]');
- // Add a click event handler to each tab
- tabs.forEach(tab => {
- tab.addEventListener("click", changeTabs);
- });
- // Enable arrow navigation between tabs in the tab list
- let tabFocus = 0;
- tabList.addEventListener("keydown", e => {
- // Move right
- if (e.keyCode === 39 || e.keyCode === 37) {
- tabs[tabFocus].setAttribute("tabindex", -1);
- if (e.keyCode === 39) {
- tabFocus++;
- // If we're at the end, go to the start
- if (tabFocus >= tabs.length) {
- tabFocus = 0;
- }
- // Move left
- } else if (e.keyCode === 37) {
- tabFocus--;
- // If we're at the start, move to the end
- if (tabFocus < 0) {
- tabFocus = tabs.length - 1;
- }
- }
- tabs[tabFocus].setAttribute("tabindex", 0);
- tabs[tabFocus].focus();
- }
- });
- });
- function setActiveTab(target) {
- const parent = target.parentNode;
- const grandparent = parent.parentNode;
- // console.log(grandparent);
- // Remove all current selected tabs
- parent
- .querySelectorAll('[aria-selected="true"]')
- .forEach(t => t.setAttribute("aria-selected", false));
- // Set this tab as selected
- target.setAttribute("aria-selected", true);
- // Hide all tab panels
- grandparent
- .querySelectorAll('[role="tabpanel"]')
- .forEach(p => p.setAttribute("hidden", true));
- // Show the selected panel
- grandparent.parentNode
- .querySelector(`#${target.getAttribute("aria-controls")}`)
- .removeAttribute("hidden");
- }
- function changeTabs(e) {
- // get the containing list of the tab that was just clicked
- const tabList = e.target.parentNode;
-
- // get all of the sibling tabs
- const buttons = Array.apply(null, tabList.querySelectorAll('button'));
-
- // loop over the siblings to discover which index thje clicked one was
- const { index } = buttons.reduce(({ found, index }, button) => {
- if (!found && buttons[index] === e.target) {
- return { found: true, index };
- } else if (!found) {
- return { found, index: index + 1 };
- } else {
- return { found, index };
- }
- }, { found: false, index: 0 });
-
- // get the tab container
- const container = tabList.parentNode;
- // read the data-tab-group value from the container, e.g. "os"
- const { tabGroup } = container.dataset;
- // get a list of all the tab groups that match this value on the page
- const groups = document.querySelectorAll('[data-tab-group=' + tabGroup + ']');
-
- // for each of the found tab groups, find the tab button at the previously discovered index and select it for each group
- groups.forEach((group) => {
- const target = group.querySelectorAll('button')[index];
- setActiveTab(target);
- });
- }
- </script>
- ++++
|