Responsive Navigation Bar (Navbar)


This post shows how to make a responsive top navbar like this website. Before you start, please read [1] and [2] to know how to toogle dropdown menu with CSS and how to create responsive grid layout. Both are used in our responsive top navbar.

Demo

Source Code for Demo (HTML):

layout.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Responsive Navigation Bar (navbar) Demo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

<nav class="top-nav" role="navigation">
  <div class="nav-header-window">
    <div class="toggleable-window visible-xs">
      <input type="checkbox" class="toggle" id="punch" checked>
      <label for="punch">&equiv;<!-- mobile devices cannot show &#8803; (math symbol STRICTLY EQUIVALENT TO) --></label>
      <div>
        <a href="#">Page</a>
        <a href="#">Archives</a>
        <a href="#">Categories</a>
        <a href="#">Tags</a>
        <a href="#">Authors</a>
        <span><a href="#">English</a></span>
        <span><a href="#">傳統中文</a></span>
      </div>
    </div>
    <header><h1><a href="#">{{ SITENAME }}</a></h1></header>
  </div><!--
--><div class="nav-links hidden-xs">
    <ul>
      <li><a href="#">Page</a></li>
      <li><a href="#">Archives</a></li>
      <li><a href="#">Categories</a></li>
      <li><a href="#">Tags</a></li>
      <li><a href="#">Authors</a></li>
    </ul>
  </div><!--
--><div class="nav-lang-select hidden-xs">
    <a href="#">[English]</a>&nbsp;
    <a href="#">[傳統中文]</a>
  </div>
</nav>

</body>
</html>

Source Code for Demo (SCSS):

It is not a good idea to write CSS by hand in this case, so SCSS syntax is used to make life easier.

style.scss | repository | view raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// reponsive class names are the same as bootstrap 3
// @see http://getbootstrap.com/css/
$screen-xs-max: 767;
$screen-sm-min: 768;
$screen-md-min: 992;
$screen-lg-min: 1200;

$smartphone: "(max-width: #{$screen-xs-max}px)";
$non-smartphone: "(min-width: #{$screen-sm-min}px)";

.visible-xs {
  @media #{$non-smartphone} {display: none !important;}
}

.hidden-xs {
  @media #{$smartphone} {display: none !important;}
}

// keep parent element of floated elements from collapsing
@mixin clearfix {
  &:after {
    content:"";
    display:table;
    clear:both;
  }
}

.common-title {
  header {
    h1, h2 {
      @media #{$smartphone} {font-size: 1.25em;}
    }
  }
}

/* pure css toggle-able window */
.toggleable-window {
  input.toggle {display: none;}
  label {
    font-size: 3em;
    font-weight:bold;
    &:hover, &:focus {
      cursor: pointer;
    }
  }
  input.toggle:checked ~ label {font-weight:normal;}
  input.toggle:checked ~ div {display: none;}
  div {
    position: absolute;
    width: 100%;
  }
}

// top navigation bar
.top-nav[role=navigation] {
  @extend .common-title;
  background-image: linear-gradient(to bottom left, white, gray);
  border-radius: 4px;
  margin-top: 8px;

  .nav-header-window, .nav-links, .nav-lang-select {
    display: inline-block;
    vertical-align: middle;
  }

  .nav-header-window {
    width: 30%;
    @media #{$smartphone} {width: 100%;}
    position: relative;
    vertical-align: middle;

    .toggleable-window {
      display: inline-block;
      label {margin-left: 10px;}
      // mobile menu
      div {
        // links for pages, archives,...
        a {
          font-size: 1.5em;
          margin: 0 2px 0 2px;
          display: block;
          padding: 6px 6px 6px 10px;
          background-color: #c0c0c0;
          border-bottom: 2px solid #202020;
        }
        // links for lang
        span a {background-color: #a0a0a0;}
      }
    }
    header {
      display: inline-block;
      @media #{$smartphone} {
        position: absolute;
        right: 10px;
      }
      @media #{$non-smartphone} {margin-left: 10px;}
      h1 { @media #{$smartphone} {font-size: 1.5em;} }
    }
  }

  .nav-links {
    width: 50%;
  }

  .nav-lang-select {
    width: 20%;
  }

  @include clearfix;

  ul li {
    display: inline;
    margin-right: 1em;
  }
}
Tested on:
  • Chromium Version 41.0.2272.76 Ubuntu 14.10 (64-bit)
  • pyScss 1.3.4