mmkm
mmkm

Reputation: 89

Flexbox overlapping absolute positioned elements

I'm trying to make a multilanguage navbar with flexbox, using some JS to toggle visibility of the elements I don't want, but am having trouble retaining the layout with absolute positioning.

Ideally I'd like .language to have absolute positioning so the multilanguage elements can invisibly overlap but applying this overrides the flexbox layout.

.language {
  position: absolute;
}

jsFiddle

function switchLanguage(lang) {
  var languageElements = document.getElementsByClassName('language')
  for (var x in languageElements) {
    if (languageElements[x].getAttribute('lang') != lang) {
      languageElements[x].style.visibility = 'hidden';
    } else {
      languageElements[x].style.visibility = 'visible';
    }
  }
}

switchLanguage('bs')
#menu {
  width: 100vw;
  position: fixed;
  top: 0px;
  text-align: center;
}

ul {
  list-style: none;
}

.container {
  display: flex;
}

.container>li {
  flex: 1;
}

@media all and (max-width: 600px) {
  .container {
    flex-wrap: wrap;
  }
  .container>li {
    flex-basis: 50%;
  }
}

@media all and (max-width: 400px) {
  .container>li {
    flex-basis: 100%;
  }
}

.language {
  z-index: auto;
  position: absolute;
}
<nav id="menu">
  <div class="language" lang="bs">
    <ul class="container">
      <li><a href="#about">O Nama</a></li>
      <li><a href="#hours">Radno Vrijeme</a></li>
      <li><a href="#map">Karta</a></li>
      <li><a href="#">Meni</a></li>
      <li onclick="switchLanguage('en')">English</li>
    </ul>
  </div>
  <div class="language" lang="en">
    <ul class="container">
      <li><a href="#about ">About Us</a></li>
      <li><a href="#hours ">Opening Hours</a></li>
      <li><a href="#map ">Map</a></li>
      <li><a href="# ">Menu</a></li>
      <li onclick="switchLanguage('bs')">Bosanski</li>
    </ul>
  </div>
</nav>

Upvotes: 2

Views: 1997

Answers (2)

Yasir
Yasir

Reputation: 687

Use a css class and switch between the blocks I have used hide class as shown below

HTML:

  <nav id="menu">
    <div class="language hide" lang="bs">
      <ul class="container">
        <li><a href="#about">O Nama</a></li>
        <li><a href="#hours">Radno Vrijeme</a></li>
        <li><a href="#map">Karta</a></li>
        <li><a href="#">Meni</a></li>
        <li onclick="switchLanguage('en')">English</li>
      </ul>
    </div>

    <div class="language" lang="en">
      <ul class="container">
        <li><a href="#about ">About Us</a></li>
        <li><a href="#hours ">Opening Hours</a></li>
        <li><a href="#map ">Map</a></li>
        <li><a href="# ">Menu</a></li>
        <li onclick="switchLanguage('bs')">Bosanski</li>
      </ul>
    </div>
  </nav>

CSS:

#menu {
  width: 100vw;
  position: fixed;
  top: 0px;
  text-align: center;
}

ul {
  list-style: none;
}

.container {
  display: flex;
}

.container>li {
  flex: 1;
}

@media all and (max-width: 600px) {
  .container {
    flex-wrap: wrap;
  }
  .container>li {
    flex-basis: 50%;
  }
}

@media all and (max-width: 400px) {
  .container>li {
    flex-basis: 100%;
  }
}

.language.hide {
  display:none;
}

JS: Modified the JS on the JSfiddle to switch classes

function switchLanguage(lang) {
  var languageElements = document.getElementsByClassName('language')
  for (var x in languageElements) {
    if (languageElements[x].getAttribute('lang') != lang) {
      console.log(languageElements[x].classList);
      languageElements[x].classList.add("hide");
    } else {
      console.log(languageElements[x].classList);
      languageElements[x].classList.remove("hide");
    }
  }
}

switchLanguage('bs')

Please find the working code on the codepen below: https://codepen.io/YasirKamdar/pen/YexWOX

Upvotes: 0

Stickers
Stickers

Reputation: 78776

You need to set the width to the absolute positioned element. Without that it collapses to content size or zero if empty. It's also recommended to apply the correct offsets.

jsFiddle

.language {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}

Upvotes: 3

Related Questions