Responsive Navigation

No CSS

The same HTML is used here as in the hamburger and flex demonstrations. The HTML is shown in the hamburger page and it would be a good idea to open that in a separate window so it can be referred to. Without any CSS styling applied the browser renders the HTML like this:

Hamburger CSS

With the finished Hamburger CSS applied this is the result:

Flex CSS

With the finished Flex CSS applied this is the result:

Responsive CSS

With the finished Responsive CSS the result can be seen at the top of this page. If the browser window is greater than or equal to 500px you see the Flex layout. If the browser window is less than 500px the Hamburger is presented.

To create responsive navigation with a mobile first approach we include all the hamburger CSS at the top of the CSS for the navigation styling. We then place the flex CSS below it inside a media query so it is only applied above a certain screen width. When we do this we get this result:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

When the screen size is below 500px wide we get the hamburger menu exactly as before. At screen sizes above 500px both the hamburger CSS and the flex CSS are being applied and we get a mess. I put the Lorem Ipsum text after the demo so it did not obscure the explanation.

Here is the CSS which results in this mess:


        #nav-1 #hamburger-button {
          width: 3rem;
          background: transparent;
          cursor: pointer;
          border: none;
        }
        #nav-1 .hamburger-bar {
          width: 100%;
          height: 0.2rem;
          background: black;
          display: block;
          margin: 0.4rem 0;
        }
        #nav-1 .top-level-list {
          display: none;
          position: absolute;
        }
        #nav-1:focus-within .top-level-list {
          display: block;
          background-color: lightgrey;
        }
        #nav-1 #hamburger-button {
          position: relative;
        }
        @media screen and (min-width: 500px) {
          #nav-1 #hamburger-button {
            display: none;
          }
          #nav-1 .top-level-list {
            display: flex;
            justify-content: space-around;
            align-items: center;
          }
          #nav-1 .top-level-list ul {
            display: none;
            position: absolute;
            background-color: lightgrey;
          }
          #nav-1 .top-level-list li:focus-within ul {
            display: block;
          }
        }
    

This CSS is simply the hamburger CSS followed by the flex CSS inside a media query. When the media query does not apply, below 500px screen width, the hamburger menu is displayed exactly as before. When the media query does apply the hamburger code interferes with the flex code in the media query.

In the hamburger section of the CSS we have


        #nav-1 .top-level-list {
          display: none;
          position: absolute;
        }
      
In the flex section, in the media query, we have exactly the same selector conferring display, justify-content and align-item properties but not the position property. So our flex top level list has absolute position which disrupts the flex behaviour. We need to add position: relative; to the top level list. We want the top level list to be relative so that the absolutely positioned second level lists will be relative to it. You can see, colored in red, in the next section position: relative is applied to the top level list in the flex section of the CSS.

We also have the problem that in the hamburger section of the CSS code we have the following rule set:


      #nav-1:focus-within .top-level-list {
        display: block;
        background-color: lightgrey;
      }
    

The selector here is more specific than the selector in the flex section of the CSS code which confers display: flex on the top level list. Also nowhere in the flex CSS code is background-color set for the top level list. So, when focus is received anywhere in the nav element, the display reverts from flex to block and the color of the top level list becomes lightgrey as opposed to the default, transparent, value. Again the adjustment to the CSS code to achieve this is shown in red in the next section.

The Finished Product

Here is the finished CSS:


      #nav-2 #hamburger-button {
        width: 3rem;
        background: transparent;
        cursor: pointer;
        border: none;
      }
      #nav-2 .hamburger-bar {
        width: 100%;
        height: 0.2rem;
        background: black;
        display: block;
        margin: 0.4rem 0;
      }
      #nav-2 .top-level-list {
        display: none;
        position: absolute;
      }
      #nav-2:focus-within .top-level-list {
        display: block;
        background-color: lightgrey;
      }
      #nav-2 #hamburger-button {
        position: relative;
      }
      @media screen and (min-width: 500px) {
        #nav-2 #hamburger-button {
          display: none;
        }
        #nav-2:focus-within .top-level-list {
          display: flex;
          background-color: transparent;
        }
        #nav-2 .top-level-list {
          display: flex;
          justify-content: space-around;
          align-items: center;
          position: relative;
        }
        #nav-2 .top-level-list ul {
          display: none;
          position: absolute;
          background-color: lightgrey;
        }
        #nav-2 .top-level-list li:focus-within ul {
          display: block;
        }
      }
    

Hopefully the responsive navigation page replicates the two independent navigation systems at the appropriate screen widths. Keyboard tabbing is not particularly relevant to the smaller screen widths which being mobiles and tablets normally do not have keyboards. At larger screen widths the flex arrangement is displayed and that does retain the keyboard accessibility required.