简体   繁体   中英

How can I turn my navbar links into a dropdown menu with HTML CSS and JavaScript?

I am trying to turn the first two links of my navbar into dropdown menus. I want to make it so that when you click on them, the dropdown menu shows and the arrow icon turns from a downward pointing arrow to an upwards pointing one.

I have tried to use JavaScript to carry out the OnClick events but I have had no success.

For some reason as well, my two dropdown menus are overlapping each other and they are not positioned under the correct navbar links. One should be one appearing under the features link and the other under the company link in the navigation bar. I would also like to request help on how to fix this.

 /* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function myFunction() { document.getElementById("dropdown").classList.toggle("show"); } // Close the dropdown menu if the user clicks outside of it window.onclick = function(event) { if (!event.target.matches('.dropdown-arrow')) { var dropdowns = document.getElementsByClassName("dropdown-content"); var i; for (i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains('show')) { openDropdown.classList.remove('show'); } } } }
 @import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@500;700&display=swap'); * { padding: 0; margin: 0; box-sizing: border-box; font-family: 'Epilogue', 'sans-serif'; } .body-container { background-color: hsl(0, 0%, 98%); height: 100vh; width: 100vw; max-width: 100%; } .navbar { display: flex; align-items: center; } .navbar-flex li { margin-right: auto; display: inline-block; padding: 1em; } .navbar-flex a { color: hsl(0, 0%, 41%); text-decoration: none; } .navbar-flex a:hover { color: hsl(0, 0%, 8%); } .navbar li { list-style-type: none; } .navbar img { padding: 1.5em 1em 1em 2em; } .navbar-btn { margin-left: auto; padding: 1.5em; } .dropdown { position: relative; display: inline-block; } .dropdown-content { /*display: none;*/ position: absolute; min-height: 100px; box-shadow: 0px 8px 16px 0px hsla(0, 0%, 0%, 0.2); z-index: 1; } .dropdown-content a { color: hsl(0, 0%, 8%); padding: 12px 16px; text-decoration: none; display: block; } /* Change color of dropdown links on hover */ .dropdown-content a:hover { background-color: hsl(0, 0%, 41%); } .dropdown-arrow { color: hsl(0, 0%, 41%); outline: none; background: none; border: none; cursor: pointer; } .dropdown-arrow:hover { color: hsl(0, 0%, 8%); } .dropdown-links { text-decoration: none; display: block; padding: 1em; color: hsl(0, 0%, 8%); } .dropdown-links:hover { background-color: hsl(0, 0%, 98%); } .show { display: block; } /* Styles for both buttons in the navbar */ .btn-primary { color: hsl(0, 0%, 41%); outline: none; padding: 0.5em; margin-left: 1em; cursor: pointer; } .btn-primary:hover { color: hsl(0, 0%, 8%); } /* Styles for login button in the navbar */ #login-btn { border: none; background: none; } /* Styles for register button in the navbar */ #register-btn { padding: 0.8em; border-radius: 10px; background: none; border-color: hsl(0, 0%, 41%); border-width: 1px; } .register-btn:hover { border-color: hsl(0, 0%, 8%); }
 <div class="body-container"> <nav class="navbar"> <a href="#"><img src="images/logo.svg" alt="company logo"></a> <ul class="navbar-flex"> <li><a href="#">Features </a> <!-- Features dropdown menu--> <div class="dropdown"> <button onclick="myFunction()" class="dropdown-arrow"> <svg class = "drop-image" svg width="10" height="6" xmlns="http://www.w3.org/2000/svg"><path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4"/></svg> </button> <ul class="dropdown-content"> <li><a class="dropdown-links" href="#">Todo List</a></li> <li><a class="dropdown-links" href="#">Calendars</a></li> <li><a class="dropdown-links" href="#">Reminders</a></li> <li><a class="dropdown-links" href="#">Planning</a></li> </ul> </div> </li> <li><a href="#">Company </a> <!-- Company dropdown menu--> <div class="dropdown"> <button onclick="myFunction()" class="dropdown-arrow"> <svg class = "drop-image" width="10" height="6" xmlns="http://www.w3.org/2000/svg"><path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4"/></svg> </button> <ul id="my-dropdown" class="dropdown-content"> <li><a class="dropdown-links" href="#">History</a></li> <li><a class="dropdown-links" href="#">Our Team</a></li> <li><a class="dropdown-links" href="#">Blog</a></li> </ul> </div> </li> <li><a href="#">Careers</a></li> <li><a href="#">About</a></li> </ul> <div class="navbar-btn"> <button class="btn-primary" id="login-btn">Login</button> <button class="btn-primary" id="register-btn">Register</button> </div> </nav> </div> </div> </div>

I wrote you a possible Vanilla JS approach to handle the behaviour you are looking for:

  1. First select all the li elements in your list;
  2. Add a click event listener;
  3. On each click it adds or remove the classes that show the modal and rotate the arrow, based on a property that I attach to the DOM node, isOpen , so you can always know if a certain element is visually opened or closed. This is useful if you plan to close the other opened dropdowns while opening a new one to prevent overlapping.

 const links = document.querySelectorAll(".navbar-flex>li") links.forEach((el, i) => { el.isOpen = false; el.onclick = e => { const dropdown = el.querySelector(".dropdown") const arrow = el.querySelector(".dropdown-arrow") el.isOpen ? close(dropdown, arrow) : open(dropdown, arrow) el.isOpen = !el.isOpen //Close other open dropdowns links.forEach((el, j) => { const dropdown = el.querySelector(".dropdown") const arrow = el.querySelector(".dropdown-arrow") if (i !== j) { if (el.isOpen) { close(dropdown, arrow) el.isOpen = false } } }) } }) function open(el, arrow) { el.classList.add("show") arrow.classList.add("rotate") } function close(el, arrow) { el.classList.remove("show") arrow.classList.remove("rotate") }
 @import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@500;700&display=swap'); * { padding: 0; margin: 0; box-sizing: border-box; font-family: 'Epilogue', 'sans-serif'; } .body-container { background-color: hsl(0, 0%, 98%); height: 100vh; width: 100vw; max-width: 100%; } .navbar { display: flex; align-items: center; } .navbar-flex li { margin-right: auto; display: inline-block; padding: 1em; } .navbar-flex a { color: hsl(0, 0%, 41%); text-decoration: none; } .navbar-flex a:hover { color: hsl(0, 0%, 8%); } .navbar li { list-style-type: none; } .navbar img { padding: 1.5em 1em 1em 2em; } .navbar-btn { margin-left: auto; padding: 1.5em; } .dropdown { position: absolute; display: none; background: #FFF; } .dropdown-content { min-height: 100px; box-shadow: 0px 8px 16px 0px hsla(0, 0%, 0%, 0.2); z-index: 1; display: flex; flex-direction: column; } .dropdown-content a { color: hsl(0, 0%, 8%); padding: 12px 16px; text-decoration: none; display: block; } /* Change color of dropdown links on hover */ .dropdown-content a:hover { background-color: hsl(0, 0%, 41%); } .dropdown-arrow { color: hsl(0, 0%, 41%); outline: none; background: none; border: none; cursor: pointer; transition: all 0.2s ease-out; } .dropdown-arrow:hover { color: hsl(0, 0%, 8%); } .dropdown-links { text-decoration: none; display: block; padding: 1em; color: hsl(0, 0%, 8%); } .dropdown-links:hover { background-color: hsl(0, 0%, 98%); } .show { display: block !important; } .rotate { transform: rotate(180deg); } /* Styles for both buttons in the navbar */ .btn-primary { color: hsl(0, 0%, 41%); outline: none; padding: 0.5em; margin-left: 1em; cursor: pointer; } .btn-primary:hover { color: hsl(0, 0%, 8%); } /* Styles for login button in the navbar */ #login-btn { border: none; background: none; } /* Styles for register button in the navbar */ #register-btn { padding: 0.8em; border-radius: 10px; background: none; border-color: hsl(0, 0%, 41%); border-width: 1px; } .register-btn:hover { border-color: hsl(0, 0%, 8%); }
 <div class="body-container"> <nav class="navbar"> <a href="#"><img src="images/logo.svg" alt="company logo"></a> <ul class="navbar-flex"> <li> <a href="#">Features </a> <button class="dropdown-arrow"> <svg class = "drop-image" svg width="10" height="6" xmlns="http://www.w3.org/2000/svg"><path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4"/></svg> </button> <!-- Features dropdown menu--> <div class="dropdown"> <ul class="dropdown-content"> <li><a class="dropdown-links" href="#">Todo List</a></li> <li><a class="dropdown-links" href="#">Calendars</a></li> <li><a class="dropdown-links" href="#">Reminders</a></li> <li><a class="dropdown-links" href="#">Planning</a></li> </ul> </div> </li> <li> <a href="#">Company </a> <button class="dropdown-arrow"> <svg class = "drop-image" width="10" height="6" xmlns="http://www.w3.org/2000/svg"><path stroke="#686868" stroke-width="1.5" fill="none" d="m1 1 4 4 4-4"/></svg> </button> <!-- Company dropdown menu--> <div class="dropdown"> <ul id="my-dropdown" class="dropdown-content"> <li><a class="dropdown-links" href="#">History</a></li> <li><a class="dropdown-links" href="#">Our Team</a></li> <li><a class="dropdown-links" href="#">Blog</a></li> </ul> </div> </li> <li><a href="#">Careers</a></li> <li><a href="#">About</a></li> </ul> <div class="navbar-btn"> <button class="btn-primary" id="login-btn">Login</button> <button class="btn-primary" id="register-btn">Register</button> </div> </nav> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM