Pure CSS Toggle Bulma Responsive Navbar


CSS only toggle responsive Bulma navbar without JavaScript.

Demo 1

Demo 2

Demo 1 is similar to the navbar style of Bulma 0.4.0., and Demo 2 is similar to that of Bulma 0.9.0. The change of navbar style is achieved by the change of placement of input checkbox element and slight change in CSS rules.

The technique is slightly modified from my previous post [1] and applied to the latest Bulma 0.9.0 version. The difference from my previous post is that The placement of invisible input checkbox element is changed so that the css sibling and child selector can be used to toggle the menu and style of the label element.

The key points of the technique [2]:
  • A visible HTML label element (only visible on small screen < 1024px).
  • A invisible HTML input checkbox element, referenced by the label element.
  • The menu to be toggled
  • CSS rules to hide/show the menu according to whether the checkbox is checked.

When users click or touch on the visible label element, it will make the invisible input checkbox checked/unchecked. And CSS rules will show the menu if the checkbox is checked, or hide the menu if the checkbox is unchecked.

Full source code is as follows:

Demo 1:

index-bulma-0.9.0.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
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
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Pure CSS Toggle Bulma Responsive Navbar</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.css" integrity="sha256-oSsWW/ca1ll8OVu2t4EKkyb9lmH0Pkd8CXKXnYP4QvA=" crossorigin="anonymous">
</head>
<body>

<style>
  @media screen and (max-width: 1023px) {
    /* show mavbar-menu on screen less than 1024px */
    #menu-toggle:checked ~ #paliNavbarMenu { display: block; }

    /* make navbar-burger become cross on screen less than 1024px */
    #menu-toggle:checked + .navbar-burger span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
    #menu-toggle:checked + .navbar-burger span:nth-child(2) { opacity: 0; }
    #menu-toggle:checked + .navbar-burger span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
    /* you can also replace + with ~ in above three rules and get the same result */

    #paliNavbarMenu { left:0; right:0; top:100%; position: absolute; }
  }
</style>

<!-- is-flex-touch is important in nav class -->
<nav class="navbar is-flex-touch" role="navigation" aria-label="main navigation">
  <a class="navbar-item">
    Pāli Dictionary
  </a>

  <input type="checkbox" id="menu-toggle" class="is-hidden">
  <label for="menu-toggle" role="button" class="navbar-burger burger">
    <span aria-hidden="true"></span>
    <span aria-hidden="true"></span>
    <span aria-hidden="true"></span>
  </label>


  <div id="paliNavbarMenu" class="navbar-menu">
    <div class="navbar-start">
      <a class="navbar-item">
        Canon
      </a>

      <a class="navbar-item">
        About
      </a>
    </div>

    <div class="navbar-end">
      <div class="navbar-item has-dropdown is-hoverable">
        <a class="navbar-link">
          Language
        </a>

        <div class="navbar-dropdown">
          <a class="navbar-item">
            English
          </a>
          <a class="navbar-item">
            傳統中文
          </a>
          <a class="navbar-item">
            Tiếng Việt
          </a>
          <a class="navbar-item">
            Français
          </a>
        </div>
      </div>
    </div>
  </div>
</nav>

<section class="section">Text here will be covered by mobile navbar menu.</section>

</body>
</html>

Demo 2:

index2-bulma-0.9.0.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
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
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Pure CSS Toggle Bulma Responsive Navbar</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.css" integrity="sha256-oSsWW/ca1ll8OVu2t4EKkyb9lmH0Pkd8CXKXnYP4QvA=" crossorigin="anonymous">
</head>
<body>

<style>
  @media screen and (max-width: 1023px) {
    /* show mavbar-menu on screen less than 1024px */
    #menu-toggle:checked ~ #paliNavbarMenu { display: block; }

    /* make navbar-burger become cross on screen less than 1024px */
    #menu-toggle:checked + .navbar-brand > label > span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
    #menu-toggle:checked + .navbar-brand > label > span:nth-child(2) { opacity: 0; }
    #menu-toggle:checked + .navbar-brand > label > span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
    /* you can also replace + with ~ in above three rules and get the same result */
  }
</style>

<nav class="navbar" role="navigation" aria-label="main navigation">
  <input type="checkbox" id="menu-toggle" class="is-hidden">
  <div class="navbar-brand">
    <a class="navbar-item">
      Pāli Dictionary
    </a>

    <label for="menu-toggle" class="navbar-burger burger">
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
    </label>
  </div>


  <div id="paliNavbarMenu" class="navbar-menu">
    <div class="navbar-start">
      <a class="navbar-item">
        Canon
      </a>

      <a class="navbar-item">
        About
      </a>
    </div>

    <div class="navbar-end">
      <div class="navbar-item has-dropdown is-hoverable">
        <a class="navbar-link">
          Language
        </a>

        <div class="navbar-dropdown">
          <a class="navbar-item">
            English
          </a>
          <a class="navbar-item">
            傳統中文
          </a>
          <a class="navbar-item">
            Tiếng Việt
          </a>
          <a class="navbar-item">
            Français
          </a>
        </div>
      </div>
    </div>
  </div>
</nav>

<section class="section">Text here will NOT be covered by mobile navbar menu.</section>

</body>
</html>

Tested on: Chromium Version 83.0.4103.116 (Official Build) snap (64-bit), Ubuntu 20.04, Bulma 0.9.0