Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!-- 
ecss nearly: https://ecss.io/  
-->

<!-- tab module -->
<section class="ns-TabsModule" data-active-tab="A">
  
  <!-- horizontal scroll wrapper -->
  <div class="ns-ScrollWrapper">
    <!-- tab nav -->
    <nav class="ns-TabNav">
      <a href="#ns-TabPanelA" class="ns-TabNav_Link" data-tab="A"><span>A</span></a>
      <a href="#ns-TabPanelB" class="ns-TabNav_Link" data-tab="B"><span>Black Eyed</span></a>
      <a href="#ns-TabPanelC" class="ns-TabNav_Link" data-tab="C"><span>Dog</span></a>
      <a href="#ns-TabPanelD" class="ns-TabNav_Link" data-tab="D"><span>He</span></a>
      <a href="#ns-TabPanelE" class="ns-TabNav_Link" data-tab="E"><span>Called</span></a>
      <a href="#ns-TabPanelF" class="ns-TabNav_Link" data-tab="F"><span>At</span></a>
      <a href="#ns-TabPanelG" class="ns-TabNav_Link" data-tab="G"><span>My Door</span></a>
      <span class="ns-TabNav_Indicator"></span>
    </nav><!-- /.ns-TabNav -->
  </div><!-- /.ns-ScrollWrapper -->
  
  <!-- tab panels -->
  <div class="ns-TabPanels">
    <div class="ns-TabPanel" id="ns-TabPanelA" data-tab-panel="A">Panel A</div>
    <div class="ns-TabPanel" id="ns-TabPanelB" data-tab-panel="B">Panel B</div>
    <div class="ns-TabPanel" id="ns-TabPanelC" data-tab-panel="C">Panel C</div>
    <div class="ns-TabPanel" id="ns-TabPanelD" data-tab-panel="D">Panel D</div>
    <div class="ns-TabPanel" id="ns-TabPanelE" data-tab-panel="E">Panel E</div>
    <div class="ns-TabPanel" id="ns-TabPanelF" data-tab-panel="F">Panel F</div>
    <div class="ns-TabPanel" id="ns-TabPanelG" data-tab-panel="G">Panel G</div>
  </div><!-- /.ns-TabPanels -->
  
</section><!-- /.ns-TabsModule -->
              
            
!

CSS

              
                @use postcss-nested;
@use postcss-simple-vars;

$base-unit: 11px;
$indicator-speed: 0.2s;

.ns-TabsModule {
  width: 100%;
  text-align: center;
}

.ns-TabNav {
  position: relative;
  /* wipe out any unwanted whitespace around inline elements */
  font-size: 0;
}

.ns-TabNav_Link {
  display: inline-block;
  margin: 0 $base-unit;
  text-decoration: none;
  font-size: 12px;
  line-height: calc($base-unit * 4);
  color: #bbb;
  text-transform: uppercase;
  span {
    font-size: inherit;
    line-height: inherit;
    letter-spacing: 1px;
    pointer-events: none;
  }
}

.ns-TabNav_Indicator {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100px;
  height: 2px;
  background-color: indianred;
  transition-property: transform, left, background-color;
  transition-duration: $indicator-speed;
  transform-origin: 0;
  transform: translate3d(0, 0, 0) scaleX(0);
  opacity: 0;
  animation: fadeMeIn $indicator-speed forwards;
  animation-delay: $indicator-speed;
}

.ns-TabPanel {
  padding: 40px;
  font-size: 11px;
  color: #505050;
  text-transform: uppercase;
  letter-spacing: 1px;
  display: none;
}

@keyframes fadeMeIn {
  to {
    opacity: 1;
  }
}

/* prettify */

body {
  box-sizing: border-box;
  background: #222;
  height: 100vh;
  overflow: hidden;
  padding-top: 100px;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.ns-ScrollWrapper {
  overflow-x: scroll;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  white-space: nowrap;
  box-shadow: inset 0 -2px 0 0 #404040;
  &::-webkit-scrollbar {
    display: none;
  }
}

/** 
* indicator color for each tab should you need,
* could attach data-color attribute to tab link instead, JS maybe 
* performance should dictate what to do
*/
/*
.ns-TabNav_Indicator {
  [data-active-tab="B"] & { background-color: black; }
  [data-active-tab="C"] & { background-color: mediumaquamarine; }
  [data-active-tab="D"] & { background-color: slateblue; }
  [data-active-tab="E"] & { background-color: coral; }
  [data-active-tab="F"] & { background-color: indianred; }
  [data-active-tab="G"] & { background-color: $color-white; }
}
*/

              
            
!

JS

              
                "use strict";
//tab menu w/tab panel behaviour
//still learning. be kind. 

//get tabs module parent
var tabsModule = document.body.querySelector(".ns-TabsModule");
//get tab nav
var tabNavList = document.body.querySelector(".ns-TabNav");
//get all tab nav links
var tabNavLinks = document.querySelectorAll(".ns-TabNav_Link");
//get tab nav current nav link indicator
var tabNavCurrentLinkindicator = tabNavList.querySelector(".ns-TabNav_Indicator");
//get all tab panels
var tabPanels = document.querySelectorAll(".ns-TabPanel");
//show tab panel A first because panel A nav link has indicator on page load
document.getElementById("ns-TabPanelA").style.display = "block";

/**
* position indicator function
*/
function positionIndicator() {
  //get left position of tab nav ul
  var tabNavListLeftPosition = tabNavList.getBoundingClientRect().left;
  //get tab module parent current data value
  var tabsModuleSectionDataValue = tabsModule.getAttribute("data-active-tab") || "A";
  //get nav link span with data value that matches current tab module parent data value
  var tabNavCurrentLinkText = tabNavList.querySelector("[data-tab='" + tabsModuleSectionDataValue + "'] span");
  //get dimensions of current nav link span
  var tabNavCurrentLinkTextPosition = tabNavCurrentLinkText.getBoundingClientRect();
  //set indicator left position via CSS transform
  //current nav link span left position - tab nav ul left position
  //prefix me for live
  tabNavCurrentLinkindicator.style.transform =
    "translate3d(" +
    (tabNavCurrentLinkTextPosition.left - tabNavListLeftPosition) +
    "px,0,0) scaleX(" +
    tabNavCurrentLinkTextPosition.width * 0.01 +
    ")";
}

/**
* hide all tab panels function
*/
function hideAllTabPanels() {
  //loop through all tab panel elements
  for (i = 0; i < tabPanels.length; i++) {
    //remove style attribute from all tab panels to hide them
    tabPanels[i].removeAttribute("style");
  }
};

/**
* tab nav link function
* tab nav link event displays matching tab panel,
* and positions current tab nav link indicator
*/
var tabNavLinkEvent = function() {
  //get this link data value
  var thisLink = this.getAttribute("data-tab");
  //get this link href value
  var thisHref = this.getAttribute("href");
  //get tab panel element with ID that matches this link href value
  var thisTabPanel = document.querySelector(thisHref);
  //set tab module parent data to this link data value
  tabsModule.setAttribute("data-active-tab", thisLink);
  //fire hide all tab panels function
  hideAllTabPanels();
  //get tab panel element with ID that matches this link href value and set its style to show it
  thisTabPanel.style.display = "block";
  //fire the position indicator function
  positionIndicator();
};

/**
* attach tabNavLinkEvent to all tab nav links
* loop through all nav links and add event
* need to change to parent element and use e.target maybe
*/
for (var i = 0; i < tabNavLinks.length; i++) {
  //for each nav link, add click event that fires tab nav link click event function
  tabNavLinks[i].addEventListener("click", tabNavLinkEvent, false);
}

/** 
* should really position indicator from parent left edge rather than body, 
* to keep indicator in position on resize. meh
* for now, here's a quick win because i'm tired 
* https://developer.mozilla.org/en-US/docs/Web/Events/resize 
*/
(function() {
  //someone smarter than me "debounce" code
  var resizeTimeout;
  function resizeThrottler() {
    if (!resizeTimeout) {
      resizeTimeout = setTimeout(function() {
        resizeTimeout = null;
        actualResizeHandler();
      }, 66);
    }
  }
  //function to fire after resize timeout delay
  function actualResizeHandler() {
    //fire the position indicator function
    positionIndicator();
  }
  //window resize event
  window.addEventListener("resize", resizeThrottler, false);
})();

/**
* fire position indicator function right away
*/
positionIndicator();

//this is old code
//make your own from this for the fun of it :)
//p.s. i'm getting better.

/**
* listen to nick drake for peace of mind
*/
              
            
!
999px

Console