<!--
  Related blog post:
  https://css-tricks.com/container-adapting-tabs-with-more-button/
-->

<nav class="tabs">
  <ul class="-primary">
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Falkenberg">
        Falkenberg
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Braga">
        Braga
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Stockholm">
        Stockholm
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Trnava">
        Trnava
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Plovdiv">
        Plovdiv
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Klaip%C4%97da">
        Klaipėda
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Punta_Cana">
        Punta Cana
      </a>
    <li>
      <a target="_blank" href="https://en.wikipedia.org/wiki/Lisbon">
        Lisbon
      </a>
  </ul>
</nav>
// defaults

$color-bg: #D51E49;
$color-bg--dark: darken($color-bg, 7%);
$color-bg--darker: darken($color-bg, 14%);

$color-text: #FAF3DD;

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  background-color: $color-text;
  padding: 2em;
}

a {
  text-decoration: none;
}

button {
  cursor: pointer;
  border: 0;
  padding: 0;
}

// tabs

.tabs {
  position: relative;

  &:not(.--jsfied) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  
  // shared
  
  .--hidden {
    display: none;
  }

  a,
  button {
    width: 100%;
    height: 100%;
    display: block;
    font-size: 1em;
    line-height: 1.2;
    text-align: center;
    color: $color-text;
    background-color: transparent;
  }
  
  // primary

  .-primary {
    display: flex;
    
    > li {
      flex-grow: 1;
      background-color: $color-bg;
      
      + li {
        border-left: 1px solid $color-bg--dark;
      }

      > a,
      > button {
        white-space: nowrap;
        padding: 1em 0.6em;
        box-shadow: inset 0 -0.2em 0 $color-bg--dark;

        &:hover  { background-color: $color-bg--dark; }
        &:active { background-color: $color-bg--darker; }
      }
    }
    
    .-more {
      background-color: $color-bg--dark;

      > button span {
        display: inline-block;
        transition: transform 0.2s;
      }
    }
  }
  
  &.--show-secondary .-primary {
    .-more > button span {
      transform: rotate(180deg);
    }
  }
  
  // secondary
  
  .-secondary {
    max-width: 100%;
    min-width: 10em;
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    box-shadow: 0 0.3em 0.5em rgba(#000, 0.3);
    animation: nav-secondary 0.2s;

    li {      
      border-top: 1px solid $color-bg;
      background-color: $color-bg--dark;
    }
    
    a,
    button {
      padding: 0.6em;
      
      &:hover  { background-color: $color-bg--darker; }
      &:active { background-color: $color-bg; }
    }
  }
  
  &.--show-secondary .-secondary {
    display: block;
  }
}

// keyframes

@keyframes nav-secondary {
  0% {
    opacity: 0;
    transform: translateY(-1em);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
/*
  Consider using these polyfills to broaden browser support:
    — https://www.npmjs.com/package/classlist-polyfill
    — https://www.npmjs.com/package/nodelist-foreach-polyfill
*/

const container = document.querySelector('.tabs')
const primary = container.querySelector('.-primary')
const primaryItems = container.querySelectorAll('.-primary > li:not(.-more)')
container.classList.add('--jsfied')

// insert "more" button and duplicate the list

primary.insertAdjacentHTML('beforeend', `
  <li class="-more">
    <button type="button" aria-haspopup="true" aria-expanded="false">
      More <span>&darr;</span>
    </button>
    <ul class="-secondary">
      ${primary.innerHTML}
    </ul>
  </li>
`)
const secondary = container.querySelector('.-secondary')
const secondaryItems = secondary.querySelectorAll('li')
const allItems = container.querySelectorAll('li')
const moreLi = primary.querySelector('.-more')
const moreBtn = moreLi.querySelector('button')
moreBtn.addEventListener('click', (e) => {
  e.preventDefault()
  container.classList.toggle('--show-secondary')
  moreBtn.setAttribute('aria-expanded', container.classList.contains('--show-secondary'))
})

// adapt tabs

const doAdapt = () => {
  // reveal all items for the calculation
  allItems.forEach((item) => {
    item.classList.remove('--hidden')
  })

  // hide items that won't fit in the Primary
  let stopWidth = moreBtn.offsetWidth
  let hiddenItems = []
  const primaryWidth = primary.offsetWidth
  primaryItems.forEach((item, i) => {
    if(primaryWidth >= stopWidth + item.offsetWidth) {
      stopWidth += item.offsetWidth
    } else {
      item.classList.add('--hidden')
      hiddenItems.push(i)
    }
  })
  
  // toggle the visibility of More button and items in Secondary
  if(!hiddenItems.length) {
    moreLi.classList.add('--hidden')
    container.classList.remove('--show-secondary')
    moreBtn.setAttribute('aria-expanded', false)
  }
  else {  
    secondaryItems.forEach((item, i) => {
      if(!hiddenItems.includes(i)) {
        item.classList.add('--hidden')
      }
    })
  }
}

doAdapt() // adapt immediately on load
window.addEventListener('resize', doAdapt) // adapt on window resize

// hide Secondary on the outside click

document.addEventListener('click', (e) => {
  let el = e.target
  while(el) {
    if(el === secondary || el === moreBtn) {
      return;
    }
    el = el.parentNode
  }
  container.classList.remove('--show-secondary')
  moreBtn.setAttribute('aria-expanded', false)
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.