javascripthtmlcssresponsive-designaccessibility

Make a first level menu vertical when there is an overflow caused from a change in the font-size in the browser setting for accessibility reasons


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?


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>