<div class="main container">
  <div class="widget">
    <div class="widget-container">
      <div class="tab-container">

        <div class="tab-list" role="tablist">
          <button role="tab" class="tab active" aria-controls="tab-content-01" id="tab-01" tabindex="0" aria-selected="true"><span>About</span></button>
          <button role="tab" class="tab" aria-controls="tab-content-02" id="tab-02" tabindex="-1" aria-selected="false"><span>Services</span></button>
          <button role="tab" class="tab" aria-controls="tab-content-03" id="tab-03" tabindex="-1" aria-selected="false"><span>Products</span></button>
          <div class="follow"></div>
        </div> <!-- tablist -->

        <div class="tab-content-wrapper">
          <div class="tab-content tab-active" id="tab-content-01" tabindex="0" role="tabpanel" aria-labelledby="tab-01">
            <h2>About</h2>

            <p>
              <code class="snippet">Use your mouse or keyboard to switch tabs </code>
            <ul>
              <li>
                Click tabs using mouse or;
              </li>
              <li>While focused on active tab, use <code>Left</code> and <code>Right</code> arrow keys </li>
            </ul>
            </p>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Corporis rerum repudiandae illum ipsam
              voluptates
              tempore eos? Voluptates illum laborum, porro, expedita sint nulla similique natus amet harum, voluptas
              quae explicabo!</p>
            <a href="#">This is a link </a>
          </div>
          <div class="tab-content" id="tab-content-02" hidden tabindex="0" role="tabpanel" aria-labelledby="tab-02">
            <h2>Services</h2>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Corrupti fuga nostrum temporibus exercitationem
            commodi molestias tenetur, iusto aut laboriosam error impedit debitis a vitae similique enim voluptatem
            vero, officiis consectetur!
            <a href="#">This is a link </a>
          </div>
          <div class="tab-content" id="tab-content-03" hidden tabindex="0" role="tabpanel" aria-labelledby="tab-03">
            <h2>Products</h2>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime officia iste illum, nostrum esse sit
            eveniet laboriosam velit aspernatur fuga, illo quam nulla voluptatem nemo, earum pariatur quis beatae
            magni!
            <a href="#">This is a link </a>
          </div>
        </div>
        <!--tab-content-wrapper -->
      </div>
    </div>
  </div>
</div>
/**
include https://codepen.io/chrisbautista/pen/ZEryzKx.css
*/

// tabbed container
.tab-container {
  $tabPadding: 0.7rem 8px;
  $margin: 0 0.1rem 0.4rem 0;

  h2 {
    font-size: 1.6em;
    font-weight: bold;
    margin-top: 0.5em;
  }

  .tab-list {
    position: relative;
    padding: 2px 5px 0;
    margin: 0;
    display: flex;
    justify-content: flex-start;
    border-bottom: $hairlines;
    width: 100%;
    overflow: hidden;

    &.navigation-selected {
      button {
        &:focus:not(:focus-visible) {
          outline: 2px solid #5a5a5a;
        }
      }
    }

    .follow {
      background-color: $colorHairlines;
      border-top-left-radius: 1rem;
      border-top-right-radius: 1rem;
      display: inline-flex;
      font-weight: bold;
      height: 27px;
      left: 0;
      position: absolute;
      top: 2px;
      width: 55px;
      z-index: 1;
      box-shadow: shadow(low);
      transition: left 0.25s ease-out, width 0.25s ease;
    }

    .tab {
      position: relative;
      z-index: 2;

      display: inline-flex;
      justify-content: center;
      align-items: center;
      background-color: transparent;
      padding: 0;
      margin: 0;
      width: 100%;
      height: 100%;
      color: $colorTextPrimary;
      border: 0;
      box-shadow: none;
      border-top-left-radius: 1rem;
      border-top-right-radius: 1rem;
      border-bottom-left-radius: 0;
      border-bottom-right-radius: 0;
      font-size: 0.875rem;
      padding: $tabPadding;
      transition: color 0.25s ease-out 0.125s;

      span {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 1;
        overflow: hidden;
        width: 100%;
        text-align: center;
        vertical-align: center;
      }

      &.is-keyboard-selected {
        &:focus:not(:focus-visible) {
          outline: 2px solid #5a5a5a;
        }
      }

      &:focus:not(:focus-visible) {
        outline: none;
      }

      &.active {
        color: $colorUiOk;
      }

      &:last-child {
        margin-right: 0;
      }
    }
  }

  .tab-content-wrapper {
    position: relative;
    display: flex;
  }

  .tab-content {
    display: none;
    background-color: $colorCanvas;
    margin-top: 0.2rem;

    &.tab-active {
      display: block;
    }

    &:focus:not(:focus-visible) {
      outline: none;
    }

    &.is-keyboard-selected {
      &:focus:not(:focus-visible) {
        outline: 2px solid #5a5a5a;
      }
    }
  }
}

// presentation

.main {
  margin: 0 auto;
  padding: min(5%, 2.5rem) 0;
  justify-content: center;
  width: min(90%, 600px);
}
View Compiled
const q = (selector, elem = document) => elem.querySelector(selector);
const qAll = (selector, elem = document) => elem.querySelectorAll(selector);
const rect = (elem) => elem.getBoundingClientRect();

(function setupTabContainers() {
  const tabContainers = qAll(".tab-container");

  tabContainers.forEach(setup);

  function setup(tabContainer) {
    const tabs = qAll(".tab", tabContainer);
    const follow = q(".tab-list .follow", tabContainer);
    let currentTabIndex = 0;
    let currentTab = tabs[currentTabIndex];
    let currentTabPanel = q(".tab-content.tab-active", tabContainer);
    if (!currentTabPanel) {
      currentTabPanel = q("tab-content", tabContainer)[currentTabIndex];
    }

    setActiveTab();

    function onTabSelect(e) {
      updateTabs(e.currentTarget);
    }

    function onTabContainerKeyUp(e) {
      e.preventDefault();
      e.stopPropagation();

      if (tabs[currentTabIndex] != document.activeElement) {
        return;
      }

      if (e.code === "ArrowRight" || e.key === "ArrowRight") {
        nextTab();
      } else if (e.code === "ArrowLeft" || e.key === "ArrowLeft") {
        prevTab();
      }
    }

    function nextTab() {
      currentTabIndex++;
      if (currentTabIndex >= tabs.length) {
        currentTabIndex = tabs.length - 1;
      }

      const currentTab = tabs[currentTabIndex];
      updateTabs(currentTab, true);
      currentTab.focus();
    }

    function prevTab() {
      currentTabIndex--;
      if (currentTabIndex < 0) {
        currentTabIndex = 0;
      }

      const currentTab = tabs[currentTabIndex];
      updateTabs(currentTab, true);
      currentTab.focus();
    }

    function updateTabs(target, isKeyboard = false) {
      currentTab.classList.remove("is-keyboard-selected");
      currentTab.classList.toggle("active");
      currentTab.setAttribute("aria-selected", false);
      currentTab.setAttribute("tabindex", "-1");
      target.classList.toggle("active");
      currentTab = target;
      setActiveTab(isKeyboard);
      setContent(currentTab.getAttribute("aria-controls"), isKeyboard);
    }

    function getActiveTabProps(tabRect) {
      const parentRect = tabContainer.getBoundingClientRect();
      return {
        left: tabRect.left - parentRect.left,
        width: tabRect.width,
        height: tabRect.height
      };
    }

    function setActiveTab(isKeyboard) {
      const tabRect = rect(currentTab);
      const newProps = getActiveTabProps(tabRect);
      follow.style.left = `${newProps.left}px`;
      follow.style.width = `${newProps.width}px`;
      follow.style.height = `${newProps.height}px`;
      currentTab.setAttribute("aria-selected", true);
      currentTab.setAttribute("tabindex", "0");

      if (isKeyboard) {
        currentTab.classList.add("is-keyboard-selected");
      }
    }

    function setContent(selector, isKeyboard) {
      // old tab content
      currentTabPanel.classList.toggle("tab-active");

      if (isKeyboard) {
        currentTabPanel.blur();
        currentTabPanel.classList.remove("is-keyboard-selected");
      }

      currentTabPanel.setAttribute("tabindex", "-1");
      currentTabPanel.setAttribute("hidden", true);

      // new tab content
      currentTabPanel = q(`#${selector}`, tabContainer);
      currentTabPanel.classList.toggle("tab-active");
      currentTabPanel.removeAttribute("hidden");
      currentTabPanel.setAttribute("tabindex", "0");
      if (isKeyboard) {
        currentTabPanel.classList.add("is-keyboard-selected");
        currentTabPanel.focus();
      }
    }

    function onResize() {
      setActiveTab();
    }

    tabs.forEach((tab) => {
      tab.addEventListener("click", onTabSelect);
    });

    tabContainer.addEventListener("keyup", onTabContainerKeyUp);
    window.addEventListener("resize", onResize);
  }
})();
View Compiled
Run Pen

External CSS

  1. https://codepen.io/chrisbautista/pen/ZEryzKx.scss

External JavaScript

This Pen doesn't use any external JavaScript resources.