Two Menus, One responsive Off-Canvas by Myri (@mynimi) on CodePen.
We start with general markup. As already said in another tutorial I usually place my menus within a header so that’s what I did here as well. Then we have one container for both menus and each menu in a separate container with a list inside, since this is a dropdown. The toggle links to open the off canvas navs as well as the triangles to toggle the sub menues are going to be added via jQuery. I wanted the main menu to be aligned on the right and the toggle button on the left. To achieve that I had my toggle in a separate ul with the class first
and the main menu in a list with the class second
Markup in Jade
1 header2 .menu-container3 nav.off-canvas-menu4 ul5 li6 a(href="#") Tasum7 li8 a(href="#") Aldpol9
10 li.menu-item-has-children11 a(href="#") Oughw12 ul.sub-menu13 li14 a(href="#") Shyidra15 li16 a(href="#") Randel17 li18 a(href="#") Ia'usk19 // /.sub-menu20
21 li22 a(href="#") Swaimim23 // /ul24 // /.off-canvas-menu25
26 nav.main-menu27 ul.second28 li29 a(href="#") Smedgone30 li31 a(href="#") Aotaliope32
33 li.menu-item-has-children34 a(href="#") Rothiope35 ul.sub-menu36 li37 a(href="#") Delirious Lyric38 li39 a(href="#") Cleliopyte40 li41 a(href="#") Xioeleia42 // /.sub-menu43
44 li45 a(href="#") Iorireto46 // /ul47 // /.main-menu48 // /.menu-container49 // /header
And the compiled HTML of that:
1 <header>2 <div class="menu-container">3 <nav class="off-canvas-menu">4 <ul>5 <li><a href="#">Tasum</a>6 </li>7 <li><a href="#">Aldpol</a>8 </li>9 <li class="menu-item-has-children"><a href="#">Oughw</a>10 <ul class="sub-menu">11 <li><a href="#">Shyidra</a>12 </li>13 <li><a href="#">Randel</a>14 </li>15 <li><a href="#">Ia'usk</a>16 </li>17 </ul>18 <!-- /.sub-menu-->19 </li>20 <li><a href="#">Swaimim</a>21 </li>22 </ul>23 <!-- /ul-->24 </nav>25 <!-- /.off-canvas-menu-->26 <nav class="main-menu">27 <ul class="second">28 <li><a href="#">Smedgone</a>29 </li>30 <li><a href="#">Aotaliope</a>31 </li>32 <li class="menu-item-has-children"><a href="#">Rothiope</a>33 <ul class="sub-menu">34 <li><a href="#">Delirious Lyric</a>35 </li>36 <li><a href="#">Cleliopyte</a>37 </li>38 <li><a href="#">Xioeleia</a>39 </li>40 </ul>41 <!-- /.sub-menu-->42 </li>43 <li><a href="#">Iorireto </a>44 </li>45 </ul>46 <!-- /ul-->47 </nav>48 <!-- /.main-menu-->49 </div>50 <!-- /.menu-container-->51 </header>52 <!-- /header-->
We will work on toggles with jQuery. So add jQuery before you add the following script
1 $(document).ready(function() {2 var offCanvasToggle = 'toggle-link-off-canvas',3 mainToggle = 'toggle-link',4 close = 'toggle-link-close';5
6 // add toggle links7 $('header').prepend('<span class="toggle ' + mainToggle + '">Menu</span>');8 $('.menu-container').prepend('<span class="toggle ' + mainToggle + ' ' + close + '">close</span>');9 $('.off-canvas-menu').prepend('<span class="toggle ' + offCanvasToggle + ' ' + close + '">close</span>');10 $('.main-menu').prepend('<ul class="first"><li><span class="toggle ' + offCanvasToggle + '">Menu Off-Canvas</span></li></ul>');11
12 // click functions for toggle links to toggle active classes on off-canvas13 $('header .toggle-link').click(function() {14 $('.menu-container').toggleClass('active');15 });16
17 $('header .toggle-link-off-canvas').click(function() {18 $('.off-canvas-menu').toggleClass('active');19 });20
21 // add Element for caret to toggle sub-menus22 $('.menu-item-has-children > a').wrap('<span class="parent"></span>');23 $('.menu-container .parent').append('<span class="submenu-opener">open submenu</span>');24
25 // toggling submenus26 $('.menu-container .submenu-opener').click(function() {27 $(this).toggleClass('sub-menu-is-open');28 $(this).parent().next('.sub-menu').slideToggle();29 });30 });
As soon as that’s done, we can add the styles.
As always I will use Sass. I use variables for the settings so feel free to play around.
Comments will go a little more into detail what everything does
1 // SETTINGS2 //-----------3
4 // helper5 //--------6
7 // colors8 $pink: #E9B4B3;9 $pale-pink: #F2E4E1;10 $coal: #1D2426;11 $teal: #35565D;12 $grass: #8AB283;13
14 // shortcuts15 $noborder: 0 solid transparent;16
17 // variable definitions18 //----------------------19 $menu-collapse: 610px;20 $a_color: $pale-pink;21 $a_color_hover: $pink;22 $header_bg: $grass;23 $off-canvas_bg: $teal;24 $main_menu_bg: $coal;25
26
27 // FUNCTIONS28 //-----------29
30 // squareroot31 @function sqrt($r) {32 $x0: 1;33 $x1: $x0;34 @for $i from 1 through 10 {35 $x1: $x0 - ($x0 * $x0 - abs($r)) / (2 * $x0);36 $x0: $x1;37 }38 @return $x1;39 }40
41 // MIXINS42 //--------43
44 // equilateral triangle45 @mixin triangle_eqla($sl, $dir, $c) {46 width: 0;47 height: 0;48 border-style: solid;49
50 @if $dir == right {51 border-color: transparent transparent transparent $c;52 }53 @if $dir == left {54 border-color: transparent $c transparent transparent;55 }56 @if $dir == bottom or $dir == down {57 border-color: $c transparent transparent transparent;58 }59 @if $dir == top or $dir == up {60 border-color: transparent transparent $c transparent;61 }62 @if $dir == right or $dir == left {63 border-width: ($sl/2) (sqrt(3)*($sl/2));64 }65 @if $dir == top or $dir == down or $dir == bottom or $dir == up {66 border-width: (sqrt(3)*($sl/2)) ($sl/2);67 }68 }69
70 // flexbox71 @mixin flexbox($direction, $wrap, $justify, $align) {72 display: flex;73 flex-direction: $direction;74 flex-wrap: $wrap;75 justify-content: $justify;76 align-items: $align;77 }78
79 // STYLING80 //---------81
82 // basic styles83 body {84 font: {85 size: 16px;86 weight: 400;87 family: Roboto;88 }89 line-height: 1.5;90 }91
92 a {93 color: $a_color;94 text-decoration: none;95 &:hover {96 color: $a_color_hover;97 cursor: pointer;98 }99 }100
101 // main style102 header {103 position: fixed;104 top: 0;105 left: 0;106 width: 100%;107 background: $header_bg;108 line-height: 2;109
110 @media screen and (max-width: $menu-collapse){111 @include flexbox(row, wrap, center, center);112 }113
114 // toggle link styling115 .toggle {116 @extend a;117 padding: 6px;118 }119
120 .toggle-link-close {121 position: absolute;122 top: 0;123 right: 0;124 }125
126 .toggle-link {127 @media screen and (min-width: $menu-collapse + 1) {128 display: none;129 }130 }131
132 .toggle-link-off-canvas {133 @media screen and (max-width: $menu-collapse) {134 display: none;135 }136 }137 }138
139 // menu container, styles will be applied for the responsive version especially140 .menu-container {141 @media screen and (max-width: $menu-collapse) {142 z-index: 100;143 position: fixed;144 top: 0;145 left: -300px;146 height: 100%;147 overflow-y: auto;148 background: $off-canvas_bg;149 width: 300px;150 box-sizing: border-box;151 transition: .3s all ease;152 transform: translate(0, 0);153
154 &.active {155 transform: translate(300px, 0);156 }157 }158
159 // sub menu styles, are the same as with the off-canvas styling160 .sub-menu {161 border-top: 1px solid rgba($coal, .5);162 border-bottom: 1px solid rgba($coal, .5);163 background: lighten($off-canvas_bg, 5%);164 display: none;165
166 li {167 a {168 box-sizing: border-box;169 @media screen and (max-width: $menu-collapse) {170 padding-left: 25px;171 }172 }173 }174 }175
176 // clickable triangle to toggle sub menu visibility177 .parent {178 @include flexbox(row, wrap, flex-start, center);179
180 .submenu-opener {181 font-size: 0;182 position: relative;183 width: 20px;184 height: 20px;185 transition: .6s all ease;186
187 @media screen and (max-width: $menu-collapse) {188 margin-left: 20px;189 }190
191 @media screen and (min-width: $menu-collapse + 1) {192 margin-left: 5px;193 }194
195 &.sub-menu-is-open {196 transform: rotate(-180deg);197 }198
199 &:after {200 content: '';201 @include triangle_eqla(10px, down, $a_color);202 position: absolute;203 top: 50%;204 left: 50%;205 transform: translate(-50%, -20%);206 transition: .3s all ease;207 }208
209 &:hover {210 cursor: pointer;211
212 &:after {213 border-color: $a_color_hover transparent transparent transparent;214 }215 }216 }217 }218 }219
220 // off-canvas navigation221 .off-canvas-menu {222 line-height: 2.5;223
224 @media screen and (min-width: $menu-collapse + 1) {225 z-index: 100;226 position: fixed;227 top: 0;228 left: -300px;229 height: 100%;230 overflow-y: auto;231 background: $off-canvas_bg;232 width: 300px;233 box-sizing: border-box;234 transition: .3s all ease;235 transform: translate(0, 0);236
237 &.active {238 transform: translate(300px, 0);239 }240 }241
242 a {243 padding: 0 10px;244 }245 }246
247 // main menu for responsive and full version248 .main-menu {249 @media screen and (max-width: $menu-collapse) {250 border-top: 1px solid darken($off-canvas_bg, 5%);251 line-height: 2.5;252
253 a {254 padding: 0 10px;255 }256 }257
258 @media screen and (min-width: $menu-collapse + 1) {259 position: fixed;260 width: 100%;261 left: 0;262 right: 0;263 background: $main_menu_bg;264 @include flexbox(row, wrap, space-between, center);265
266 ul {267 @include flexbox(row, wrap, flex-start, center);268
269 li {270 padding: 10px;271 }272 }273
274 .sub-menu {275 top: 100%;276 position: absolute;277 background: lighten($main_menu_bg, 5%);278 }279 }280 }
And the compiled CSS of that:
1 body {2 font-size: 16px;3 font-weight: 400;4 font-family: Roboto;5 line-height: 1.5;6 }7
8 a, header .toggle {9 color: #F2E4E1;10 text-decoration: none;11 }12 a:hover, header .toggle:hover {13 color: #E9B4B3;14 cursor: pointer;15 }16
17 header {18 position: fixed;19 top: 0;20 left: 0;21 width: 100%;22 background: #8AB283;23 line-height: 2;24 }25 @media screen and (max-width: 610px) {26 header {27 display: -webkit-box;28 display: -webkit-flex;29 display: -ms-flexbox;30 display: flex;31 -webkit-box-orient: horizontal;32 -webkit-box-direction: normal;33 -webkit-flex-direction: row;34 -ms-flex-direction: row;35 flex-direction: row;36 -webkit-flex-wrap: wrap;37 -ms-flex-wrap: wrap;38 flex-wrap: wrap;39 -webkit-box-pack: center;40 -webkit-justify-content: center;41 -ms-flex-pack: center;42 justify-content: center;43 -webkit-box-align: center;44 -webkit-align-items: center;45 -ms-flex-align: center;46 align-items: center;47 }48 }49 header .toggle {50 padding: 6px;51 }52 header .toggle-link-close {53 position: absolute;54 top: 0;55 right: 0;56 }57 @media screen and (min-width: 611px) {58 header .toggle-link {59 display: none;60 }61 }62 @media screen and (max-width: 610px) {63 header .toggle-link-off-canvas {64 display: none;65 }66 }67
68 @media screen and (max-width: 610px) {69 .menu-container {70 z-index: 100;71 position: fixed;72 top: 0;73 left: -300px;74 height: 100%;75 overflow-y: auto;76 background: #35565D;77 width: 300px;78 box-sizing: border-box;79 -webkit-transition: .3s all ease;80 transition: .3s all ease;81 -webkit-transform: translate(0, 0);82 -ms-transform: translate(0, 0);83 transform: translate(0, 0);84 }85 .menu-container.active {86 -webkit-transform: translate(300px, 0);87 -ms-transform: translate(300px, 0);88 transform: translate(300px, 0);89 }90 }91 .menu-container .sub-menu {92 border-top: 1px solid rgba(29, 36, 38, 0.5);93 border-bottom: 1px solid rgba(29, 36, 38, 0.5);94 background: #3e656d;95 display: none;96 }97 .menu-container .sub-menu li a, .menu-container .sub-menu li header .toggle, header .menu-container .sub-menu li .toggle {98 box-sizing: border-box;99 }100 @media screen and (max-width: 610px) {101 .menu-container .sub-menu li a, .menu-container .sub-menu li header .toggle, header .menu-container .sub-menu li .toggle {102 padding-left: 25px;103 }104 }105 .menu-container .parent {106 display: -webkit-box;107 display: -webkit-flex;108 display: -ms-flexbox;109 display: flex;110 -webkit-box-orient: horizontal;111 -webkit-box-direction: normal;112 -webkit-flex-direction: row;113 -ms-flex-direction: row;114 flex-direction: row;115 -webkit-flex-wrap: wrap;116 -ms-flex-wrap: wrap;117 flex-wrap: wrap;118 -webkit-box-pack: start;119 -webkit-justify-content: flex-start;120 -ms-flex-pack: start;121 justify-content: flex-start;122 -webkit-box-align: center;123 -webkit-align-items: center;124 -ms-flex-align: center;125 align-items: center;126 }127 .menu-container .parent .submenu-opener {128 font-size: 0;129 position: relative;130 width: 20px;131 height: 20px;132 -webkit-transition: .6s all ease;133 transition: .6s all ease;134 }135 @media screen and (max-width: 610px) {136 .menu-container .parent .submenu-opener {137 margin-left: 20px;138 }139 }140 @media screen and (min-width: 611px) {141 .menu-container .parent .submenu-opener {142 margin-left: 5px;143 }144 }145 .menu-container .parent .submenu-opener.sub-menu-is-open {146 -webkit-transform: rotate(-180deg);147 -ms-transform: rotate(-180deg);148 transform: rotate(-180deg);149 }150 .menu-container .parent .submenu-opener:after {151 content: '';152 width: 0;153 height: 0;154 border-style: solid;155 border-color: #F2E4E1 transparent transparent transparent;156 border-width: 8.66025px 5px;157 position: absolute;158 top: 50%;159 left: 50%;160 -webkit-transform: translate(-50%, -20%);161 -ms-transform: translate(-50%, -20%);162 transform: translate(-50%, -20%);163 -webkit-transition: .3s all ease;164 transition: .3s all ease;165 }166 .menu-container .parent .submenu-opener:hover {167 cursor: pointer;168 }169 .menu-container .parent .submenu-opener:hover:after {170 border-color: #E9B4B3 transparent transparent transparent;171 }172
173 .off-canvas-menu {174 line-height: 2.5;175 }176 @media screen and (min-width: 611px) {177 .off-canvas-menu {178 z-index: 100;179 position: fixed;180 top: 0;181 left: -300px;182 height: 100%;183 overflow-y: auto;184 background: #35565D;185 width: 300px;186 box-sizing: border-box;187 -webkit-transition: .3s all ease;188 transition: .3s all ease;189 -webkit-transform: translate(0, 0);190 -ms-transform: translate(0, 0);191 transform: translate(0, 0);192 }193 .off-canvas-menu.active {194 -webkit-transform: translate(300px, 0);195 -ms-transform: translate(300px, 0);196 transform: translate(300px, 0);197 }198 }199 .off-canvas-menu a, .off-canvas-menu header .toggle, header .off-canvas-menu .toggle {200 padding: 0 10px;201 }202
203 @media screen and (max-width: 610px) {204 .main-menu {205 border-top: 1px solid #2c474d;206 line-height: 2.5;207 }208 .main-menu a, .main-menu header .toggle, header .main-menu .toggle {209 padding: 0 10px;210 }211 }212 @media screen and (min-width: 611px) {213 .main-menu {214 position: fixed;215 width: 100%;216 left: 0;217 right: 0;218 background: #1D2426;219 display: -webkit-box;220 display: -webkit-flex;221 display: -ms-flexbox;222 display: flex;223 -webkit-box-orient: horizontal;224 -webkit-box-direction: normal;225 -webkit-flex-direction: row;226 -ms-flex-direction: row;227 flex-direction: row;228 -webkit-flex-wrap: wrap;229 -ms-flex-wrap: wrap;230 flex-wrap: wrap;231 -webkit-box-pack: justify;232 -webkit-justify-content: space-between;233 -ms-flex-pack: justify;234 justify-content: space-between;235 -webkit-box-align: center;236 -webkit-align-items: center;237 -ms-flex-align: center;238 align-items: center;239 }240 .main-menu ul {241 display: -webkit-box;242 display: -webkit-flex;243 display: -ms-flexbox;244 display: flex;245 -webkit-box-orient: horizontal;246 -webkit-box-direction: normal;247 -webkit-flex-direction: row;248 -ms-flex-direction: row;249 flex-direction: row;250 -webkit-flex-wrap: wrap;251 -ms-flex-wrap: wrap;252 flex-wrap: wrap;253 -webkit-box-pack: start;254 -webkit-justify-content: flex-start;255 -ms-flex-pack: start;256 justify-content: flex-start;257 -webkit-box-align: center;258 -webkit-align-items: center;259 -ms-flex-align: center;260 align-items: center;261 }262 .main-menu ul li {263 padding: 10px;264 }265 .main-menu .sub-menu {266 top: 100%;267 position: absolute;268 background: #283234;269 }270 }
And that’s it.