2
\$\begingroup\$

I'm a beginner in front-end development and tried to make a dropdown menu that includes the toggle button within the menu, instead of opening a separate menu besides the toggle button. I went with such approach because I want to apply either a border or a shadow (like in my example) around the whole menu and toggle button. And I thought only way to achieve that would be to physically include the toggle button inside the dropdown menu.

I don't have much experience but I feel like my approach isn't 'clean', specifically how the dropdown menu is shown and hidden by changing the height. I do apply visibility: hidden to links when the menu is closed, but I'm not sure if that's enough.

I'd like to hear any feedback you might have.

const dropdowns = document.querySelectorAll('.dropdown');

dropdowns.forEach(dropdown => {
  const btn = dropdown.querySelector('[data-toggle]');
  const links = dropdown.querySelectorAll('a');

  dropdown.addEventListener('click', (e) => {
    e.stopPropagation();
  });

  btn.addEventListener('click', (e) => {
    e.preventDefault();

    dropdowns.forEach(elem => {
      if (elem !== dropdown) {
        elem.classList.remove('active');
      }
    });

    dropdown.classList.toggle('active');
  });

  links.forEach(link => {
    link.addEventListener('click', () => {
      dropdown.classList.remove('active');
    });
  });
});

window.onclick = function(event) {
  if (!event.target.matches('.dropdown')) {
    dropdowns.forEach(dropdown => {
      dropdown.classList.remove('active');
    });
  }
}
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: Arial, Helvetica, sans-serif;
}

.container {
  margin-left: 10px;
  max-width: 500px;
}

.dropdown-placeholder {
  position: relative;
  height: 2.2rem;
}

.dropdown {
  position: absolute;
  height: 2.2rem;
  overflow: hidden;
}

.dropdown:not(.active) a {
  visibility: hidden;
}

.dropdown.active {
  background: white;
  box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.75);
  height: max-content;
}

.dropdown.active a {
  visibility: visible;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

button,
a {
  border: none;
  background: none;
  text-decoration: none;
  appearance: none;
}

button,
a {
  display: inline-block;
  margin: 0;
  padding: 0.5em 1em;
  font-size: 1rem;
  font-weight: 700;
  color: rgb(70, 151, 184);
  cursor: pointer;
}

button:hover,
a:hover {
  color: rgb(107, 197, 233);
  ;
}
<section class="container">
  <h1>Lorem ipsum dolor sit amet.</h1>
  <p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto voluptate molestiae placeat.
  </p>
  <div class="dropdown-placeholder">
    <div class="dropdown">
      <ul>
        <li>
          <button data-toggle="">SHARE</button>
        </li>
        <li>
          <a href="#">Social 1</a>
        </li>
        <li>
          <a href="#">Social 2</a>
        </li>
        <li>
          <a href="#">Social 3</a>
        </li>
      </ul>
    </div>
  </div>
  <p>
    Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quos laboriosam repellendus cum ducimus ratione eius laborum corporis laudantium ullam suscipit minus, veritatis repellat aspernatur saepe beatae ipsa, aut ad libero iusto vitae nesciunt distinctio,
    dolorem quibusdam commodi? Itaque inventore, adipisci reiciendis obcaecati minus, expedita quo dolorum autem harum maiores.
  </p>
  <div class="dropdown-placeholder">
    <div class="dropdown">
      <ul>
        <li>
          <button data-toggle="">SHARE</button>
        </li>
        <li>
          <a href="#">Social 1</a>
        </li>
        <li>
          <a href="#">Social 2</a>
        </li>
        <li>
          <a href="#">Social 3</a>
        </li>
      </ul>
    </div>
  </div>
  <p>
    Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quos laboriosam repellendus cum ducimus ratione eius laborum corporis laudantium ullam suscipit minus, veritatis repellat aspernatur saepe beatae ipsa, aut ad libero iusto vitae nesciunt distinctio,
    dolorem quibusdam commodi? Itaque inventore, adipisci reiciendis obcaecati minus, expedita quo dolorum autem harum maiores, voluptatibus consectetur nulla excepturi aliquid corrupti sed totam.
  </p>
</section>

jsfiddle

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.