Flexbox Mobile Navigation

This post is over six (6) months old. Some things on this page my be out of date or no longer applicable.


While working on a template for a client we decided to use Flexbox. I had these requirements set in stone from the get go:

  1. Be Accessible
  2. Load Quickly
  3. Not have a ton of dependencies
  4. Work when javascript may fail

Jquery for all its usefulness I felt was unneeded for this navigation for a few reasons. One being if JQuery wasn't being used on the page I didn't want to load it. Two It would make our dependency tree smaller. Not loading un-needed files helps with #2 requirement and Tim Kadlec's "whatdoesmysitecost.com" really helps put into perspective what heavy sites may cost in other parts of the world. Our browser support was at least Internet Explorer 9. So working off the assumptions of being mobile AND accessible first I came up with Flexbox Mobile Dropdown Navigation

Its a small "module" that should be fine plugged into any site. In the tables below you'll find the sizes of both files - CSS and JavaScript - minified and gzipped. Gzip sizes may differ depending on your servers settings.

File Size Minified Size Gzipped
navigation.min.css (with fallback support) 4.5KB 1.7KB
nav-flexbox-only.min.css (without fallback support) 3.0KB 1.0KB
navigation.android-ie8.min.js 3.3KB 1.9KB
navigation.min.js (without classList polyfill) 1.6KB 1.1KB

This isn't going to be useful to everyone - for instance there is no support for multi-level menus currently - but you can modify it to to fit your needs!

Browser Support:

  • Desktop:
    • Chrome, Firefox, Safari, Opera, Internet Explorer 8+
  • Mobile OS:
    • Android 2.3.1+ (requires the file navigation.android-ie8.min.js or classList Polyfill for Android Gingerbread github.com/eligrey/classList.js)
    • iOS5+
    • Tested on Windows Phone 8.1

Screenshots of the demo page on various browsers:

  • Android 2.3.1 Flexnav Opened and Closed

    Android 2.3.1

  • Android 4.0 Flexnav Opened and Closed

    Android 4.0

  • Android Opera Mini Flexnav Opened and Closed

    Opera Mini

  • Windows Phone 8.1 Flexnav Opened and Closed

    Windows Phone 8.1 (IE 11)

  • Flexnav on iOS 8

    iOS 8 Safari

  • Flexnav with javascript disabled

    No JavaScript

  • Flexnav on Internet Explorer 8

    Internet Explorer 8

  • Flexnav on Internet Explorer 9

    Internet Explorer 9

  • Flexnav on Internet Explorer 10

    Internet Explorer 10

For a demo visit: Flexbox Nav on Github

How To Use

  1. Download the latest release or entire github repo or clone it:
  2. Move the CSS and Js files you wish to use from the dist directory into your css and JS folders of your project along with the menu.png from the img directory to a directory titled "img".
  3. Follow the markup provided below

This is written in a way to assume that JavaScript has failed to load or a user has disabled JavaScript. Also known as progressive enhancement. So I have made a few opinionated assumptions and added a no-js class to the document. This will be removed if you include the bundled modernizr or your own version. To go along with an accessibility minded approach we have not disabled zooming and set the viewport to:

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

More information on the viewport can be found at the a11y project website.


<!doctype html>
  <html class="no-js" lang="en">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>

The CSS File

Add in the CSS file you wish to use from the dist/css directory.


<link rel="stylesheet" href="dist/css/navigation.MOST-CURRENT-DATE-HERE.min.css">

Underneath that add in either the included modernizr from dist/js or your own custom version with flexbox tests.


<script src="js/modernizr.MOST-CURRENT-DATE-HERE.js"></script>


  <header class="fn-header" id="js-header">
    <div class="fn-header__title-container">
      <h1 class="fn-header__name">Your Site Title</h1>
    </div>
    <!-- used for no-js fallbacks -->
    <input type="checkbox" id="fn-noJs" class="fn-navTrigger__no-js"/>
    <label id="fn-noJs_label" for="fn-noJs"></label>
    <!-- /end of no-js fallback -->
    <nav class="fn-nav-container" role="navigation">
      <ul class="fn-navigation" id="js-nav">
        <!-- for each link mark them up as follows -->
        <li class="fn-navigation__item">
          <a href="#first-Link">Link 1</a>
        </li>
      </ul>
    </nav>
    <!-- /.fn-nav-container -->
  </header>
  <!-- /.fn-header -->

On small devices to enable the menu to be closed besides clicking the close button you must add in a <main> tag.


  <!-- previous steps above here -->
  </nav>
</header>
<main>

The JavaScript

Include the navigation js file from dist/js you wish to use before your closing body.

 <script src="dist/js/navigation.android-ie8.min.js" async defer></script> 

Completed Setup


<!doctype html>
<html class="no-js" lang="">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <link rel="stylesheet" href="dist/css/navigation.MOST-CURRENT-DATE-HERE.min.css">
    <!-- any other css files -->
    <script src="js/modernizr.MOST-CURRENT-DATE-HERE.js"></script>
  </head>
<body>
  <header class="fn-header" id="js-header">
    <div class="fn-header__title-container">
      <h1 class="fn-header__name">Your Site Title</h1>
    </div>
    <input type="checkbox" id="fn-noJs" class="fn-navTrigger__no-js"/>
    <label id="fn-noJs_label" for="fn-noJs"></label>
    <nav class="fn-nav-container" role="navigation">
      <ul class="fn-navigation" id="js-nav">
        <li class="fn-navigation__item">
          <a href="#">Link 1</a>
        </li>
        <li class="fn-navigation__item">
          <a href="#">Link 2</a>
        </li>
        <li class="fn-navigation__item">
          <a href="#">Link 3</a>
        </li>
        <li class="fn-navigation__item">
          <a href="#">Link 4</a>
        </li>
        <li class="fn-navigation__item">
          <a href="#">Link 5</a>
        </li>
      </ul>
    </nav>
  </header>
  <main>
  <!-- body content -->
  </main>
  <footer>
  <!-- footer content if present -->
  <footer>
  <script src="dist/js/navigation.android-ie8.min.js" async defer><script>
<body>
<html>