I need help with figuring out how to focus the ‘clicking’ part of this dropdown navbar icon so that I don’t have to click a little to the left of the icon (also the other navbar items) since I’m trying to recreate Mac OS’s navbar.
function myFunction() { document.getElementById("myDropdown").classList.toggle("show"); } // Close the dropdown if the user clicks outside of it window.onclick = function(e) { if (!e.target.matches('.dropbtn')) { var myDropdown = document.getElementById("myDropdown"); if (myDropdown.classList.contains('show')) { myDropdown.classList.remove('show'); } } }
.navbar { overflow: hidden; background-color: #333; font-family: Arial, Helvetica, sans-serif; } .navbar a { float: left; font-size: 12px; color: white; text-align: center; padding: 10px 10px; text-decoration: none; } .dropdown { float: left; overflow: hidden; } .dropdown .dropbtn { cursor: pointer; font-size: 12px; border: none; outline: none; color: white; padding: 5px 10px; background-color: inherit; font-family: inherit; margin: 0; }
<div class="dropdown"> <button class="dropbtn" onclick="myFunction()"> <i class="fa-solid fa-power-off"></i> </button> <div class="dropdown-content" id="myDropdown"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div>
Advertisement
Answer
Problem
I found the source where OP came from and I am not surprised why you ran into trouble. W3Schools is a good resource because it’s simple and never over explains things but at times it omits or just overlooks certain details. In the W3School example “Dropdown Menu Inside a Navigation Bar” the following segment of a CSS ruleset is wrong:
.dropbtn:focus { background-color: red; }
focus
event only applies to the these tags:
<input>
<textarea>
<select>
<a>
It may vary between browsers but the above list is standard. So <button>
is usually not focusable.
Solution
- Change the
<button>
into an<a>
- Add
e.preventDefault();
to the event handler so the page won’t jump when the<a>
is clicked.
The rest of the changes are recommended, but not necessary. Although I strongly suggest that you don’t use inline event handlers:
<button onclick="lame(this)">Don't do this</button>
Instead use:
// onevent property document.querySelector('button').onclick = better;
OR
// event listener document.querySelector('button').addEventListener('click', best);
const menu = document.querySelector("menu"); document.querySelector('.btn').onclick = toggleMenu; function toggleMenu(e) { e.preventDefault(); menu.classList.toggle("show"); } window.onclick = function(e) { if (!e.target.matches('.btn, .btn *') && menu.classList.contains('show')) { menu.classList.remove('show'); } }
html { font: 300 2vmax/1.2 'Segoe UI'; } nav { display: flex; overflow: hidden; background-color: #333; } nav a { display: block; padding: 0.75rem 1.2rem; color: white; text-align: center; text-decoration: none; } .dropdown { min-width: 7.75rem; overflow: hidden; } .btn { display: flex; justify-content: space-between; align-items: center; margin: 0; padding: 0.75rem 1.2rem; border: none; outline: none; color: white; text-align: left; } .btn * { display: block; font-weight: 300; } .btn i { padding-top: 0.15rem; } nav a:hover, .btn:focus { background-color: red; } menu { position: absolute; display: none; min-width: 7.75rem; margin: 0; padding-left: 0; background-color: #f9f9f9; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); } menu a { padding: 0.5rem 1.2rem; text-align: left; color: black; } menu a:hover { background-color: #ddd; } .show { display: block; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <nav> <a href="#home">Home</a> <a href="#news">News</a> <div class='dropdown'> <a href='#' class="btn"><b>Menu</b> <i class="fa fa-chevron-circle-down"></i> </a> <menu> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </menu> </div> </nav>