Pen Settings

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

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

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.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
                      <div class="container">
  <nav class="nav" aria-label="Main Navigation">
  <a class="hidden" href="#main" id="skip">Skip to main content</a>
  <ul class="nav__ul" id="navbar1" role="menu" >
    <li role="none" class="nav__li"><a id="twitter" role="menuitem" class="nav__button" href="#">
      <span class="nav__text">Twitter</span>
      <svg aria-hidden="true" class="nav__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <circle class="nav__circle" cx="300" cy="300" r="300" fill="#fff"/>
  <g class="nav__logo">
    <circle cx="300" cy="300" r="272.7" fill="#1da1f2"/>
    <path fill="#fff" d="M256.1,543.9c120.9,0,187.1-100.3,187.1-187.1,0-2.9,0-5.8-.2-8.5a133.4,133.4,0,0,0,32.9-34.1,131.3,131.3,0,0,1-37.8,10.4A65.5,65.5,0,0,0,467,288.2a132.1,132.1,0,0,1-41.7,15.9,65.8,65.8,0,0,0-113.7,45,56.6,56.6,0,0,0,1.8,15,186.6,186.6,0,0,1-135.6-68.7,65.9,65.9,0,0,0,20.5,87.7,65.4,65.4,0,0,1-29.8-8.2v.8a65.9,65.9,0,0,0,52.8,64.5,65.1,65.1,0,0,1-17.3,2.3,64.3,64.3,0,0,1-12.4-1.2A65.6,65.6,0,0,0,253,487a132.2,132.2,0,0,1-81.7,28.1,117.2,117.2,0,0,1-15.7-1,182.6,182.6,0,0,0,100.5,29.8" transform="translate(-6 -100)"/>
      </g>
</svg></a></li>
    <li role="none" class="nav__li"><a role="menuitem" class="nav__button" href="#">
      <span class="nav__text">Instagram</span>
      <svg aria-hidden="true" class="nav__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <defs>
    <linearGradient id="a" x2="1" y1="791.98" y2="791.98" gradientTransform="scale(493.93 -493.93) rotate(46.672 919.155 395.799)" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#ffd521"/>
      <stop offset=".5" stop-color="#f50701"/>
      <stop offset="1" stop-color="#b900b4"/>
    </linearGradient>
  </defs>
  <circle class="nav__circle" cx="300" cy="300" r="300" fill="#fff"/>
  <g class="nav__logo">
    <circle cx="300" cy="300" r="272.7" fill="url(#a)"/>
    <path fill="#fff" d="M305.8,249.5c-39.8,0-44.7.2-60.3.9s-26.2,3.2-35.5,6.8a72.9,72.9,0,0,0-25.9,16.9A71.6,71.6,0,0,0,167.2,300c-3.6,9.3-6.1,19.9-6.8,35.5s-.9,20.5-.9,60.3.2,44.6.9,60.2,3.2,26.2,6.8,35.5a71.6,71.6,0,0,0,16.9,25.9A70.3,70.3,0,0,0,210,534.3c9.3,3.6,19.9,6.1,35.5,6.8s20.5.9,60.3.9,44.6-.2,60.2-.9,26.2-3.2,35.5-6.8a75.1,75.1,0,0,0,42.8-42.8c3.6-9.3,6.1-19.9,6.8-35.5s.9-20.5.9-60.2-.2-44.7-.9-60.3-3.2-26.2-6.8-35.5a70.3,70.3,0,0,0-16.9-25.9,72.9,72.9,0,0,0-25.9-16.9c-9.3-3.6-19.9-6.1-35.5-6.8s-20.5-.9-60.2-.9Zm0,26.4c39,0,43.6.1,59,.8s22,3.1,27.2,5.1a48.1,48.1,0,0,1,27.7,27.7c2,5.2,4.4,12.9,5.1,27.2s.8,20,.8,59.1-.1,43.6-.8,59-3.1,22-5.1,27.2A48.1,48.1,0,0,1,392,509.7c-5.2,2-12.9,4.4-27.2,5.1s-20,.8-59,.8-43.7-.1-59.1-.8-22-3.1-27.2-5.1A48.1,48.1,0,0,1,191.8,482c-2-5.2-4.4-12.9-5.1-27.2s-.8-20-.8-59,.1-43.7.8-59.1,3.1-22,5.1-27.2a48.1,48.1,0,0,1,27.7-27.7c5.2-2,12.9-4.4,27.2-5.1s20-.8,59.1-.8Z" transform="translate(-5.8 -95.8)"/>
    <path fill="#fff" d="M305.8 444.5a48.8 48.8 0 1 1 48.7-48.7A48.7 48.7 0 0 1 305.8 444.5zm0-123.8a75.1 75.1 0 1 0 75 75.1 75.1 75.1 0 0 0-75-75.1zM401.4 317.7a17.6 17.6 0 1 1-17.6-17.5A17.6 17.6 0 0 1 401.4 317.7z" transform="translate(-5.8 -95.8)"/>
      </g>
</svg></a></li>
    <li role="none" class="nav__li"><a role="menuitem" class="nav__button" href="#">
      <span class="nav__text">Github</span>
      <svg aria-hidden="true" class="nav__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <circle class="nav__circle" cx="300" cy="300" r="300" fill="#ffffff"/>
  <g class="nav__logo">
    <circle cx="300" cy="300" r="272.7" fill="#ffffff"/>
    <path fill-rule="evenodd" d="M305.8,123C155.1,123,33,245.1,33,395.8c0,120.6,78.1,222.6,186.5,258.7,13.6,2.4,18.8-5.8,18.8-12.9s-.4-28-.4-50.8c-68.5,12.6-86.2-16.7-91.7-32.1-3.1-7.8-16.4-32-27.9-38.5-9.6-5.1-23.2-17.7-.4-18.1s36.8,19.8,41.9,28c24.6,41.2,63.8,29.6,79.5,22.5,2.4-17.8,9.5-29.7,17.4-36.5-60.7-6.8-124.1-30.3-124.1-134.7,0-29.6,10.5-54.2,27.9-73.3-2.7-6.8-12.2-34.7,2.8-72.2,0,0,22.8-7.2,75,27.9a257,257,0,0,1,136.3,0c52.2-35.4,75-27.9,75-27.9,15,37.5,5.5,65.4,2.7,72.2,17.4,19.1,28,43.3,28,73.3,0,104.7-63.7,127.9-124.4,134.7,9.9,8.5,18.4,24.9,18.4,50.5,0,36.4-.4,65.7-.4,75,0,7.1,5.2,15.6,18.8,12.9,110.7-37.4,185.8-141.9,185.8-258.7C578.5,245.1,456.4,123,305.8,123Z" transform="translate(-5.8 -95.8)"/></g>
</svg></a></li>
    <li role="none" class="nav__li"><a role="menuitem" class="nav__button" href="#">
      <span class="nav__text">Dribbble</span>
      <svg aria-hidden="true" class="nav__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <circle class="nav__circle" cx="300" cy="300" r="300" fill="#ffffff"/>
  <g class="nav__logo">
    <circle cx="300" cy="300" r="261.8" fill="#ea4c89"/>
    <path fill="#c32361" fill-rule="evenodd" d="M305.8,123C155.2,123,33,245.2,33,395.8S155.2,668.5,305.8,668.5,578.5,546.3,578.5,395.8,456,123,305.8,123ZM485.9,248.7a231.9,231.9,0,0,1,52.6,145c-7.6-1.5-84.5-17.2-162-7.4-1.8-3.9-3.3-8-5.1-12.1-4.7-11.3-10-22.8-15.4-33.8,85.8-34.9,124.9-85.1,129.9-91.7ZM305.8,163.3a232.5,232.5,0,0,1,154.4,58.5c-4.2,5.9-39.4,53-122.2,84-38.2-70.1-80.5-127.5-87-136.3a234.3,234.3,0,0,1,54.8-6.2Zm-99.1,21.8c6.2,8.3,47.6,66,86.3,134.6-108.8,29-205,28.4-215.3,28.4C92.8,276,141.6,215.9,206.7,185.1Zm-134,211V389c10,.2,123,1.7,239.3-33.2,6.8,13,13,26.3,18.9,39.7l-9.2,2.6c-120.1,38.8-184,144.7-189.3,153.5A232.1,232.1,0,0,1,72.7,396.1ZM305.8,628.8a231,231,0,0,1-142.9-49.1c4.1-8.5,51.5-99.6,182.8-145.5l1.5-.6c32.8,84.9,46.1,156.2,49.7,176.6A229.7,229.7,0,0,1,305.8,628.8Zm129.8-39.9c-2.4-14.2-14.8-82.2-45.2-165.9,73-11.6,136.9,7.4,144.9,10A230.9,230.9,0,0,1,435.6,588.9Z" transform="translate(-5.8 -95.8)"/></g>
</svg></a></li>
    <li role="none" class="nav__li"><a role="menuitem" class="nav__button" href="#">
      <span class="nav__text">Codepen</span>
      <svg aria-hidden="true" class="nav__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <circle class="nav__circle" cx="300" cy="300" r="300" fill="#ffffff" />
  <g class="nav__logo">
    <circle cx="300" cy="300" r="272.7" fill="#ffffff"/>
    <path
    fill="#000000"
    d="M166.1 371.5V420l36.3-24.2-36.3-24.3zM291.3 336.3V268.7L177.7 344.4l50.7 33.9zM433.8 344.4L320.2 268.7v67.6l62.9 42zM177.7 447.1l113.6 75.7V455.2l-62.9-42-50.7 33.9zM320.2 455.2v67.6l113.6-75.7-50.7-33.9-62.9 42zM305.8 361.5l-51.3 34.3L305.8 430 357 395.8z"
    transform="translate(-5.8 -95.8)"
  />
    <path
    fill="#000000"
   d="M474.4,447.1c0,.7-.1,1.3-.1,1.9s-.1.5-.2.7a5,5,0,0,1-.2,1.2,1.4,1.4,0,0,0-.2.7,4.2,4.2,0,0,0-.4,1l-.3.7-.5,1a1.6,1.6,0,0,0-.4.7,2.7,2.7,0,0,1-.7.8,1.8,1.8,0,0,1-.5.7l-.7.8-.5.5-.9.7-.6.5-.3.2L313.8,562a14.4,14.4,0,0,1-8,2.4,15,15,0,0,1-8.1-2.4L143.6,459.2l-.3-.2-.6-.5a2.7,2.7,0,0,1-.8-.7l-.6-.5-.7-.8a1.8,1.8,0,0,1-.5-.7,2.4,2.4,0,0,1-.6-.8l-.5-.7a9.3,9.3,0,0,0-.5-1l-.3-.7-.3-1-.3-.7a5,5,0,0,1-.2-1.2,1.7,1.7,0,0,1-.1-.7,11.1,11.1,0,0,1-.2-1.9V344.4a11.1,11.1,0,0,1,.2-1.9,1.3,1.3,0,0,1,.1-.6,5.9,5.9,0,0,1,.2-1.3l.3-.7.3-1,.3-.7a9.3,9.3,0,0,0,.5-1l.5-.7c.1-.3.4-.5.6-.8l.5-.7a4.6,4.6,0,0,1,.7-.7l.6-.6a2.7,2.7,0,0,1,.8-.7l.6-.5.3-.2L297.7,229.6a14.3,14.3,0,0,1,16.1,0L467.9,332.3l.3.2.6.5.9.7.5.6a4.6,4.6,0,0,1,.7.7l.5.7.7.8a1.6,1.6,0,0,0,.4.7l.5,1,.3.7a4.2,4.2,0,0,0,.4,1,1.4,1.4,0,0,0,.2.7,5.9,5.9,0,0,1,.2,1.3c.1.2.1.4.2.6s.1,1.2.1,1.9V447.1ZM305.8,123C155.1,123,33,245.1,33,395.8S155.1,668.5,305.8,668.5,578.5,546.4,578.5,395.8,456.4,123,305.8,123"
    transform="translate(-5.8 -95.8)"
  />
    <path
    fill="#000000"
    d="M445.4,420V371.5l-36.3,24.3Z"
    transform="translate(-5.8 -95.8)"
        /></g>
</svg></a></li>
  </ul>
</nav>
<main id="main" class="main">
  <h1>Accessible SVG Navbar</h1>
  <p>Above is an example of a tab-navigable accessibility-conscious navbar comprised of SVG icons. If you click <kbd>Tab</kbd>, you'll see a <a class="main__link" href="#skip" tabindex="-1">skip to main content<a> link so you can skip the navigation. If you continue to tab through, you'll see that a description of each link appears. Once the navbar has focus, it can be navigated using the lateral arrow keys <kbd>⟵</kbd> and <kbd>⟶</kbd>. Pressing <kbd>Escape</kbd> releases focus on the navbar. Pressing the key associated with a particular link also focuses it, so <kbd>t</kbd> for Twitter and <kbd>c</kbd> for Codepen. Importantly, all links contain readable text content, none of which is hidden using <code>display:none</code>—instead, it is positioned offscreen so screen readers can still access it, and made visible when pertinent.</p>
</main>
</div>
            
          
!
            
              $container-color: hsl(0, 7%, 20%);
$container-shadow: hsla(0, 7%, 10%, 100%);

$bg-blue: hsl(200, 70%, 50%);
$bg-pink: hsl(300, 45%, 50%);
$bg-purple: hsl(260, 70%, 60%);

$link-blue: hsl(200, 100%, 72%);
$link-pink: hsl(300, 65%, 75%);

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background: $bg-blue;
  background: linear-gradient(0deg, $bg-pink 0%,
    $bg-purple 50%, $bg-blue 100%);
  color: white;
  display: grid;
  font-family: 'Roboto', sans-serif;;
  
  height: 900px;
  height: 100vh;
  
  padding: 10px;
  place-content: center;
  width: 100%;
}

p {
  line-height: 1.3em;
  hyphens: auto;
  padding: 10px;
  padding: 2vmin;
}

h1 {
  text-align: center;
  text-shadow: 0px 2px 2px black;
  padding: 10px;
  padding: 2vmin;
}

kbd {
  background: white;
  border-radius: .2rem;
  box-shadow: -2px 2px 0px 3px black,
    -2px 2px 0px 4px white;
  color: black;
  
  font-size: 1rem;
  font-size: calc(1vh + (22 - 10) * ((100vw - 300px) / (1600 - 300)));
  
  hyphens: none;
  margin: 0 .5rem 0 .6rem;
  padding: 1px .5em;
  text-shadow: none;
}

.container {
  background: $container-color;
  background: radial-gradient(circle, $container-color 20%, $container-shadow 100%);
  border: 1px solid $container-color;
  border-radius: 1rem;
  box-shadow: 0px 10px 20px 2px hsla(0, 0%, 0%, 0.5);
  display: grid;
  grid-template-rows: auto 1fr;
  
  height: calc(100vh - 15vmin);
  
  width: calc(100vw - 15vmin);
}

.nav {
  background: $container-color;
  background: radial-gradient(circle, $container-color 0%, $container-shadow 100%);
  border-top: 1px solid hsl(0, 7%, 15%);
  box-shadow: 0px 4px white;
  border-radius: 1em 1em 0 0;
  grid-row: 1;
  width: 100%;
}

.hidden {
  position: absolute;
  left:-10000px;
  top:auto;
  overflow:hidden;
}

.hidden:focus {
  background: black;
  border-radius: 5px;
  box-shadow: 0px 0px 8px 1px hsla(0, 0%, 100%, 50%);
  color: white;
  left: 9vmin;
  outline: none;
  padding: 1em;
  text-decoration: none;
  top: 9vmin;
  z-index: 10;
}

.nav__ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
  padding: 1.5rem .5rem;
  list-style: none;
}

.nav__li {
  position: relative;
}

.nav__button {
  position: relative;
}

.nav__button:focus {
  outline: none;
}

.nav__icon {
  border-radius: 50%;
  box-shadow: 0px 5px 15px hsla(0, 0%, 0%, .5);
  transition: transform .1s ease;
  width: calc(6vw + 1rem);
}

.nav__logo {
  opacity: 1;
  transition: opacity .1s ease;
}

.nav__text {
  position: absolute;
  left:-10000px;
  top:auto;
}

.nav__icon:hover {
  transform: scale(1.2);  
}

.nav__logo:hover {
  opacity: 0.5;
}

.nav__button:focus .nav__logo {
  opacity: 0.5;
}

.nav__button:hover > .nav__text, 
.nav__button:focus > .nav__text {
  background: black;
  border-radius: .5rem;
  box-shadow: 0px 0px 10px 1px hsla(0, 0%, 100%, 50%);
  color: white;
  display: block;
  font-size: 1rem;
  padding: 1rem;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-right: -50%;
  transform: translate(-50%, 20%);
  z-index: 10;
}

.nav__button:hover > .nav__text:before,
.nav__button:focus > .nav__text:before {
  content: '';
  display: block;
  height: 0;
  width: 0;
  border-left: .7em solid transparent;
  border-right: .7em solid transparent;
  border-bottom: .8em solid black;
  position: absolute;
  top: 1px;
  left: 50%;
  margin-right: -50%;
  transform: translate(-50%, -100%);
  z-index: 11;
}

.main {
  font-size: 1.2rem;
  font-size: calc(2vh + (28 - 14) * ((100vw - 300px) / (1600 - 300)));
  
  grid-row: 2;
  overflow: scroll;
  
  padding: 20px;
  padding: 6vmin;
}

.main__link {
  text-decoration: none;
  color: $link-blue;
  transition: color .2s ease;
}

.main__link:hover,
.main__link:active,
.main__link:visited {
  color: $link-pink;
}
            
          
!
            
              "use strict";

/*-------------------------------------------------------
You should be able to copy/paste this code into your navbar if:
1. Your page has a single element with the id 'navbar1' and the attribute 'role="menu"'. This element will be the menu's parent element.
2. Your parent has at least two enclosed '<a>' HTML elements with the the attribute 'role="menuitem"' (don't have to be direct children).
3. You can at least browse over this code to make sure I am not maliciously including any dangerous code, like cross-origin requests or evals or weird funkiness you're unsure of.
This code was not technically designed for multiple navbars in a single page, but if you want multiple intances, it isn't necessary to copy/paste this functionality more than once; merely initialize a separate instance of Navbar with a querySelector query for a different id, such as 'navbar2' like this: '#navbar2[role=menu]'
--------------------------------------------------------*/

const Navbar = function(domNode) {
  this.domNode = domNode;
  this.navbarItems = [];
  this.firstChars = [];
  this.firstItem = null;
  this.lastItem = null;
  this.focusedChild = null;
};

Navbar.prototype.init = function() {
  const items = this.domNode.querySelectorAll("a[role=menuitem]");
  const itemsLength = items.length;

  if (itemsLength > 0) {
    for (let i = 0; i < itemsLength; i++) {
      const thisItem = items[i];
      const navbarItem = new NavbarItem(thisItem, this, i);
      navbarItem.init();
      this.navbarItems.push(navbarItem);
      this.firstChars.push(
        thisItem.textContent
          .trim()
          .toLowerCase()
          .substring(0, 1)
      );
    }
    this.firstItem = this.navbarItems[0];
    this.lastItem = this.navbarItems[this.navbarItems.length - 1];
    this.domNode.addEventListener("keydown", this.handleKey.bind(this));
  }
};

Navbar.prototype.handleKey = function(e) {
  const key = e.key;

  switch (key) {
    case "Escape":
      this.focusedChild.domNode.blur();
      break;

    case "ArrowLeft":
      this.focusedChild.index == 0
        ? this.lastItem.domNode.focus()
        : this.navbarItems[this.focusedChild.index - 1].domNode.focus();
      break;

    case "ArrowRight":
      this.focusedChild.index == this.navbarItems.length - 1
        ? this.firstItem.domNode.focus()
        : this.navbarItems[this.focusedChild.index + 1].domNode.focus();
      break;

    case "Home":
      this.firstItem.domNode.focus();
      break;

    case "End":
      this.lastItem.domNode.focus();
      break;

    default:
      if (key.length == 1 && key.match(/\S/)) {
        const lowercase = key.toLowerCase();
        if (this.firstChars.includes(lowercase)) {
          const index = this.focusedChild.index + 1;
          const length = this.navbarItems.length;
          const subarray = this.firstChars.slice(index, length);
          const subindex = subarray.indexOf(lowercase);
          if (subarray.includes(lowercase)) {
            this.navbarItems[subarray.indexOf(lowercase) + index].domNode.focus();
          } else {
            this.navbarItems[
              this.firstChars.indexOf(lowercase)
            ].domNode.focus();
          }
        }
      }
      break;
  }
};

const NavbarItem = function(domNode, parentMenu, index) {
  this.parentMenu = parentMenu;
  this.domNode = domNode;
  this.index = index;
};

NavbarItem.prototype.init = function() {
  this.domNode.addEventListener("focus", this.handleFocus.bind(this));
};

NavbarItem.prototype.handleFocus = function(domNode) {
  this.parentMenu.focusedChild = this;
};

var navbar = new Navbar(document.querySelector("#navbar1[role=menu]"));
navbar.init();

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console