I'm creating a simple first level menu (here I have a minimum reproducible example) with flexbox. When there isn't enough horizontal space for the seven links I make the menu vertical with a simple media query (the breackpoint is 650 pixels and I'm using the desktop first approach).
However for accessibility reasons I must ensure that with a zoom of the text the content is still OK (no overflow) but it's not the case. If I make a zoom with CTRL + is ok but if I increase the font-size in the browser setting the seven links exceeds the container and in this case I don't know the right breakpoint.
I could use flex-wrap:wrap
on the ul
tag but in this way the links breaks to a new line one at a time instead I would the menu becomes vertical right away. You can simulate an increased font-size in the browser with font-size:2em
on the html
tag (there is a comment in the code). Here it is the code:
* {
box-sizing: border-box;
}
/* html {
font-size: 2em;
} */
body {
margin: 0;
}
.main-menu {
border: 3px solid rgb(230, 121, 38);
padding-block: 0.5rem;
margin: 0 auto;
display: flex;
justify-content: center;
}
.main-menu ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
.main-menu ul li a {
display: block;
padding: 0.7rem;
text-decoration: none;
color: black;
text-transform: uppercase;
font-weight: bold;
font-size: 1.2rem;
border: 1px solid black;
text-align: center;
}
@media (max-width: 650px) {
.main-menu ul {
flex-direction: column;
}
}
<nav class="main-menu">
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
<li><a href="#">Link 6</a></li>
<li><a href="#">Link 7</a></li>
</ul>
</nav>
I could anticipate the breakpoint (a bigger breackpoint) to make the menu vertical for a font-size:2em
but I don't like thi solution. Is there a solution in css only to handle this situation? If not, does it exist a javascript solution?
I found a simple solution on my own in css only. It's enough to set the breackpoint in em and in this manner the modified (also in the browser setting) font-size change automatically the breackpoint. It's very simple. So, I changed 650px to 40.625em
This is the code:
function checkMenuOverflow() {
const menuContainer = document.querySelector(".main-menu");
const menu = document.querySelector(".main-menu ul");
const menuWidth = menu.clientWidth; // Larghezza effettiva del contenuto
console.log("๐ ~ checkMenuOverflow ~ menuWidth:", menuWidth);
const containerWidth = menuContainer.clientWidth; // Larghezza del contenitore visibile
console.log("๐ ~ checkMenuOverflow ~ containerWidth:", containerWidth);
if (menuWidth > containerWidth) {
menu.classList.add("vertical"); // Se c'รจ overflow, aggiungi la classe per layout verticale
} else {
if (menu.clientHeight < containerWidth) {
console.log("๐ ~ checkMenuOverflow ~ menu.clientHeight:", menu.clientHeight);
menu.classList.remove("vertical"); // Altrimenti, rimuovi la classe verticale
}
}
}
// Verifica overflow quando la pagina viene caricata
checkMenuOverflow();
// Verifica overflow quando la finestra viene ridimensionata
window.addEventListener("resize", checkMenuOverflow);
* {
box-sizing: border-box;
}
/* html {
font-size: 2em;
} */
body {
margin: 0;
}
.main-menu {
border: 3px solid rgb(230, 121, 38);
padding-block: 0.5rem;
margin: 0 auto;
display: flex;
justify-content: center;
}
.main-menu ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-shrink: 0;
}
.main-menu ul.vertical {
flex-direction: column;
}
.main-menu ul li a {
display: block;
padding: 0.7rem;
text-decoration: none;
color: black;
text-transform: uppercase;
font-weight: bold;
font-size: 1.2rem;
border: 1px solid black;
text-align: center;
}
@media (max-width: 40.625em) {
.main-menu ul {
flex-direction: column;
}
}
<nav class="main-menu">
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
<li><a href="#">Link 6</a></li>
<li><a href="#">Link 7</a></li>
</ul>
</nav>