├── .gitignore ├── docs ├── favicon.png ├── theme-1.png ├── theme-2.png ├── hc-offcanvas-nav.png ├── knockout.html ├── demo.scss ├── index.html └── hc-offcanvas-nav.js ├── src ├── scss │ ├── _toggle.scss │ ├── hc-offcanvas-nav.scss │ ├── hc-offcanvas-nav.carbon.scss │ ├── _mixins.scss │ ├── _core.scss │ ├── _theme-carbon.scss │ └── _theme-default.scss └── js │ └── hc-offcanvas-nav.helpers.js ├── LICENSE ├── package.json ├── gulpfile.js ├── dist ├── hc-offcanvas-nav.carbon.css ├── hc-offcanvas-nav.css └── hc-offcanvas-nav.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somewebmedia/hc-offcanvas-nav/HEAD/docs/favicon.png -------------------------------------------------------------------------------- /docs/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somewebmedia/hc-offcanvas-nav/HEAD/docs/theme-1.png -------------------------------------------------------------------------------- /docs/theme-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somewebmedia/hc-offcanvas-nav/HEAD/docs/theme-2.png -------------------------------------------------------------------------------- /src/scss/_toggle.scss: -------------------------------------------------------------------------------- 1 | @import './mixins'; 2 | 3 | .hc-nav-trigger { 4 | @include hc-hamburger; 5 | } -------------------------------------------------------------------------------- /src/scss/hc-offcanvas-nav.scss: -------------------------------------------------------------------------------- 1 | @import './core'; 2 | @import './toggle'; 3 | @import './theme-default'; -------------------------------------------------------------------------------- /src/scss/hc-offcanvas-nav.carbon.scss: -------------------------------------------------------------------------------- 1 | @import './core'; 2 | @import './toggle'; 3 | @import './theme-carbon'; -------------------------------------------------------------------------------- /docs/hc-offcanvas-nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somewebmedia/hc-offcanvas-nav/HEAD/docs/hc-offcanvas-nav.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Some Web Media 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hc-offcanvas-nav", 3 | "version": "6.1.5", 4 | "description": "JavaScript library for creating off-canvas multi-level navigations", 5 | "homepage": "https://somewebmedia.github.io/hc-offcanvas-nav/", 6 | "main": "dist/hc-offcanvas-nav.js", 7 | "sass": "src/scss/hc-offcanvas-nav.scss", 8 | "author": { 9 | "name": "Some Web Media", 10 | "url": "https://github.com/somewebmedia" 11 | }, 12 | "license": "MIT", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/somewebmedia/hc-offcanvas-nav.git" 16 | }, 17 | "devDependencies": { 18 | "@babel/cli": "^7.12.8", 19 | "@babel/core": "^7.12.9", 20 | "@babel/preset-env": "^7.12.7", 21 | "gulp": "^4.0.2", 22 | "gulp-autoprefixer": "^6.1.0", 23 | "gulp-babel": "^8.0.0", 24 | "gulp-bump": "^3.2.0", 25 | "gulp-concat": "^2.6.1", 26 | "gulp-open": "^3.0.1", 27 | "gulp-replace": "^1.0.0", 28 | "gulp-sass": "^5.0.0", 29 | "gulp-uglify": "^3.0.2", 30 | "node-sass": "^6.0.1", 31 | "uglify-save-license": "^0.4.1", 32 | "yargs": "^15.4.1" 33 | }, 34 | "keywords": [ 35 | "nav", 36 | "navigation", 37 | "menu", 38 | "offcanvas", 39 | "mobile", 40 | "mobile-nav", 41 | "hamburger", 42 | "hamburger-menu", 43 | "swipe-menu", 44 | "jquery", 45 | "plugin", 46 | "jquery-plugin" 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /src/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | $hc-offcanvas-nav-trigger-width: 30px !default; 2 | $hc-offcanvas-nav-trigger-height: 24px !default; 3 | $hc-offcanvas-nav-trigger-line-width: 4px !default; 4 | $hc-offcanvas-nav-trigger-color: #34495E !default; 5 | $hc-offcanvas-nav-trigger-transform-speed: .2s !default; 6 | 7 | @mixin hc-hamburger($type: 'default', $width: $hc-offcanvas-nav-trigger-width, $height: $hc-offcanvas-nav-trigger-height, $line-width: $hc-offcanvas-nav-trigger-line-width, $color: $hc-offcanvas-nav-trigger-color, $transform-speed: $hc-offcanvas-nav-trigger-transform-speed) { 8 | position: absolute; 9 | cursor: pointer; 10 | user-select: none; 11 | display: none; 12 | top: 20px; 13 | z-index: 9980; 14 | width: $width; 15 | min-height: $height; 16 | 17 | $line-offset: ($height - $line-width) / 2; 18 | 19 | span { 20 | width: $width; 21 | top: 50%; 22 | transform: translateY(-50%); 23 | transform-origin: 50% 50%; 24 | 25 | &, 26 | &::before, 27 | &::after { 28 | display: block; 29 | position: absolute; 30 | left: 0; 31 | height: $line-width; 32 | background: $color; 33 | transition: all $transform-speed ease; 34 | } 35 | 36 | &::before, 37 | &::after { 38 | content: ''; 39 | width: 100%; 40 | } 41 | 42 | &::before { 43 | top: -$line-offset; 44 | } 45 | 46 | &::after { 47 | bottom: -$line-offset; 48 | } 49 | } 50 | 51 | &.toggle-open { 52 | 53 | span { 54 | background: rgba(0, 0, 0, 0); 55 | transform: rotate(45deg); 56 | 57 | &::before { 58 | transform: translate3d(0, $line-offset, 0); 59 | } 60 | 61 | &::after { 62 | transform: rotate(-90deg) translate3d($line-offset, 0, 0); 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const { src, dest, parallel, series, watch } = require('gulp'); 2 | const glob = require('glob'); 3 | const sass = require('gulp-sass')(require('node-sass')); 4 | const autoprefixer = require('gulp-autoprefixer'); 5 | const uglify = require('gulp-uglify'); 6 | const concat = require('gulp-concat'); 7 | const open = require('gulp-open'); 8 | const saveLicense = require('uglify-save-license'); 9 | const babel = require('gulp-babel'); 10 | const through = require('through2'); 11 | const path = require('path'); 12 | const argv = require('yargs').argv; 13 | const bump = require('gulp-bump'); 14 | const replace = require('gulp-replace'); 15 | 16 | const compileJs = () => { 17 | return src([ 18 | './src/js/hc-offcanvas-nav.js', 19 | './src/js/hc-offcanvas-nav.helpers.js' 20 | ]) 21 | .pipe(concat('hc-offcanvas-nav.js')) 22 | .pipe(babel( 23 | { 24 | presets: [ 25 | [ 26 | '@babel/preset-env', 27 | { 28 | modules: false, 29 | loose: true, 30 | exclude: ['transform-typeof-symbol'] 31 | } 32 | ] 33 | ] 34 | } 35 | )) 36 | .pipe(argv.dev ? through.obj() : uglify({ 37 | output: { 38 | comments: saveLicense 39 | } 40 | })) 41 | .pipe(dest('./docs/')) // demo 42 | .pipe(dest('./dist/')); 43 | }; 44 | 45 | const compileScss = () => { 46 | return src(['./src/scss/*.scss']) 47 | .pipe(sass({ 48 | 'includePaths': ['node_modules'], 49 | 'outputStyle': argv.dev ? 'development' : 'compressed' 50 | }).on('error', sass.logError)) 51 | .pipe(autoprefixer()) 52 | .pipe(dest('./dist/')); 53 | }; 54 | 55 | const compileDemoScss = () => { 56 | return src(['./docs/demo.scss']) 57 | .pipe(sass({ 58 | 'includePaths': ['node_modules'], 59 | 'outputStyle': argv.dev ? 'development' : 'compressed' 60 | }).on('error', sass.logError)) 61 | .pipe(autoprefixer()) 62 | .pipe(dest('./docs/')); 63 | }; 64 | 65 | const runDemo = () => { 66 | return src('./docs/index.html').pipe(open()); 67 | }; 68 | 69 | const bumpPackage = () => { 70 | return src('./*.json') 71 | .pipe(bump(argv.ver && argv.ver.indexOf('.') > -1 ? {version: argv.ver} : {type: argv.ver || 'patch'})) 72 | .pipe(dest('./')); 73 | }; 74 | 75 | const bumpJs = () => { 76 | const package = require('./package.json'); 77 | 78 | return src(['./src/js/*.js']) 79 | .pipe(replace(/ \* Version: ([\d\.]+)/g, () => { 80 | return ` * Version: ${package.version}`; 81 | })) 82 | .pipe(dest('./src/js/')) 83 | }; 84 | 85 | const bumpHtml = () => { 86 | const package = require('./package.json'); 87 | 88 | return src(['./docs/*.html']) 89 | .pipe(replace(/\?ver=([\d\.]+)/g, () => { 90 | return `?ver=${package.version}`; 91 | })) 92 | .pipe(replace(/v([\d\.]+)/g, () => { 93 | return `v${package.version}`; 94 | })) 95 | .pipe(dest('./docs/')) 96 | }; 97 | 98 | const defaultTask = parallel(compileJs, compileScss, compileDemoScss); 99 | 100 | const watchFiles = () => { 101 | const watch_scss = glob.sync('./src/scss/*.scss'); 102 | const watch_js = glob.sync('./src/js/*.js'); 103 | const watch_demo = glob.sync('./docs/demo.scss'); 104 | 105 | watch(watch_scss, parallel(compileScss, compileDemoScss)); 106 | watch(watch_demo, compileDemoScss); 107 | watch(watch_js, compileJs); 108 | }; 109 | 110 | module.exports.default = defaultTask; 111 | module.exports.watch = series(defaultTask, watchFiles); 112 | module.exports.bump = series(bumpPackage, bumpJs, bumpHtml, compileJs); 113 | module.exports.demo = series(defaultTask, runDemo); -------------------------------------------------------------------------------- /docs/knockout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 40 | 41 | 54 | 55 | 132 | 133 |
134 | 135 | 136 | -------------------------------------------------------------------------------- /src/scss/_core.scss: -------------------------------------------------------------------------------- 1 | $hc-offcanvas-nav-transition-duration: .4s !default; 2 | $hc-offcanvas-nav-transition-timing-function: ease !default; 3 | 4 | html.hc-nav-yscroll { 5 | overflow-y: scroll; 6 | } 7 | 8 | body.hc-nav-open { 9 | overflow: visible; 10 | position: fixed; 11 | width: 100%; 12 | min-height: 100%; 13 | } 14 | 15 | .hc-offcanvas-nav { 16 | visibility: hidden; 17 | display: none; 18 | position: fixed; 19 | top: 0; 20 | height: 100%; 21 | z-index: 9999; 22 | text-align: left; 23 | 24 | &.is-ios { 25 | * { 26 | cursor: pointer !important; 27 | } 28 | } 29 | 30 | .nav-container { 31 | position: fixed; 32 | z-index: 9998; 33 | top: 0; 34 | height: 100%; 35 | max-width: 100%; 36 | max-height: 100%; 37 | box-sizing: border-box; 38 | transition: transform $hc-offcanvas-nav-transition-duration $hc-offcanvas-nav-transition-timing-function; 39 | } 40 | 41 | .nav-wrapper { 42 | width: 100%; 43 | height: 100%; 44 | box-sizing: border-box; 45 | overscroll-behavior: none; 46 | } 47 | 48 | .nav-content { 49 | height: 100%; 50 | } 51 | 52 | .nav-wrapper-0 { 53 | & > .nav-content { 54 | overflow: scroll; 55 | overflow-x: visible; 56 | overflow-y: auto; 57 | box-sizing: border-box; 58 | } 59 | } 60 | 61 | ul { 62 | list-style: none; 63 | margin: 0; 64 | padding: 0; 65 | } 66 | 67 | li { 68 | position: relative; 69 | display: block; 70 | 71 | &.level-open { 72 | & > .nav-wrapper { 73 | visibility: visible; 74 | } 75 | } 76 | 77 | &:not(.custom-content) { 78 | a { 79 | position: relative; 80 | display: block; 81 | box-sizing: border-box; 82 | cursor: pointer; 83 | 84 | &[disabled] { 85 | cursor: not-allowed; 86 | } 87 | 88 | &, 89 | &:hover { 90 | text-decoration: none; 91 | } 92 | } 93 | } 94 | } 95 | 96 | input[type="checkbox"] { 97 | display: none; 98 | } 99 | 100 | label { 101 | position: absolute; 102 | top: 0; 103 | left: 0; 104 | right: 0; 105 | bottom: 0; 106 | z-index: 10; 107 | cursor: pointer; 108 | } 109 | 110 | .nav-item-wrapper { 111 | position: relative; 112 | } 113 | 114 | .nav-item-link { 115 | position: relative; 116 | display: block; 117 | box-sizing: border-box; 118 | } 119 | 120 | &:not(.user-is-tabbing) { 121 | .nav-close-button, 122 | .nav-item-wrapper a { 123 | &:focus { 124 | outline: none; 125 | } 126 | } 127 | } 128 | 129 | .nav-close, 130 | .nav-next, 131 | .nav-back { 132 | &:focus { 133 | z-index: 10; 134 | } 135 | } 136 | 137 | // Background overlay 138 | 139 | &.disable-body, 140 | .nav-wrapper { 141 | &::after { 142 | content: ''; 143 | z-index: 9990; 144 | top: 0; 145 | left: 0; 146 | right: 0; 147 | bottom: 0; 148 | width: 100%; 149 | height: 100%; 150 | overscroll-behavior: none; 151 | visibility: hidden; 152 | opacity: 0; 153 | transition: visibility 0s ease $hc-offcanvas-nav-transition-duration, opacity $hc-offcanvas-nav-transition-duration ease; 154 | } 155 | } 156 | 157 | &.disable-body { 158 | &::after { 159 | position: fixed; 160 | } 161 | } 162 | 163 | .nav-wrapper { 164 | &::after { 165 | position: absolute; 166 | } 167 | } 168 | 169 | &.disable-body.nav-open, 170 | .sub-level-open { 171 | &::after { 172 | visibility: visible; 173 | opacity: 1; 174 | transition-delay: .05s; 175 | } 176 | } 177 | 178 | &:not(.nav-open) { 179 | &::after { 180 | pointer-events: none; 181 | } 182 | } 183 | 184 | // Expand Levels 185 | &.nav-levels-expand { 186 | 187 | .nav-wrapper { 188 | 189 | &::after { 190 | display: none; 191 | } 192 | 193 | &.nav-wrapper-0 { 194 | max-height: 100vh; 195 | 196 | & > .nav-content { 197 | overflow: scroll; 198 | overflow-x: visible; 199 | overflow-y: auto; 200 | box-sizing: border-box; 201 | max-height: 100vh; 202 | } 203 | } 204 | } 205 | 206 | ul { 207 | .nav-wrapper { 208 | min-width: 0; 209 | max-height: 0; 210 | visibility: hidden; 211 | overflow: hidden; 212 | transition: height 0s ease $hc-offcanvas-nav-transition-duration; 213 | } 214 | } 215 | 216 | .level-open { 217 | & > .nav-wrapper { 218 | max-height: none; 219 | overflow: visible; 220 | visibility: visible; 221 | } 222 | } 223 | } 224 | 225 | // Transform Levels 226 | &.nav-levels-overlap { 227 | 228 | .nav-content { 229 | overflow: scroll; 230 | overflow-x: visible; 231 | overflow-y: auto; 232 | box-sizing: border-box; 233 | max-height: 100vh; 234 | } 235 | 236 | .nav-wrapper { 237 | max-height: 100vh; 238 | } 239 | 240 | ul { 241 | 242 | .nav-wrapper { 243 | position: absolute; 244 | z-index: 9999; 245 | top: 0; 246 | height: 100%; 247 | visibility: hidden; 248 | transition: visibility 0s ease $hc-offcanvas-nav-transition-duration, transform $hc-offcanvas-nav-transition-duration $hc-offcanvas-nav-transition-timing-function; 249 | } 250 | 251 | li { 252 | 253 | &.nav-parent { 254 | position: static; 255 | } 256 | 257 | &.level-open { 258 | & > .nav-wrapper { 259 | visibility: visible; 260 | transform: translate3d(0, 0, 0); 261 | transition: transform $hc-offcanvas-nav-transition-duration $hc-offcanvas-nav-transition-timing-function; 262 | } 263 | } 264 | } 265 | } 266 | } 267 | 268 | // Left 269 | &.nav-position-left { 270 | left: 0; 271 | 272 | .nav-container { 273 | left: 0; 274 | } 275 | 276 | &.nav-levels-overlap { 277 | 278 | li { 279 | .nav-wrapper { 280 | left: 0; 281 | transform: translate3d(-100%, 0, 0); 282 | } 283 | } 284 | } 285 | } 286 | 287 | // Right 288 | &.nav-position-right { 289 | right: 0; 290 | 291 | .nav-container { 292 | right: 0; 293 | } 294 | 295 | &.nav-levels-overlap { 296 | 297 | li { 298 | .nav-wrapper { 299 | right: 0; 300 | transform: translate3d(100%, 0, 0); 301 | } 302 | } 303 | } 304 | } 305 | 306 | // Top 307 | &.nav-position-top { 308 | top: 0; 309 | 310 | .nav-container { 311 | top: 0; 312 | width: 100%; 313 | } 314 | 315 | &.nav-levels-overlap { 316 | 317 | li { 318 | .nav-wrapper { 319 | left: 0; 320 | transform: translate3d(0, -100%, 0); 321 | } 322 | } 323 | } 324 | } 325 | 326 | // Bottom 327 | &.nav-position-bottom { 328 | top: auto; 329 | bottom: 0; 330 | 331 | .nav-container { 332 | top: auto; 333 | bottom: 0; 334 | width: 100%; 335 | } 336 | 337 | &.nav-levels-overlap { 338 | 339 | li { 340 | .nav-wrapper { 341 | left: 0; 342 | transform: translate3d(0, 100%, 0); 343 | } 344 | } 345 | } 346 | } 347 | 348 | // Open Nav 349 | &.nav-open[class*='hc-nav-'] { 350 | div.nav-container { 351 | transform: translate3d(0, 0, 0); 352 | } 353 | } 354 | 355 | // RTL 356 | &.rtl { 357 | text-align: right; 358 | direction: rtl; 359 | } 360 | } -------------------------------------------------------------------------------- /src/scss/_theme-carbon.scss: -------------------------------------------------------------------------------- 1 | $hc-offcanvas-nav-background-color: #202225 !default; 2 | $hc-offcanvas-nav-text-color: #fff !default; 3 | $hc-offcanvas-nav-text-size: 15px !default; 4 | 5 | .hc-offcanvas-nav { 6 | font-family: sans-serif; 7 | 8 | .nav-container, 9 | .nav-wrapper, 10 | ul { 11 | background: $hc-offcanvas-nav-background-color; 12 | } 13 | 14 | &, 15 | .nav-wrapper { 16 | &::after { 17 | background: rgba(0, 0, 0, .3); 18 | } 19 | } 20 | 21 | .nav-content { 22 | padding: 0 15px; 23 | 24 | & > { 25 | h2, h3, h4, h5, h6 { 26 | font-size: round($hc-offcanvas-nav-text-size * 1.26); 27 | font-weight: normal; 28 | padding: 25px 15px 30px; 29 | color: $hc-offcanvas-nav-text-color; 30 | 31 | &:first-child { 32 | margin-top: 10px; 33 | } 34 | 35 | &:not(.nav-title):not(.level-title) { 36 | font-size: $hc-offcanvas-nav-text-size + 1; 37 | padding: 15px 12px; 38 | text-transform: uppercase; 39 | color: darken($hc-offcanvas-nav-text-color, 30%); 40 | } 41 | } 42 | } 43 | } 44 | 45 | .nav-item-link, 46 | li.nav-close a, 47 | .nav-back a { 48 | padding: 12px; 49 | font-size: $hc-offcanvas-nav-text-size; 50 | color: $hc-offcanvas-nav-text-color; 51 | z-index: 1; 52 | background: rgba(0, 0, 0, 0); 53 | border-radius: 5px; 54 | transition: .05s background ease; 55 | 56 | &:focus, 57 | &:focus-within { 58 | z-index: 10; 59 | } 60 | 61 | &[disabled] { 62 | color: rgba($hc-offcanvas-nav-text-color, .5); 63 | } 64 | } 65 | 66 | &:not(.touch-device) { 67 | li:not(.nav-item-custom) { 68 | a:not([disabled]) { 69 | &:hover { 70 | background: lighten($hc-offcanvas-nav-background-color, 3%); 71 | } 72 | } 73 | } 74 | } 75 | 76 | .nav-custom-content { 77 | padding: 12px 15px; 78 | font-size: $hc-offcanvas-nav-text-size; 79 | } 80 | 81 | .nav-highlight { 82 | & > .nav-item-wrapper .nav-item-link { 83 | border-radius: 5px; 84 | background: lighten($hc-offcanvas-nav-background-color, 4%); 85 | } 86 | } 87 | 88 | .nav-wrapper-0 { 89 | & > .nav-content > { 90 | ul { 91 | 92 | &:first-child { 93 | margin-top: 15px; 94 | } 95 | 96 | &:not(:last-child) { 97 | margin-bottom: 18px; 98 | } 99 | } 100 | } 101 | } 102 | 103 | li { 104 | color: $hc-offcanvas-nav-text-color; 105 | 106 | &.nav-close, 107 | &.nav-back { 108 | a { 109 | &:hover { 110 | background: darken($hc-offcanvas-nav-background-color, 6.5%); 111 | } 112 | } 113 | 114 | &:not(:first-child) { 115 | a { 116 | margin-top: -1px; 117 | } 118 | } 119 | } 120 | 121 | &.nav-parent { 122 | .nav-item-link { 123 | 124 | &:last-child { 125 | padding-right: 62px; 126 | } 127 | 128 | &:not(:last-child) { 129 | margin-right: 52px; 130 | } 131 | } 132 | } 133 | } 134 | 135 | .nav-close-button span, 136 | .nav-parent .nav-next, 137 | .nav-back span { 138 | width: 40px; 139 | position: absolute; 140 | top: 0; 141 | right: 0; 142 | bottom: 0; 143 | text-align: center; 144 | cursor: pointer; 145 | border-radius: 5px; 146 | transition: background .2s ease; 147 | } 148 | 149 | .nav-close-button { 150 | position: relative; 151 | display: block; 152 | 153 | span { 154 | &::before, 155 | &::after { 156 | content: ''; 157 | position: absolute; 158 | top: 50%; 159 | left: 50%; 160 | width: 6px; 161 | height: 6px; 162 | margin-top: -3px; 163 | border-top: 2px solid $hc-offcanvas-nav-text-color; 164 | border-left: 2px solid $hc-offcanvas-nav-text-color; 165 | } 166 | 167 | &::before { 168 | margin-left: -9px; 169 | transform: rotate(135deg); 170 | } 171 | 172 | &::after { 173 | transform: rotate(-45deg); 174 | } 175 | } 176 | } 177 | 178 | .nav-content > .nav-close { 179 | 180 | a { 181 | height: 44px; 182 | font-size: $hc-offcanvas-nav-text-size; 183 | color: $hc-offcanvas-nav-text-color; 184 | background: rgba(0, 0, 0, 0); 185 | border-radius: 5px; 186 | z-index: 1; 187 | text-decoration: none; 188 | box-sizing: border-box; 189 | 190 | &.has-label { 191 | padding: 12px 15px; 192 | } 193 | 194 | &:hover { 195 | background: lighten($hc-offcanvas-nav-background-color, 2%); 196 | } 197 | } 198 | 199 | &:first-child { 200 | position: relative; 201 | min-height: 40px; 202 | margin-top: 15px; 203 | 204 | & + ul { 205 | margin-top: 15px; 206 | } 207 | 208 | a { 209 | 210 | &.has-label { 211 | margin-bottom: -15px; 212 | } 213 | 214 | &:not(.has-label) { 215 | position: absolute; 216 | width: 40px; 217 | height: 40px; 218 | line-height: 40px; 219 | top: 0; 220 | right: 0; 221 | 222 | & + ul { 223 | margin-top: 60px; 224 | } 225 | 226 | & + { 227 | h2, h3, h4, h5, h6 { 228 | margin-top: 55px; 229 | } 230 | } 231 | } 232 | } 233 | } 234 | } 235 | 236 | .nav-title { 237 | & + .nav-close { 238 | a:not(.has-label) { 239 | position: absolute; 240 | width: 40px; 241 | height: 40px; 242 | line-height: 40px; 243 | top: 28px; 244 | right: 15px; 245 | } 246 | } 247 | } 248 | 249 | &.nav-close-button-empty { 250 | .nav-title { 251 | padding-right: 46px; 252 | } 253 | } 254 | 255 | li.nav-close { 256 | 257 | &:first-child { 258 | padding-bottom: 15px; 259 | } 260 | 261 | .nav-close-button { 262 | 263 | &.has-label { 264 | margin-bottom: -15px; 265 | } 266 | 267 | &:not(.has-label) { 268 | width: 40px; 269 | height: 40px; 270 | line-height: 40px; 271 | float: right; 272 | } 273 | } 274 | 275 | .nav-item-wrapper { 276 | &::after { 277 | content: ''; 278 | display: table; 279 | clear: both; 280 | } 281 | } 282 | } 283 | 284 | a.nav-next { 285 | position: relative; 286 | 287 | &:before { 288 | content: ''; 289 | position: absolute; 290 | width: 2px; 291 | height: 25px; 292 | left: -7px; 293 | top: 9px; 294 | background: darken($hc-offcanvas-nav-text-color, 70%); 295 | border-radius: 2px; 296 | } 297 | } 298 | 299 | .nav-next, 300 | .nav-back { 301 | span { 302 | &::before { 303 | content: ''; 304 | position: absolute; 305 | top: 50%; 306 | left: 50%; 307 | width: 8px; 308 | height: 8px; 309 | margin-left: -2px; 310 | box-sizing: border-box; 311 | border-top: 2px solid $hc-offcanvas-nav-text-color; 312 | border-left: 2px solid $hc-offcanvas-nav-text-color; 313 | transform-origin: center; 314 | } 315 | } 316 | } 317 | 318 | .nav-next { 319 | span { 320 | position: absolute; 321 | top: 0; 322 | right: 0; 323 | left: 0; 324 | bottom: 0; 325 | 326 | &::before { 327 | transform: translate(-50%, -50%) rotate(135deg); 328 | } 329 | } 330 | } 331 | 332 | .nav-back { 333 | span { 334 | &::before { 335 | margin-left: 2px; 336 | transform: translate(-50%, -50%) rotate(-45deg); 337 | } 338 | } 339 | } 340 | 341 | /* Left */ 342 | 343 | &.nav-position-left { 344 | 345 | &.nav-open.nav-levels-overlap { 346 | .nav-wrapper { 347 | box-shadow: 1px 0 2px rgba(0, 0, 0, .2); 348 | } 349 | } 350 | } 351 | 352 | /* Right */ 353 | 354 | &.nav-position-right { 355 | 356 | &.nav-open.nav-levels-overlap { 357 | .nav-wrapper { 358 | box-shadow: -1px 0 2px rgba(0, 0, 0, .2); 359 | } 360 | } 361 | 362 | .nav-next { 363 | span { 364 | &::before { 365 | margin-left: 2px; 366 | transform: translate(-50%, -50%) rotate(-45deg); 367 | } 368 | } 369 | } 370 | 371 | .nav-back { 372 | span { 373 | &::before { 374 | margin-left: -2px; 375 | transform: translate(-50%, -50%) rotate(135deg); 376 | } 377 | } 378 | } 379 | } 380 | 381 | /* Top */ 382 | 383 | &.nav-position-top { 384 | 385 | &.nav-open { 386 | .nav-wrapper { 387 | box-shadow: 0 1px 2px rgba(0, 0, 0, .2); 388 | } 389 | } 390 | 391 | .nav-next { 392 | span { 393 | &::before { 394 | margin-left: 0; 395 | margin-right: -2px; 396 | transform: translate(-50%, -50%) rotate(-135deg); 397 | } 398 | } 399 | } 400 | 401 | .nav-back { 402 | span { 403 | &::before { 404 | margin-left: 0; 405 | margin-right: -2px; 406 | transform: translate(-50%, -50%) rotate(45deg); 407 | } 408 | } 409 | } 410 | } 411 | 412 | /* Bottom */ 413 | 414 | &.nav-position-bottom { 415 | 416 | &.nav-open { 417 | .nav-wrapper { 418 | box-shadow: 0 -1px 2px rgba(0, 0, 0, .2); 419 | } 420 | } 421 | 422 | .nav-next { 423 | span { 424 | &::before { 425 | margin-left: 0; 426 | margin-right: -2px; 427 | transform: translate(-50%, -50%) rotate(45deg); 428 | } 429 | } 430 | } 431 | 432 | .nav-back { 433 | span { 434 | &::before { 435 | margin-left: 0; 436 | margin-right: -2px; 437 | transform: translate(-50%, -50%) rotate(-135deg); 438 | } 439 | } 440 | } 441 | } 442 | 443 | /* Overlap */ 444 | 445 | &.nav-levels-overlap { 446 | 447 | ul ul:first-child { 448 | margin-top: 15px; 449 | } 450 | } 451 | 452 | /* Expand & none */ 453 | 454 | &.nav-levels-expand, 455 | &.nav-levels-none { 456 | 457 | .nav-content .nav-content { 458 | padding: 0; 459 | } 460 | 461 | .nav-wrapper .nav-wrapper { 462 | width: auto; 463 | position: relative; 464 | margin-left: 20px; 465 | } 466 | 467 | li { 468 | 469 | &.level-open { 470 | 471 | & > .nav-item-wrapper > { 472 | .nav-next, 473 | a > .nav-next { 474 | span { 475 | &::before { 476 | margin-top: -2px; 477 | transform: translate(-50%, -50%) rotate(-135deg); 478 | } 479 | } 480 | } 481 | } 482 | } 483 | } 484 | } 485 | 486 | &.nav-levels-expand li.level-open > .nav-wrapper, 487 | &.nav-levels-none li .nav-wrapper { 488 | &::before { 489 | content: ''; 490 | position: absolute; 491 | width: 2px; 492 | left: -7px; 493 | top: 5px; 494 | bottom: 5px; 495 | background: darken($hc-offcanvas-nav-text-color, 70%); 496 | border-radius: 2px; 497 | } 498 | } 499 | 500 | /* RTL */ 501 | 502 | &.rtl { 503 | 504 | .nav-wrapper .nav-wrapper { 505 | margin-left: 0; 506 | margin-right: 20px; 507 | } 508 | 509 | a.nav-next { 510 | &:before { 511 | left: auto; 512 | right: -7px; 513 | } 514 | } 515 | 516 | .nav-title + .nav-close a:not(.has-label) { 517 | left: 15px; 518 | right: auto; 519 | } 520 | 521 | .nav-close-button span, 522 | .nav-next, 523 | .nav-back span { 524 | left: 0; 525 | right: auto; 526 | } 527 | 528 | li { 529 | 530 | &.nav-parent { 531 | .nav-item-link { 532 | 533 | &:last-child { 534 | padding-left: 62px; 535 | padding-right: 12px; 536 | } 537 | 538 | &:not(:last-child) { 539 | margin-left: 52px; 540 | margin-right: 0; 541 | } 542 | } 543 | } 544 | } 545 | 546 | &.nav-levels-expand li.level-open > .nav-wrapper, 547 | &.nav-levels-none li .nav-wrapper { 548 | &::before { 549 | left: auto; 550 | right: -7px; 551 | } 552 | } 553 | } 554 | } -------------------------------------------------------------------------------- /src/scss/_theme-default.scss: -------------------------------------------------------------------------------- 1 | $hc-offcanvas-nav-background-color: #336ca6 !default; 2 | $hc-offcanvas-nav-text-color: #fff !default; 3 | $hc-offcanvas-nav-text-size: 14px !default; 4 | 5 | .hc-offcanvas-nav { 6 | font-family: sans-serif; 7 | 8 | &, 9 | .nav-wrapper { 10 | &::after { 11 | background: rgba(0, 0, 0, .3); 12 | } 13 | } 14 | 15 | .nav-container, 16 | .nav-wrapper, 17 | ul { 18 | background: $hc-offcanvas-nav-background-color; 19 | } 20 | 21 | .nav-content > { 22 | h2, h3, h4, h5, h6 { 23 | font-size: round($hc-offcanvas-nav-text-size * 1.35); 24 | font-weight: normal; 25 | padding: 20px 17px; 26 | color: darken($hc-offcanvas-nav-background-color, 20%); 27 | 28 | &:not(.nav-title):not(.level-title) { 29 | font-size: round($hc-offcanvas-nav-text-size * 1.14); 30 | padding: 15px 17px; 31 | background: $hc-offcanvas-nav-background-color; 32 | } 33 | } 34 | } 35 | 36 | .nav-item-link, 37 | li.nav-close a, 38 | .nav-back a { 39 | padding: 14px 17px; 40 | font-size: $hc-offcanvas-nav-text-size; 41 | color: $hc-offcanvas-nav-text-color; 42 | z-index: 1; 43 | background: rgba(0, 0, 0, 0); 44 | border-bottom: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 45 | transition: background .1s ease; 46 | 47 | &:focus, 48 | &:focus-within { 49 | z-index: 10; 50 | } 51 | 52 | &[disabled] { 53 | color: rgba($hc-offcanvas-nav-text-color, .5); 54 | } 55 | } 56 | 57 | div.nav-back { 58 | & + ul > li:first-child > .nav-item-wrapper > .nav-item-link { 59 | border-top: none !important; 60 | } 61 | } 62 | 63 | &:not(.touch-device) { 64 | li:not(.nav-item-custom) { 65 | a:not([disabled]) { 66 | &:hover { 67 | background: darken($hc-offcanvas-nav-background-color, 2%); 68 | } 69 | } 70 | } 71 | } 72 | 73 | .nav-custom-content { 74 | padding: 14px 17px; 75 | font-size: $hc-offcanvas-nav-text-size; 76 | border-bottom: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 77 | } 78 | 79 | .nav-highlight { 80 | background: darken($hc-offcanvas-nav-background-color, 4%); 81 | } 82 | 83 | .nav-wrapper { 84 | & > .nav-content > { 85 | 86 | ul { 87 | 88 | &:first-of-type { 89 | & > li { 90 | &:first-child:not(.nav-back):not(.nav-close) { 91 | & > .nav-item-wrapper { 92 | & > .nav-item-link { 93 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 94 | 95 | & + a { 96 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | &:not(:last-child) { 105 | border-bottom: 2px solid darken($hc-offcanvas-nav-background-color, 6%); 106 | } 107 | 108 | & + { 109 | h2, h3, h4, h5, h6 { 110 | margin-top: -2px; 111 | } 112 | } 113 | } 114 | 115 | h2, h3, h4, h5, h6 { 116 | & + ul { 117 | & > li { 118 | &:first-child:not(.nav-back):not(.nav-close) { 119 | & > .nav-item-wrapper { 120 | & > .nav-item-link { 121 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 122 | } 123 | } 124 | } 125 | } 126 | } 127 | } 128 | 129 | .nav-title, 130 | .level-title, 131 | .nav-close { 132 | & + { 133 | h2, h3, h4, h5, h6 { 134 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 135 | } 136 | } 137 | } 138 | } 139 | } 140 | 141 | li { 142 | color: $hc-offcanvas-nav-text-color; 143 | 144 | &.nav-parent { 145 | .nav-item-link { 146 | 147 | &:last-child { 148 | padding-right: 58px; 149 | } 150 | 151 | &:not(:last-child) { 152 | margin-right: 45px; 153 | } 154 | } 155 | } 156 | } 157 | 158 | .nav-close-button span, 159 | .nav-parent .nav-next, 160 | .nav-back span { 161 | width: 45px; 162 | position: absolute; 163 | top: 0; 164 | right: 0; 165 | bottom: 0; 166 | text-align: center; 167 | cursor: pointer; 168 | transition: background .1s ease; 169 | } 170 | 171 | .nav-close-button { 172 | position: relative; 173 | display: block; 174 | 175 | span { 176 | &::before, 177 | &::after { 178 | content: ''; 179 | position: absolute; 180 | top: 50%; 181 | left: 50%; 182 | width: 6px; 183 | height: 6px; 184 | margin-top: -3px; 185 | border-top: 2px solid $hc-offcanvas-nav-text-color; 186 | border-left: 2px solid $hc-offcanvas-nav-text-color; 187 | } 188 | 189 | &::before { 190 | margin-left: -9px; 191 | transform: rotate(135deg); 192 | } 193 | 194 | &::after { 195 | transform: rotate(-45deg); 196 | } 197 | } 198 | } 199 | 200 | .nav-content > .nav-close { 201 | position: relative; 202 | z-index: 2; 203 | 204 | a { 205 | font-size: $hc-offcanvas-nav-text-size; 206 | color: $hc-offcanvas-nav-text-color; 207 | background: rgba(0, 0, 0, 0); 208 | z-index: 1; 209 | text-decoration: none; 210 | box-sizing: border-box; 211 | 212 | &:not(.has-label) { 213 | height: 50px; 214 | } 215 | 216 | &.has-label { 217 | padding: 14px 17px; 218 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 219 | } 220 | 221 | &:hover { 222 | border: none; 223 | background: radial-gradient( 224 | farthest-corner at top right, 225 | rgba(0, 0, 0, .1), 226 | rgba(0, 0, 0, 0) 227 | ); 228 | } 229 | } 230 | 231 | &.has-label + ul { 232 | margin-top: -1px; 233 | } 234 | } 235 | 236 | &:not(.nav-close-button-empty) { 237 | .nav-content > .nav-close { 238 | margin-bottom: -1px; 239 | } 240 | } 241 | 242 | .nav-title { 243 | & + .nav-close { 244 | a:not(.has-label) { 245 | position: absolute; 246 | width: 45px; 247 | height: 66px; 248 | line-height: 66px; 249 | top: -66px; 250 | right: 0; 251 | } 252 | } 253 | } 254 | 255 | &.nav-close-button-empty { 256 | .nav-title { 257 | padding-right: 55px; 258 | } 259 | } 260 | 261 | li.nav-close { 262 | a:not(.has-label) { 263 | height: 49px; 264 | } 265 | } 266 | 267 | .nav-content > .nav-close:first-child a, 268 | .nav-title + .nav-close a.has-label, 269 | li.nav-close a, 270 | .nav-back a { 271 | background: darken($hc-offcanvas-nav-background-color, 3%); 272 | border-top: 1px solid darken($hc-offcanvas-nav-background-color, 7%); 273 | border-bottom: 1px solid darken($hc-offcanvas-nav-background-color, 7%); 274 | 275 | &:hover { 276 | background: darken($hc-offcanvas-nav-background-color, 4.3%); 277 | } 278 | } 279 | 280 | li.nav-close, 281 | li.nav-back { 282 | &:not(:first-child) { 283 | a { 284 | margin-top: -1px; 285 | } 286 | } 287 | } 288 | 289 | a.nav-next { 290 | border-left: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 291 | border-bottom: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 292 | } 293 | 294 | .nav-next, 295 | .nav-back { 296 | span { 297 | &::before { 298 | content: ''; 299 | position: absolute; 300 | top: 50%; 301 | left: 50%; 302 | width: 8px; 303 | height: 8px; 304 | margin-left: -2px; 305 | box-sizing: border-box; 306 | border-top: 2px solid $hc-offcanvas-nav-text-color; 307 | border-left: 2px solid $hc-offcanvas-nav-text-color; 308 | transform-origin: center; 309 | } 310 | } 311 | } 312 | 313 | .nav-next { 314 | span { 315 | position: absolute; 316 | top: 0; 317 | right: 0; 318 | left: 0; 319 | bottom: 0; 320 | 321 | &::before { 322 | transform: translate(-50%, -50%) rotate(135deg); 323 | } 324 | } 325 | } 326 | 327 | .nav-back { 328 | span { 329 | &::before { 330 | margin-left: 2px; 331 | transform: translate(-50%, -50%) rotate(-45deg); 332 | } 333 | } 334 | } 335 | 336 | /* Left */ 337 | 338 | &.nav-position-left { 339 | 340 | &.nav-open.nav-levels-overlap { 341 | .nav-wrapper { 342 | box-shadow: 1px 0 2px rgba(0, 0, 0, .2); 343 | } 344 | } 345 | } 346 | 347 | /* Right */ 348 | 349 | &.nav-position-right { 350 | 351 | &.nav-open.nav-levels-overlap { 352 | .nav-wrapper { 353 | box-shadow: -1px 0 2px rgba(0, 0, 0, .2); 354 | } 355 | } 356 | 357 | .nav-next { 358 | span { 359 | &::before { 360 | margin-left: 2px; 361 | transform: translate(-50%, -50%) rotate(-45deg); 362 | } 363 | } 364 | } 365 | 366 | .nav-back { 367 | span { 368 | &::before { 369 | margin-left: -2px; 370 | transform: translate(-50%, -50%) rotate(135deg); 371 | } 372 | } 373 | } 374 | } 375 | 376 | /* Top */ 377 | 378 | &.nav-position-top { 379 | 380 | &.nav-open { 381 | .nav-wrapper { 382 | box-shadow: 0 1px 2px rgba(0, 0, 0, .2); 383 | } 384 | } 385 | 386 | .nav-next { 387 | span { 388 | &::before { 389 | margin-left: 0; 390 | margin-right: -2px; 391 | transform: translate(-50%, -50%) rotate(-135deg); 392 | } 393 | } 394 | } 395 | 396 | .nav-back { 397 | span { 398 | &::before { 399 | margin-left: 0; 400 | margin-right: -2px; 401 | transform: translate(-50%, -50%) rotate(45deg); 402 | } 403 | } 404 | } 405 | } 406 | 407 | /* Bottom */ 408 | 409 | &.nav-position-bottom { 410 | 411 | &.nav-open { 412 | .nav-wrapper { 413 | box-shadow: 0 -1px 2px rgba(0, 0, 0, .2); 414 | } 415 | } 416 | 417 | .nav-next { 418 | span { 419 | &::before { 420 | margin-left: 0; 421 | margin-right: -2px; 422 | transform: translate(-50%, -50%) rotate(45deg); 423 | } 424 | } 425 | } 426 | 427 | .nav-back { 428 | span { 429 | &::before { 430 | margin-left: 0; 431 | margin-right: -2px; 432 | transform: translate(-50%, -50%) rotate(-135deg); 433 | } 434 | } 435 | } 436 | } 437 | 438 | /* Expand & none */ 439 | 440 | &.nav-levels-expand, 441 | &.nav-levels-none { 442 | 443 | ul { 444 | .nav-wrapper { 445 | box-shadow: none; 446 | background: transparent; 447 | } 448 | } 449 | 450 | li { 451 | 452 | &.level-open { 453 | background: darken($hc-offcanvas-nav-background-color, 4%); 454 | 455 | & > .nav-item-wrapper > { 456 | 457 | a { 458 | border-bottom: 1px solid darken($hc-offcanvas-nav-background-color, 8%); 459 | 460 | &:hover { 461 | background: darken($hc-offcanvas-nav-background-color, 3%); 462 | } 463 | } 464 | 465 | .nav-next, 466 | a > .nav-next { 467 | span { 468 | &::before { 469 | margin-top: -2px; 470 | transform: translate(-50%, -50%) rotate(-135deg); 471 | } 472 | } 473 | } 474 | } 475 | } 476 | } 477 | 478 | @for $i from 1 through 5 { 479 | .nav-wrapper-#{$i} .nav-item-link { 480 | padding-left: calc(17px + 20px * #{$i}); 481 | } 482 | } 483 | } 484 | 485 | /* RTL */ 486 | 487 | &.rtl { 488 | 489 | a.nav-next { 490 | border-left: none; 491 | border-right: 1px solid darken($hc-offcanvas-nav-background-color, 6%); 492 | } 493 | 494 | .nav-title + .nav-close a:not(.has-label), 495 | .nav-close-button span, 496 | .nav-next, 497 | .nav-back span { 498 | left: 0; 499 | right: auto; 500 | } 501 | 502 | li { 503 | &.nav-parent { 504 | .nav-item-link { 505 | 506 | &:last-child { 507 | padding-left: 58px; 508 | padding-right: 17px; 509 | } 510 | 511 | &:not(:last-child) { 512 | margin-left: 45px; 513 | margin-right: 0; 514 | } 515 | } 516 | } 517 | } 518 | 519 | @for $i from 1 through 5 { 520 | .nav-wrapper-#{$i} li.nav-item .nav-item-link { 521 | padding-right: calc(17px + 20px * #{$i}); 522 | } 523 | } 524 | } 525 | } -------------------------------------------------------------------------------- /docs/demo.scss: -------------------------------------------------------------------------------- 1 | $background: #243949; 2 | $white: #fffce1; 3 | $yellow: #dab977; 4 | 5 | @import '../src/scss/mixins'; 6 | @import '../src/scss/core'; 7 | 8 | body.theme-default { 9 | @import '../src/scss/theme-default'; 10 | } 11 | 12 | body.theme-carbon { 13 | @import '../src/scss/theme-carbon'; 14 | } 15 | 16 | @mixin mi { 17 | font-family: 'Material Icons'; 18 | font-weight: normal; 19 | font-style: normal; 20 | display: inline-block; 21 | line-height: 1; 22 | text-transform: none; 23 | text-indent: 0; 24 | letter-spacing: normal; 25 | word-wrap: normal; 26 | white-space: nowrap; 27 | direction: ltr; 28 | -webkit-font-smoothing: antialiased; 29 | text-rendering: optimizeLegibility; 30 | -moz-osx-font-smoothing: grayscale; 31 | font-feature-settings: 'liga'; 32 | display: inline-block; 33 | width: 19px; 34 | height: 19px; 35 | margin-right: 15px; 36 | font-size: 23px; 37 | vertical-align: top; 38 | speak: never; 39 | } 40 | 41 | html, body, div, span, header, ul, li, a { 42 | margin: 0; 43 | padding: 0; 44 | border: 0; 45 | font-size: 100%; 46 | font: inherit; 47 | vertical-align: baseline; 48 | } 49 | 50 | html { 51 | height: 100%; 52 | } 53 | 54 | h1, h2, h3, h4, h5, h6 { 55 | margin: 0; 56 | } 57 | 58 | em { 59 | font-style: italic; 60 | } 61 | 62 | strong { 63 | font-weight: 600; 64 | } 65 | 66 | ol, ul { 67 | list-style: none; 68 | } 69 | 70 | .cf { 71 | &::before, 72 | &::after { 73 | content: ''; 74 | display: block; 75 | height: 0; 76 | overflow: hidden; 77 | } 78 | 79 | &::after { 80 | clear: both; 81 | } 82 | } 83 | 84 | #container { 85 | display: flex; 86 | flex-direction: column; 87 | min-height: 100vh; 88 | height: 100%; 89 | background: linear-gradient(-134deg, #517FA4 0%, $background 100%); 90 | font-family: 'Raleway', sans-serif; 91 | text-align: center; 92 | color: $white; 93 | } 94 | 95 | .wrapper { 96 | max-width: 800px; 97 | margin: 0 auto; 98 | padding: 0 20px; 99 | } 100 | 101 | #main-nav { 102 | display: none; 103 | } 104 | 105 | header { 106 | position: relative; 107 | padding: 50px 0 20px; 108 | 109 | h1 { 110 | font-size: 50px; 111 | font-weight: 700; 112 | text-align: center; 113 | letter-spacing: 5px; 114 | padding-bottom: 8px; 115 | } 116 | 117 | h2 { 118 | max-width: 680px; 119 | margin: auto; 120 | font-size: 20px; 121 | font-weight: 200; 122 | line-height: 1.4; 123 | text-align: center; 124 | letter-spacing: 1px; 125 | padding-bottom: 30px; 126 | } 127 | 128 | .git { 129 | display: inline-block; 130 | text-decoration: none; 131 | color: #fff; 132 | border-radius: 4px; 133 | padding: 4px 10px 4px 0; 134 | font-size: 15px; 135 | font-weight: 400; 136 | color: $white; 137 | background: #54b9cb; 138 | transition: background .15s ease-in-out; 139 | 140 | &:hover { 141 | background: #4CA8B9; 142 | 143 | svg { 144 | border-color: #54b9cb; 145 | } 146 | } 147 | 148 | svg { 149 | width: 15px; 150 | height: 15px; 151 | fill: $white; 152 | position: relative; 153 | top: 2px; 154 | padding: 0 10px; 155 | margin-right: 10px; 156 | border-right: 1px solid #4daabb; 157 | transition: border-color .15s ease-in-out; 158 | } 159 | } 160 | 161 | .ver { 162 | padding-top: 15px; 163 | font-weight: 200; 164 | color: $yellow; 165 | 166 | span { 167 | color: $white; 168 | } 169 | } 170 | 171 | .toggle { 172 | @include hc-hamburger('default', 35px, 26px, 4px, darken($background, 7%), .25s); 173 | position: relative; 174 | width: auto; 175 | top: auto; 176 | left: auto; 177 | float: left; 178 | display: block; 179 | cursor: pointer; 180 | box-sizing: content-box; 181 | font-size: 18px; 182 | padding-left: 55px; 183 | line-height: 22px; 184 | margin-top: 55px; 185 | color: #fff; 186 | text-align: left; 187 | text-decoration: none; 188 | 189 | &:hover { 190 | span { 191 | &, 192 | &::before, 193 | &::after { 194 | background: $yellow; 195 | } 196 | } 197 | } 198 | 199 | i { 200 | font-size: 10px; 201 | display: block; 202 | line-height: 10px; 203 | opacity: .7; 204 | } 205 | } 206 | } 207 | 208 | footer { 209 | padding-bottom: 40px; 210 | 211 | .swm { 212 | display: inline-block; 213 | padding: 0 15px; 214 | 215 | svg { 216 | display: block; 217 | width: auto; 218 | height: 17px; 219 | margin-top: 22px; 220 | 221 | path { 222 | transition: fill .1s ease; 223 | } 224 | 225 | .l-1 { 226 | fill: #4fb5e1; 227 | } 228 | .l-2 { 229 | fill: #f2c053; 230 | } 231 | .l-3 { 232 | fill: #a7ce38; 233 | } 234 | } 235 | 236 | &:not(:hover) { 237 | svg { 238 | .l-1 { 239 | fill: lighten($background, 20%); 240 | } 241 | .l-2 { 242 | fill: lighten($background, 50%); 243 | } 244 | .l-3 { 245 | fill: lighten($background, 30%); 246 | } 247 | } 248 | } 249 | } 250 | } 251 | 252 | main { 253 | flex: 1 0 auto; 254 | padding-bottom: 30px; 255 | text-align: left; 256 | 257 | .content { 258 | border-top: 1px solid rgba(255, 255, 255, .1); 259 | } 260 | 261 | h4 { 262 | font-size: 15px; 263 | letter-spacing: 1px; 264 | font-weight: 600; 265 | text-transform: uppercase; 266 | margin: 20px 0; 267 | 268 | &:first-child { 269 | margin-top: 30px; 270 | } 271 | } 272 | 273 | .actions { 274 | margin: 0 -15px; 275 | text-align: center; 276 | 277 | div { 278 | padding: 0 15px 20px; 279 | box-sizing: border-box; 280 | } 281 | 282 | @media screen and (min-width: 800px) { 283 | 284 | &:not(.theme) { 285 | display: flex; 286 | flex-wrap: wrap; 287 | 288 | div { 289 | float: left; 290 | flex: 1 1 33.33%; 291 | max-width: 33.33%; 292 | } 293 | 294 | &.position { 295 | div { 296 | float: left; 297 | flex: 1 1 25%; 298 | max-width: 25%; 299 | } 300 | } 301 | } 302 | 303 | &.theme { 304 | 305 | &::after { 306 | content: ''; 307 | display: table; 308 | clear: both; 309 | } 310 | 311 | div { 312 | float: left; 313 | } 314 | } 315 | } 316 | 317 | &.checkboxes { 318 | text-align: left; 319 | padding-top: 8px; 320 | 321 | label { 322 | font-size: 14px; 323 | text-transform: uppercase; 324 | cursor: pointer; 325 | 326 | input { 327 | display: none; 328 | 329 | &:checked { 330 | 331 | & ~ span { 332 | background: $yellow; 333 | 334 | &::before { 335 | content: ''; 336 | position: absolute; 337 | top: 50%; 338 | left: 50%; 339 | margin-top: -1px; 340 | border: solid $background; 341 | border-width: 0 3px 3px 0; 342 | display: inline-block; 343 | padding: 5px 2px; 344 | transform: translate(-50%, -50%) rotate(45deg); 345 | } 346 | } 347 | } 348 | } 349 | 350 | span { 351 | display: inline-block; 352 | position: relative; 353 | top: -1px; 354 | width: 22px; 355 | height: 22px; 356 | background: $white; 357 | margin-right: 12px; 358 | vertical-align: top; 359 | transition: all .1s ease; 360 | } 361 | } 362 | } 363 | } 364 | 365 | .button { 366 | position: relative; 367 | display: block; 368 | padding: 18px 30px 16px; 369 | text-transform: uppercase; 370 | text-align: center; 371 | font-size: 16px; 372 | font-weight: 700; 373 | line-height: 1.4; 374 | letter-spacing: 1px; 375 | text-decoration: none; 376 | color: $background; 377 | cursor: pointer; 378 | background: $white; 379 | border-radius: 30px/80px; 380 | transition: all .1s ease; 381 | 382 | &:not(.active):hover { 383 | color: darken($yellow, 5%); 384 | } 385 | 386 | &.active { 387 | background: $yellow; 388 | } 389 | } 390 | 391 | .thumb { 392 | position: relative; 393 | display: block; 394 | width: 100px; 395 | height: 100px; 396 | border: 4px solid $white; 397 | border-radius: 5px; 398 | background-size: cover; 399 | 400 | &.active { 401 | border-color: $yellow; 402 | } 403 | } 404 | } 405 | 406 | .hc-offcanvas-nav { 407 | 408 | .nav-wrapper-0 > .nav-content { 409 | padding-bottom: 41px; 410 | } 411 | 412 | h2 { 413 | & ~ ul > li.search { 414 | .nav-custom-content { 415 | padding-top: 0; 416 | } 417 | } 418 | } 419 | 420 | &.rtl { 421 | 422 | .nav-item-link { 423 | &::before { 424 | margin-left: 15px; 425 | margin-right: 0 !important; 426 | } 427 | } 428 | 429 | .nav-item.collections > .nav-item-wrapper .nav-item-link span { 430 | float: left; 431 | } 432 | } 433 | 434 | li { 435 | 436 | .custom-message { 437 | font-size: 12px; 438 | 439 | a { 440 | color: #fff; 441 | font-size: 13px; 442 | 443 | &:hover { 444 | text-decoration: none; 445 | } 446 | } 447 | } 448 | 449 | &.add > .nav-item-wrapper a::before { 450 | @include mi; 451 | content: 'add'; 452 | } 453 | 454 | &.new > .nav-item-wrapper .nav-item-link::before { 455 | @include mi; 456 | content: 'fiber_new'; 457 | } 458 | 459 | &.cryptocurrency > .nav-item-wrapper .nav-item-link::before { 460 | @include mi; 461 | content: 'local_atm'; 462 | } 463 | 464 | &.devices > .nav-item-wrapper .nav-item-link::before { 465 | @include mi; 466 | content: 'devices'; 467 | } 468 | 469 | &.mobile > .nav-item-wrapper .nav-item-link::before { 470 | @include mi; 471 | content: 'phone_android'; 472 | } 473 | 474 | &.television > .nav-item-wrapper .nav-item-link::before { 475 | @include mi; 476 | content: 'desktop_windows'; 477 | } 478 | 479 | &.camera > .nav-item-wrapper .nav-item-link::before { 480 | @include mi; 481 | content: 'camera_alt'; 482 | } 483 | 484 | &.magazines > .nav-item-wrapper .nav-item-link::before { 485 | @include mi; 486 | content: 'import_contacts'; 487 | } 488 | 489 | &.store > .nav-item-wrapper .nav-item-link::before { 490 | @include mi; 491 | content: 'store'; 492 | } 493 | 494 | &.collections > .nav-item-wrapper .nav-item-link { 495 | span { 496 | font-size: 70%; 497 | line-height: 15px; 498 | height: 15px; 499 | padding: 0 4px; 500 | float: right; 501 | background: #ff635a; 502 | border-radius: 2px; 503 | margin-top: 2px; 504 | } 505 | 506 | &::before { 507 | @include mi; 508 | content: 'collections'; 509 | } 510 | } 511 | 512 | &.nolink > .nav-item-wrapper .nav-item-link::before { 513 | @include mi; 514 | content: 'format_clear'; 515 | } 516 | 517 | &.disabled > .nav-item-wrapper .nav-item-link::before { 518 | @include mi; 519 | content: 'block'; 520 | } 521 | } 522 | 523 | &.nav-position-top, 524 | &.nav-position-bottom { 525 | 526 | ul.bottom-nav { 527 | position: relative; 528 | border-top: none; 529 | } 530 | 531 | .nav-wrapper-0 > .nav-content { 532 | padding-bottom: 0; 533 | } 534 | } 535 | 536 | ul.bottom-nav { 537 | position: absolute; 538 | left: 0; 539 | right: 0; 540 | bottom: 0; 541 | z-index: 10; 542 | width: 100%; 543 | display: flex; 544 | flex-wrap: nowrap; 545 | align-items: stretch; 546 | border-top: 1px solid rgba(#000, .15); 547 | 548 | li { 549 | flex: auto; 550 | 551 | a { 552 | padding: 10px; 553 | text-align: center; 554 | height: 100%; 555 | border-bottom: none; 556 | } 557 | 558 | svg { 559 | fill: #fff; 560 | display: inline-block; 561 | vertical-align: middle; 562 | } 563 | 564 | &.github { 565 | svg { 566 | width: 17px; 567 | height: 17px; 568 | } 569 | } 570 | 571 | &.ko-fi { 572 | svg { 573 | width: 21px; 574 | height: 21px; 575 | } 576 | } 577 | 578 | &.email { 579 | svg { 580 | width: 19px; 581 | height: 19px; 582 | } 583 | } 584 | } 585 | } 586 | } 587 | 588 | body.theme-default { 589 | .hc-offcanvas-nav { 590 | 591 | .second-nav { 592 | border-bottom: none !important; 593 | } 594 | } 595 | } -------------------------------------------------------------------------------- /dist/hc-offcanvas-nav.carbon.css: -------------------------------------------------------------------------------- 1 | html.hc-nav-yscroll{overflow-y:scroll}body.hc-nav-open{overflow:visible;position:fixed;width:100%;min-height:100%}.hc-offcanvas-nav{visibility:hidden;display:none;position:fixed;top:0;height:100%;z-index:9999;text-align:left}.hc-offcanvas-nav.is-ios *{cursor:pointer !important}.hc-offcanvas-nav .nav-container{position:fixed;z-index:9998;top:0;height:100%;max-width:100%;max-height:100%;box-sizing:border-box;transition:transform .4s ease}.hc-offcanvas-nav .nav-wrapper{width:100%;height:100%;box-sizing:border-box;-ms-scroll-chaining:none;overscroll-behavior:none}.hc-offcanvas-nav .nav-content{height:100%}.hc-offcanvas-nav .nav-wrapper-0>.nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box}.hc-offcanvas-nav ul{list-style:none;margin:0;padding:0}.hc-offcanvas-nav li{position:relative;display:block}.hc-offcanvas-nav li.level-open>.nav-wrapper{visibility:visible}.hc-offcanvas-nav li:not(.custom-content) a{position:relative;display:block;box-sizing:border-box;cursor:pointer}.hc-offcanvas-nav li:not(.custom-content) a[disabled]{cursor:not-allowed}.hc-offcanvas-nav li:not(.custom-content) a,.hc-offcanvas-nav li:not(.custom-content) a:hover{text-decoration:none}.hc-offcanvas-nav input[type="checkbox"]{display:none}.hc-offcanvas-nav label{position:absolute;top:0;left:0;right:0;bottom:0;z-index:10;cursor:pointer}.hc-offcanvas-nav .nav-item-wrapper{position:relative}.hc-offcanvas-nav .nav-item-link{position:relative;display:block;box-sizing:border-box}.hc-offcanvas-nav:not(.user-is-tabbing) .nav-close-button:focus,.hc-offcanvas-nav:not(.user-is-tabbing) .nav-item-wrapper a:focus{outline:none}.hc-offcanvas-nav .nav-close:focus,.hc-offcanvas-nav .nav-next:focus,.hc-offcanvas-nav .nav-back:focus{z-index:10}.hc-offcanvas-nav.disable-body::after,.hc-offcanvas-nav .nav-wrapper::after{content:'';z-index:9990;top:0;left:0;right:0;bottom:0;width:100%;height:100%;-ms-scroll-chaining:none;overscroll-behavior:none;visibility:hidden;opacity:0;transition:visibility 0s ease .4s,opacity .4s ease}.hc-offcanvas-nav.disable-body::after{position:fixed}.hc-offcanvas-nav .nav-wrapper::after{position:absolute}.hc-offcanvas-nav.disable-body.nav-open::after,.hc-offcanvas-nav .sub-level-open::after{visibility:visible;opacity:1;transition-delay:.05s}.hc-offcanvas-nav:not(.nav-open)::after{pointer-events:none}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper::after{display:none}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper.nav-wrapper-0{max-height:100vh}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper.nav-wrapper-0>.nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box;max-height:100vh}.hc-offcanvas-nav.nav-levels-expand ul .nav-wrapper{min-width:0;max-height:0;visibility:hidden;overflow:hidden;transition:height 0s ease .4s}.hc-offcanvas-nav.nav-levels-expand .level-open>.nav-wrapper{max-height:none;overflow:visible;visibility:visible}.hc-offcanvas-nav.nav-levels-overlap .nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box;max-height:100vh}.hc-offcanvas-nav.nav-levels-overlap .nav-wrapper{max-height:100vh}.hc-offcanvas-nav.nav-levels-overlap ul .nav-wrapper{position:absolute;z-index:9999;top:0;height:100%;visibility:hidden;transition:visibility 0s ease .4s,transform .4s ease}.hc-offcanvas-nav.nav-levels-overlap ul li.nav-parent{position:static}.hc-offcanvas-nav.nav-levels-overlap ul li.level-open>.nav-wrapper{visibility:visible;transform:translate3d(0, 0, 0);transition:transform .4s ease}.hc-offcanvas-nav.nav-position-left{left:0}.hc-offcanvas-nav.nav-position-left .nav-container{left:0}.hc-offcanvas-nav.nav-position-left.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(-100%, 0, 0)}.hc-offcanvas-nav.nav-position-right{right:0}.hc-offcanvas-nav.nav-position-right .nav-container{right:0}.hc-offcanvas-nav.nav-position-right.nav-levels-overlap li .nav-wrapper{right:0;transform:translate3d(100%, 0, 0)}.hc-offcanvas-nav.nav-position-top{top:0}.hc-offcanvas-nav.nav-position-top .nav-container{top:0;width:100%}.hc-offcanvas-nav.nav-position-top.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(0, -100%, 0)}.hc-offcanvas-nav.nav-position-bottom{top:auto;bottom:0}.hc-offcanvas-nav.nav-position-bottom .nav-container{top:auto;bottom:0;width:100%}.hc-offcanvas-nav.nav-position-bottom.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(0, 100%, 0)}.hc-offcanvas-nav.nav-open[class*='hc-nav-'] div.nav-container{transform:translate3d(0, 0, 0)}.hc-offcanvas-nav.rtl{text-align:right;direction:rtl}.hc-nav-trigger{position:absolute;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:none;top:20px;z-index:9980;width:30px;min-height:24px}.hc-nav-trigger span{width:30px;top:50%;transform:translateY(-50%);transform-origin:50% 50%}.hc-nav-trigger span,.hc-nav-trigger span::before,.hc-nav-trigger span::after{display:block;position:absolute;left:0;height:4px;background:#34495E;transition:all .2s ease}.hc-nav-trigger span::before,.hc-nav-trigger span::after{content:'';width:100%}.hc-nav-trigger span::before{top:-10px}.hc-nav-trigger span::after{bottom:-10px}.hc-nav-trigger.toggle-open span{background:rgba(0,0,0,0);transform:rotate(45deg)}.hc-nav-trigger.toggle-open span::before{transform:translate3d(0, 10px, 0)}.hc-nav-trigger.toggle-open span::after{transform:rotate(-90deg) translate3d(10px, 0, 0)}.hc-offcanvas-nav{font-family:sans-serif}.hc-offcanvas-nav .nav-container,.hc-offcanvas-nav .nav-wrapper,.hc-offcanvas-nav ul{background:#202225}.hc-offcanvas-nav::after,.hc-offcanvas-nav .nav-wrapper::after{background:rgba(0,0,0,0.3)}.hc-offcanvas-nav .nav-content{padding:0 15px}.hc-offcanvas-nav .nav-content>h2,.hc-offcanvas-nav .nav-content>h3,.hc-offcanvas-nav .nav-content>h4,.hc-offcanvas-nav .nav-content>h5,.hc-offcanvas-nav .nav-content>h6{font-size:19px;font-weight:normal;padding:25px 15px 30px;color:#fff}.hc-offcanvas-nav .nav-content>h2:first-child,.hc-offcanvas-nav .nav-content>h3:first-child,.hc-offcanvas-nav .nav-content>h4:first-child,.hc-offcanvas-nav .nav-content>h5:first-child,.hc-offcanvas-nav .nav-content>h6:first-child{margin-top:10px}.hc-offcanvas-nav .nav-content>h2:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h3:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h4:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h5:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h6:not(.nav-title):not(.level-title){font-size:16px;padding:15px 12px;text-transform:uppercase;color:#b3b3b3}.hc-offcanvas-nav .nav-item-link,.hc-offcanvas-nav li.nav-close a,.hc-offcanvas-nav .nav-back a{padding:12px;font-size:15px;color:#fff;z-index:1;background:rgba(0,0,0,0);border-radius:5px;transition:.05s background ease}.hc-offcanvas-nav .nav-item-link:focus,.hc-offcanvas-nav .nav-item-link:focus-within,.hc-offcanvas-nav li.nav-close a:focus,.hc-offcanvas-nav li.nav-close a:focus-within,.hc-offcanvas-nav .nav-back a:focus,.hc-offcanvas-nav .nav-back a:focus-within{z-index:10}.hc-offcanvas-nav .nav-item-link[disabled],.hc-offcanvas-nav li.nav-close a[disabled],.hc-offcanvas-nav .nav-back a[disabled]{color:rgba(255,255,255,0.5)}.hc-offcanvas-nav:not(.touch-device) li:not(.nav-item-custom) a:not([disabled]):hover{background:#272a2d}.hc-offcanvas-nav .nav-custom-content{padding:12px 15px;font-size:15px}.hc-offcanvas-nav .nav-highlight>.nav-item-wrapper .nav-item-link{border-radius:5px;background:#292c30}.hc-offcanvas-nav .nav-wrapper-0>.nav-content>ul:first-child{margin-top:15px}.hc-offcanvas-nav .nav-wrapper-0>.nav-content>ul:not(:last-child){margin-bottom:18px}.hc-offcanvas-nav li{color:#fff}.hc-offcanvas-nav li.nav-close a:hover,.hc-offcanvas-nav li.nav-back a:hover{background:#111213}.hc-offcanvas-nav li.nav-close:not(:first-child) a,.hc-offcanvas-nav li.nav-back:not(:first-child) a{margin-top:-1px}.hc-offcanvas-nav li.nav-parent .nav-item-link:last-child{padding-right:62px}.hc-offcanvas-nav li.nav-parent .nav-item-link:not(:last-child){margin-right:52px}.hc-offcanvas-nav .nav-close-button span,.hc-offcanvas-nav .nav-parent .nav-next,.hc-offcanvas-nav .nav-back span{width:40px;position:absolute;top:0;right:0;bottom:0;text-align:center;cursor:pointer;border-radius:5px;transition:background .2s ease}.hc-offcanvas-nav .nav-close-button{position:relative;display:block}.hc-offcanvas-nav .nav-close-button span::before,.hc-offcanvas-nav .nav-close-button span::after{content:'';position:absolute;top:50%;left:50%;width:6px;height:6px;margin-top:-3px;border-top:2px solid #fff;border-left:2px solid #fff}.hc-offcanvas-nav .nav-close-button span::before{margin-left:-9px;transform:rotate(135deg)}.hc-offcanvas-nav .nav-close-button span::after{transform:rotate(-45deg)}.hc-offcanvas-nav .nav-content>.nav-close a{height:44px;font-size:15px;color:#fff;background:rgba(0,0,0,0);border-radius:5px;z-index:1;text-decoration:none;box-sizing:border-box}.hc-offcanvas-nav .nav-content>.nav-close a.has-label{padding:12px 15px}.hc-offcanvas-nav .nav-content>.nav-close a:hover{background:#25272a}.hc-offcanvas-nav .nav-content>.nav-close:first-child{position:relative;min-height:40px;margin-top:15px}.hc-offcanvas-nav .nav-content>.nav-close:first-child+ul{margin-top:15px}.hc-offcanvas-nav .nav-content>.nav-close:first-child a.has-label{margin-bottom:-15px}.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label){position:absolute;width:40px;height:40px;line-height:40px;top:0;right:0}.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+ul{margin-top:60px}.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+h2,.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+h3,.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+h4,.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+h5,.hc-offcanvas-nav .nav-content>.nav-close:first-child a:not(.has-label)+h6{margin-top:55px}.hc-offcanvas-nav .nav-title+.nav-close a:not(.has-label){position:absolute;width:40px;height:40px;line-height:40px;top:28px;right:15px}.hc-offcanvas-nav.nav-close-button-empty .nav-title{padding-right:46px}.hc-offcanvas-nav li.nav-close:first-child{padding-bottom:15px}.hc-offcanvas-nav li.nav-close .nav-close-button.has-label{margin-bottom:-15px}.hc-offcanvas-nav li.nav-close .nav-close-button:not(.has-label){width:40px;height:40px;line-height:40px;float:right}.hc-offcanvas-nav li.nav-close .nav-item-wrapper::after{content:'';display:table;clear:both}.hc-offcanvas-nav a.nav-next{position:relative}.hc-offcanvas-nav a.nav-next:before{content:'';position:absolute;width:2px;height:25px;left:-7px;top:9px;background:#4d4d4d;border-radius:2px}.hc-offcanvas-nav .nav-next span::before,.hc-offcanvas-nav .nav-back span::before{content:'';position:absolute;top:50%;left:50%;width:8px;height:8px;margin-left:-2px;box-sizing:border-box;border-top:2px solid #fff;border-left:2px solid #fff;transform-origin:center}.hc-offcanvas-nav .nav-next span{position:absolute;top:0;right:0;left:0;bottom:0}.hc-offcanvas-nav .nav-next span::before{transform:translate(-50%, -50%) rotate(135deg)}.hc-offcanvas-nav .nav-back span::before{margin-left:2px;transform:translate(-50%, -50%) rotate(-45deg)}.hc-offcanvas-nav.nav-position-left.nav-open.nav-levels-overlap .nav-wrapper{box-shadow:1px 0 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-right.nav-open.nav-levels-overlap .nav-wrapper{box-shadow:-1px 0 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-right .nav-next span::before{margin-left:2px;transform:translate(-50%, -50%) rotate(-45deg)}.hc-offcanvas-nav.nav-position-right .nav-back span::before{margin-left:-2px;transform:translate(-50%, -50%) rotate(135deg)}.hc-offcanvas-nav.nav-position-top.nav-open .nav-wrapper{box-shadow:0 1px 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-top .nav-next span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-position-top .nav-back span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(45deg)}.hc-offcanvas-nav.nav-position-bottom.nav-open .nav-wrapper{box-shadow:0 -1px 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-bottom .nav-next span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(45deg)}.hc-offcanvas-nav.nav-position-bottom .nav-back span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-levels-overlap ul ul:first-child{margin-top:15px}.hc-offcanvas-nav.nav-levels-expand .nav-content .nav-content,.hc-offcanvas-nav.nav-levels-none .nav-content .nav-content{padding:0}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper .nav-wrapper,.hc-offcanvas-nav.nav-levels-none .nav-wrapper .nav-wrapper{width:auto;position:relative;margin-left:20px}.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>.nav-next span::before,.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>a>.nav-next span::before,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>.nav-next span::before,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>a>.nav-next span::before{margin-top:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-wrapper::before,.hc-offcanvas-nav.nav-levels-none li .nav-wrapper::before{content:'';position:absolute;width:2px;left:-7px;top:5px;bottom:5px;background:#4d4d4d;border-radius:2px}.hc-offcanvas-nav.rtl .nav-wrapper .nav-wrapper{margin-left:0;margin-right:20px}.hc-offcanvas-nav.rtl a.nav-next:before{left:auto;right:-7px}.hc-offcanvas-nav.rtl .nav-title+.nav-close a:not(.has-label){left:15px;right:auto}.hc-offcanvas-nav.rtl .nav-close-button span,.hc-offcanvas-nav.rtl .nav-next,.hc-offcanvas-nav.rtl .nav-back span{left:0;right:auto}.hc-offcanvas-nav.rtl li.nav-parent .nav-item-link:last-child{padding-left:62px;padding-right:12px}.hc-offcanvas-nav.rtl li.nav-parent .nav-item-link:not(:last-child){margin-left:52px;margin-right:0}.hc-offcanvas-nav.rtl.nav-levels-expand li.level-open>.nav-wrapper::before,.hc-offcanvas-nav.rtl.nav-levels-none li .nav-wrapper::before{left:auto;right:-7px} 2 | -------------------------------------------------------------------------------- /dist/hc-offcanvas-nav.css: -------------------------------------------------------------------------------- 1 | html.hc-nav-yscroll{overflow-y:scroll}body.hc-nav-open{overflow:visible;position:fixed;width:100%;min-height:100%}.hc-offcanvas-nav{visibility:hidden;display:none;position:fixed;top:0;height:100%;z-index:9999;text-align:left}.hc-offcanvas-nav.is-ios *{cursor:pointer !important}.hc-offcanvas-nav .nav-container{position:fixed;z-index:9998;top:0;height:100%;max-width:100%;max-height:100%;box-sizing:border-box;transition:transform .4s ease}.hc-offcanvas-nav .nav-wrapper{width:100%;height:100%;box-sizing:border-box;-ms-scroll-chaining:none;overscroll-behavior:none}.hc-offcanvas-nav .nav-content{height:100%}.hc-offcanvas-nav .nav-wrapper-0>.nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box}.hc-offcanvas-nav ul{list-style:none;margin:0;padding:0}.hc-offcanvas-nav li{position:relative;display:block}.hc-offcanvas-nav li.level-open>.nav-wrapper{visibility:visible}.hc-offcanvas-nav li:not(.custom-content) a{position:relative;display:block;box-sizing:border-box;cursor:pointer}.hc-offcanvas-nav li:not(.custom-content) a[disabled]{cursor:not-allowed}.hc-offcanvas-nav li:not(.custom-content) a,.hc-offcanvas-nav li:not(.custom-content) a:hover{text-decoration:none}.hc-offcanvas-nav input[type="checkbox"]{display:none}.hc-offcanvas-nav label{position:absolute;top:0;left:0;right:0;bottom:0;z-index:10;cursor:pointer}.hc-offcanvas-nav .nav-item-wrapper{position:relative}.hc-offcanvas-nav .nav-item-link{position:relative;display:block;box-sizing:border-box}.hc-offcanvas-nav:not(.user-is-tabbing) .nav-close-button:focus,.hc-offcanvas-nav:not(.user-is-tabbing) .nav-item-wrapper a:focus{outline:none}.hc-offcanvas-nav .nav-close:focus,.hc-offcanvas-nav .nav-next:focus,.hc-offcanvas-nav .nav-back:focus{z-index:10}.hc-offcanvas-nav.disable-body::after,.hc-offcanvas-nav .nav-wrapper::after{content:'';z-index:9990;top:0;left:0;right:0;bottom:0;width:100%;height:100%;-ms-scroll-chaining:none;overscroll-behavior:none;visibility:hidden;opacity:0;transition:visibility 0s ease .4s,opacity .4s ease}.hc-offcanvas-nav.disable-body::after{position:fixed}.hc-offcanvas-nav .nav-wrapper::after{position:absolute}.hc-offcanvas-nav.disable-body.nav-open::after,.hc-offcanvas-nav .sub-level-open::after{visibility:visible;opacity:1;transition-delay:.05s}.hc-offcanvas-nav:not(.nav-open)::after{pointer-events:none}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper::after{display:none}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper.nav-wrapper-0{max-height:100vh}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper.nav-wrapper-0>.nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box;max-height:100vh}.hc-offcanvas-nav.nav-levels-expand ul .nav-wrapper{min-width:0;max-height:0;visibility:hidden;overflow:hidden;transition:height 0s ease .4s}.hc-offcanvas-nav.nav-levels-expand .level-open>.nav-wrapper{max-height:none;overflow:visible;visibility:visible}.hc-offcanvas-nav.nav-levels-overlap .nav-content{overflow:scroll;overflow-x:visible;overflow-y:auto;box-sizing:border-box;max-height:100vh}.hc-offcanvas-nav.nav-levels-overlap .nav-wrapper{max-height:100vh}.hc-offcanvas-nav.nav-levels-overlap ul .nav-wrapper{position:absolute;z-index:9999;top:0;height:100%;visibility:hidden;transition:visibility 0s ease .4s,transform .4s ease}.hc-offcanvas-nav.nav-levels-overlap ul li.nav-parent{position:static}.hc-offcanvas-nav.nav-levels-overlap ul li.level-open>.nav-wrapper{visibility:visible;transform:translate3d(0, 0, 0);transition:transform .4s ease}.hc-offcanvas-nav.nav-position-left{left:0}.hc-offcanvas-nav.nav-position-left .nav-container{left:0}.hc-offcanvas-nav.nav-position-left.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(-100%, 0, 0)}.hc-offcanvas-nav.nav-position-right{right:0}.hc-offcanvas-nav.nav-position-right .nav-container{right:0}.hc-offcanvas-nav.nav-position-right.nav-levels-overlap li .nav-wrapper{right:0;transform:translate3d(100%, 0, 0)}.hc-offcanvas-nav.nav-position-top{top:0}.hc-offcanvas-nav.nav-position-top .nav-container{top:0;width:100%}.hc-offcanvas-nav.nav-position-top.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(0, -100%, 0)}.hc-offcanvas-nav.nav-position-bottom{top:auto;bottom:0}.hc-offcanvas-nav.nav-position-bottom .nav-container{top:auto;bottom:0;width:100%}.hc-offcanvas-nav.nav-position-bottom.nav-levels-overlap li .nav-wrapper{left:0;transform:translate3d(0, 100%, 0)}.hc-offcanvas-nav.nav-open[class*='hc-nav-'] div.nav-container{transform:translate3d(0, 0, 0)}.hc-offcanvas-nav.rtl{text-align:right;direction:rtl}.hc-nav-trigger{position:absolute;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:none;top:20px;z-index:9980;width:30px;min-height:24px}.hc-nav-trigger span{width:30px;top:50%;transform:translateY(-50%);transform-origin:50% 50%}.hc-nav-trigger span,.hc-nav-trigger span::before,.hc-nav-trigger span::after{display:block;position:absolute;left:0;height:4px;background:#34495E;transition:all .2s ease}.hc-nav-trigger span::before,.hc-nav-trigger span::after{content:'';width:100%}.hc-nav-trigger span::before{top:-10px}.hc-nav-trigger span::after{bottom:-10px}.hc-nav-trigger.toggle-open span{background:rgba(0,0,0,0);transform:rotate(45deg)}.hc-nav-trigger.toggle-open span::before{transform:translate3d(0, 10px, 0)}.hc-nav-trigger.toggle-open span::after{transform:rotate(-90deg) translate3d(10px, 0, 0)}.hc-offcanvas-nav{font-family:sans-serif}.hc-offcanvas-nav::after,.hc-offcanvas-nav .nav-wrapper::after{background:rgba(0,0,0,0.3)}.hc-offcanvas-nav .nav-container,.hc-offcanvas-nav .nav-wrapper,.hc-offcanvas-nav ul{background:#336ca6}.hc-offcanvas-nav .nav-content>h2,.hc-offcanvas-nav .nav-content>h3,.hc-offcanvas-nav .nav-content>h4,.hc-offcanvas-nav .nav-content>h5,.hc-offcanvas-nav .nav-content>h6{font-size:19px;font-weight:normal;padding:20px 17px;color:#1b3958}.hc-offcanvas-nav .nav-content>h2:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h3:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h4:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h5:not(.nav-title):not(.level-title),.hc-offcanvas-nav .nav-content>h6:not(.nav-title):not(.level-title){font-size:16px;padding:15px 17px;background:#336ca6}.hc-offcanvas-nav .nav-item-link,.hc-offcanvas-nav li.nav-close a,.hc-offcanvas-nav .nav-back a{padding:14px 17px;font-size:14px;color:#fff;z-index:1;background:rgba(0,0,0,0);border-bottom:1px solid #2c5d8f;transition:background .1s ease}.hc-offcanvas-nav .nav-item-link:focus,.hc-offcanvas-nav .nav-item-link:focus-within,.hc-offcanvas-nav li.nav-close a:focus,.hc-offcanvas-nav li.nav-close a:focus-within,.hc-offcanvas-nav .nav-back a:focus,.hc-offcanvas-nav .nav-back a:focus-within{z-index:10}.hc-offcanvas-nav .nav-item-link[disabled],.hc-offcanvas-nav li.nav-close a[disabled],.hc-offcanvas-nav .nav-back a[disabled]{color:rgba(255,255,255,0.5)}.hc-offcanvas-nav div.nav-back+ul>li:first-child>.nav-item-wrapper>.nav-item-link{border-top:none !important}.hc-offcanvas-nav:not(.touch-device) li:not(.nav-item-custom) a:not([disabled]):hover{background:#31679e}.hc-offcanvas-nav .nav-custom-content{padding:14px 17px;font-size:14px;border-bottom:1px solid #2c5d8f}.hc-offcanvas-nav .nav-highlight{background:#2e6296}.hc-offcanvas-nav .nav-wrapper>.nav-content>ul:first-of-type>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link{border-top:1px solid #2c5d8f}.hc-offcanvas-nav .nav-wrapper>.nav-content>ul:first-of-type>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link+a{border-top:1px solid #2c5d8f}.hc-offcanvas-nav .nav-wrapper>.nav-content>ul:not(:last-child){border-bottom:2px solid #2c5d8f}.hc-offcanvas-nav .nav-wrapper>.nav-content>ul+h2,.hc-offcanvas-nav .nav-wrapper>.nav-content>ul+h3,.hc-offcanvas-nav .nav-wrapper>.nav-content>ul+h4,.hc-offcanvas-nav .nav-wrapper>.nav-content>ul+h5,.hc-offcanvas-nav .nav-wrapper>.nav-content>ul+h6{margin-top:-2px}.hc-offcanvas-nav .nav-wrapper>.nav-content>h2+ul>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link,.hc-offcanvas-nav .nav-wrapper>.nav-content>h3+ul>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link,.hc-offcanvas-nav .nav-wrapper>.nav-content>h4+ul>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link,.hc-offcanvas-nav .nav-wrapper>.nav-content>h5+ul>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link,.hc-offcanvas-nav .nav-wrapper>.nav-content>h6+ul>li:first-child:not(.nav-back):not(.nav-close)>.nav-item-wrapper>.nav-item-link{border-top:1px solid #2c5d8f}.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-title+h2,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-title+h3,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-title+h4,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-title+h5,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-title+h6,.hc-offcanvas-nav .nav-wrapper>.nav-content>.level-title+h2,.hc-offcanvas-nav .nav-wrapper>.nav-content>.level-title+h3,.hc-offcanvas-nav .nav-wrapper>.nav-content>.level-title+h4,.hc-offcanvas-nav .nav-wrapper>.nav-content>.level-title+h5,.hc-offcanvas-nav .nav-wrapper>.nav-content>.level-title+h6,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-close+h2,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-close+h3,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-close+h4,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-close+h5,.hc-offcanvas-nav .nav-wrapper>.nav-content>.nav-close+h6{border-top:1px solid #2c5d8f}.hc-offcanvas-nav li{color:#fff}.hc-offcanvas-nav li.nav-parent .nav-item-link:last-child{padding-right:58px}.hc-offcanvas-nav li.nav-parent .nav-item-link:not(:last-child){margin-right:45px}.hc-offcanvas-nav .nav-close-button span,.hc-offcanvas-nav .nav-parent .nav-next,.hc-offcanvas-nav .nav-back span{width:45px;position:absolute;top:0;right:0;bottom:0;text-align:center;cursor:pointer;transition:background .1s ease}.hc-offcanvas-nav .nav-close-button{position:relative;display:block}.hc-offcanvas-nav .nav-close-button span::before,.hc-offcanvas-nav .nav-close-button span::after{content:'';position:absolute;top:50%;left:50%;width:6px;height:6px;margin-top:-3px;border-top:2px solid #fff;border-left:2px solid #fff}.hc-offcanvas-nav .nav-close-button span::before{margin-left:-9px;transform:rotate(135deg)}.hc-offcanvas-nav .nav-close-button span::after{transform:rotate(-45deg)}.hc-offcanvas-nav .nav-content>.nav-close{position:relative;z-index:2}.hc-offcanvas-nav .nav-content>.nav-close a{font-size:14px;color:#fff;background:rgba(0,0,0,0);z-index:1;text-decoration:none;box-sizing:border-box}.hc-offcanvas-nav .nav-content>.nav-close a:not(.has-label){height:50px}.hc-offcanvas-nav .nav-content>.nav-close a.has-label{padding:14px 17px;border-top:1px solid #2c5d8f}.hc-offcanvas-nav .nav-content>.nav-close a:hover{border:none;background:radial-gradient(farthest-corner at top right, rgba(0,0,0,0.1), rgba(0,0,0,0))}.hc-offcanvas-nav .nav-content>.nav-close.has-label+ul{margin-top:-1px}.hc-offcanvas-nav:not(.nav-close-button-empty) .nav-content>.nav-close{margin-bottom:-1px}.hc-offcanvas-nav .nav-title+.nav-close a:not(.has-label){position:absolute;width:45px;height:66px;line-height:66px;top:-66px;right:0}.hc-offcanvas-nav.nav-close-button-empty .nav-title{padding-right:55px}.hc-offcanvas-nav li.nav-close a:not(.has-label){height:49px}.hc-offcanvas-nav .nav-content>.nav-close:first-child a,.hc-offcanvas-nav .nav-title+.nav-close a.has-label,.hc-offcanvas-nav li.nav-close a,.hc-offcanvas-nav .nav-back a{background:#2f649a;border-top:1px solid #2b5a8b;border-bottom:1px solid #2b5a8b}.hc-offcanvas-nav .nav-content>.nav-close:first-child a:hover,.hc-offcanvas-nav .nav-title+.nav-close a.has-label:hover,.hc-offcanvas-nav li.nav-close a:hover,.hc-offcanvas-nav .nav-back a:hover{background:#2e6195}.hc-offcanvas-nav li.nav-close:not(:first-child) a,.hc-offcanvas-nav li.nav-back:not(:first-child) a{margin-top:-1px}.hc-offcanvas-nav a.nav-next{border-left:1px solid #2c5d8f;border-bottom:1px solid #2c5d8f}.hc-offcanvas-nav .nav-next span::before,.hc-offcanvas-nav .nav-back span::before{content:'';position:absolute;top:50%;left:50%;width:8px;height:8px;margin-left:-2px;box-sizing:border-box;border-top:2px solid #fff;border-left:2px solid #fff;transform-origin:center}.hc-offcanvas-nav .nav-next span{position:absolute;top:0;right:0;left:0;bottom:0}.hc-offcanvas-nav .nav-next span::before{transform:translate(-50%, -50%) rotate(135deg)}.hc-offcanvas-nav .nav-back span::before{margin-left:2px;transform:translate(-50%, -50%) rotate(-45deg)}.hc-offcanvas-nav.nav-position-left.nav-open.nav-levels-overlap .nav-wrapper{box-shadow:1px 0 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-right.nav-open.nav-levels-overlap .nav-wrapper{box-shadow:-1px 0 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-right .nav-next span::before{margin-left:2px;transform:translate(-50%, -50%) rotate(-45deg)}.hc-offcanvas-nav.nav-position-right .nav-back span::before{margin-left:-2px;transform:translate(-50%, -50%) rotate(135deg)}.hc-offcanvas-nav.nav-position-top.nav-open .nav-wrapper{box-shadow:0 1px 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-top .nav-next span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-position-top .nav-back span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(45deg)}.hc-offcanvas-nav.nav-position-bottom.nav-open .nav-wrapper{box-shadow:0 -1px 2px rgba(0,0,0,0.2)}.hc-offcanvas-nav.nav-position-bottom .nav-next span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(45deg)}.hc-offcanvas-nav.nav-position-bottom .nav-back span::before{margin-left:0;margin-right:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-levels-expand ul .nav-wrapper,.hc-offcanvas-nav.nav-levels-none ul .nav-wrapper{box-shadow:none;background:transparent}.hc-offcanvas-nav.nav-levels-expand li.level-open,.hc-offcanvas-nav.nav-levels-none li.level-open{background:#2e6296}.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>a,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>a{border-bottom:1px solid #295887}.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>a:hover,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>a:hover{background:#2f649a}.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>.nav-next span::before,.hc-offcanvas-nav.nav-levels-expand li.level-open>.nav-item-wrapper>a>.nav-next span::before,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>.nav-next span::before,.hc-offcanvas-nav.nav-levels-none li.level-open>.nav-item-wrapper>a>.nav-next span::before{margin-top:-2px;transform:translate(-50%, -50%) rotate(-135deg)}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper-1 .nav-item-link,.hc-offcanvas-nav.nav-levels-none .nav-wrapper-1 .nav-item-link{padding-left:calc(17px + 20px * 1)}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper-2 .nav-item-link,.hc-offcanvas-nav.nav-levels-none .nav-wrapper-2 .nav-item-link{padding-left:calc(17px + 20px * 2)}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper-3 .nav-item-link,.hc-offcanvas-nav.nav-levels-none .nav-wrapper-3 .nav-item-link{padding-left:calc(17px + 20px * 3)}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper-4 .nav-item-link,.hc-offcanvas-nav.nav-levels-none .nav-wrapper-4 .nav-item-link{padding-left:calc(17px + 20px * 4)}.hc-offcanvas-nav.nav-levels-expand .nav-wrapper-5 .nav-item-link,.hc-offcanvas-nav.nav-levels-none .nav-wrapper-5 .nav-item-link{padding-left:calc(17px + 20px * 5)}.hc-offcanvas-nav.rtl a.nav-next{border-left:none;border-right:1px solid #2c5d8f}.hc-offcanvas-nav.rtl .nav-title+.nav-close a:not(.has-label),.hc-offcanvas-nav.rtl .nav-close-button span,.hc-offcanvas-nav.rtl .nav-next,.hc-offcanvas-nav.rtl .nav-back span{left:0;right:auto}.hc-offcanvas-nav.rtl li.nav-parent .nav-item-link:last-child{padding-left:58px;padding-right:17px}.hc-offcanvas-nav.rtl li.nav-parent .nav-item-link:not(:last-child){margin-left:45px;margin-right:0}.hc-offcanvas-nav.rtl .nav-wrapper-1 li.nav-item .nav-item-link{padding-right:calc(17px + 20px * 1)}.hc-offcanvas-nav.rtl .nav-wrapper-2 li.nav-item .nav-item-link{padding-right:calc(17px + 20px * 2)}.hc-offcanvas-nav.rtl .nav-wrapper-3 li.nav-item .nav-item-link{padding-right:calc(17px + 20px * 3)}.hc-offcanvas-nav.rtl .nav-wrapper-4 li.nav-item .nav-item-link{padding-right:calc(17px + 20px * 4)}.hc-offcanvas-nav.rtl .nav-wrapper-5 li.nav-item .nav-item-link{padding-right:calc(17px + 20px * 5)} 2 | -------------------------------------------------------------------------------- /src/js/hc-offcanvas-nav.helpers.js: -------------------------------------------------------------------------------- 1 | ((window) => { 2 | 'use strict'; 3 | 4 | const hcOffcanvasNav = window.hcOffcanvasNav; 5 | const document = window.document; 6 | 7 | if (typeof Object.assign !== 'function') { 8 | Object.defineProperty(Object, 'assign', { 9 | value: function assign(target, varArgs) { 10 | 'use strict'; 11 | if (target == null) { 12 | throw new TypeError('Cannot convert undefined or null to object'); 13 | } 14 | 15 | var to = Object(target); 16 | 17 | for (var index = 1; index < arguments.length; index++) { 18 | var nextSource = arguments[index]; 19 | 20 | if (nextSource != null) { 21 | for (var nextKey in nextSource) { 22 | if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { 23 | to[nextKey] = nextSource[nextKey]; 24 | } 25 | } 26 | } 27 | } 28 | return to; 29 | }, 30 | writable: true, 31 | configurable: true 32 | }); 33 | } 34 | 35 | if (!Element.prototype.closest) { 36 | Element.prototype.closest = function(s) { 37 | let el = this; 38 | do { 39 | if (Element.prototype.matches.call(el, s)) return el; 40 | el = el.parentElement || el.parentNode; 41 | } while (el !== null && el.nodeType === 1); 42 | return null; 43 | }; 44 | } 45 | 46 | if (!Array.prototype.flat) { 47 | Object.defineProperty(Array.prototype, 'flat', { 48 | configurable: true, 49 | value: function flat() { 50 | var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]); 51 | 52 | return depth ? Array.prototype.reduce.call(this, function (acc, cur) { 53 | if (Array.isArray(cur)) { 54 | acc.push.apply(acc, flat.call(cur, depth - 1)); 55 | } else { 56 | acc.push(cur); 57 | } 58 | 59 | return acc; 60 | }, []) : Array.prototype.slice.call(this); 61 | }, 62 | writable: true 63 | }); 64 | } 65 | 66 | if (!Element.prototype.matches) { 67 | Element.prototype.matches = 68 | Element.prototype.msMatchesSelector || 69 | Element.prototype.matchesSelector || 70 | Element.prototype.mozMatchesSelector || 71 | Element.prototype.oMatchesSelector || 72 | Element.prototype.webkitMatchesSelector; 73 | } 74 | 75 | let supportsPassive = false; 76 | try { 77 | const opts = Object.defineProperty({}, 'passive', { 78 | get: function() { 79 | supportsPassive = {passive: false}; 80 | } 81 | }); 82 | window.addEventListener('testPassive', null, opts); 83 | window.removeEventListener('testPassive', null, opts); 84 | } catch (e) {} 85 | 86 | const isIos = (() => ((/iPad|iPhone|iPod/.test(navigator.userAgent)) || (!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform))) && !window.MSStream)(); 87 | 88 | const isTouchDevice = (() => 'ontouchstart' in window || navigator.maxTouchPoints || (window.DocumentTouch && document instanceof DocumentTouch))(); 89 | 90 | const isNumeric = (n) => !isNaN(parseFloat(n)) && isFinite(n); 91 | 92 | const formatSizeVal = (n) => (n === 'auto') ? '100%' : isNumeric(n) && n !== 0 ? `${n}px` : n; 93 | 94 | const toMs = (s) => parseFloat(s) * (/\ds$/.test(s) ? 1000 : 1); 95 | 96 | const stopPropagation = (e) => e.stopPropagation(); 97 | const preventDefault = (e) => e.preventDefault(); 98 | 99 | const preventClick = (cb) => { 100 | return (e) => { 101 | e.preventDefault(); 102 | e.stopPropagation(); 103 | if (typeof cb === 'function') cb(); 104 | }; 105 | }; 106 | 107 | const browserPrefix = (prop) => { 108 | const prefixes = ['Webkit', 'Moz', 'Ms', 'O']; 109 | const thisBody = document.body || document.documentElement; 110 | const thisStyle = thisBody.style; 111 | const Prop = prop.charAt(0).toUpperCase() + prop.slice(1); 112 | 113 | if (typeof thisStyle[prop] !== 'undefined') { 114 | return prop; 115 | } 116 | 117 | for (let i = 0; i < prefixes.length; i++) { 118 | if (typeof thisStyle[prefixes[i] + Prop] !== 'undefined') { 119 | return prefixes[i] + Prop; 120 | } 121 | } 122 | 123 | return false; 124 | }; 125 | 126 | const children = (el, selector) => { 127 | if (el instanceof Element) { 128 | return selector ? Array.prototype.filter.call(el.children, (child) => child.matches(selector)) : el.children; 129 | } 130 | else { 131 | let children = []; 132 | 133 | Array.prototype.forEach.call(el, (n) => { 134 | children = selector 135 | ? children.concat(Array.prototype.filter.call(n.children, (child) => child.matches(selector))) 136 | : children.concat(Array.prototype.slice.call(n.children)); 137 | }); 138 | 139 | return children; 140 | } 141 | }; 142 | 143 | const wrap = (el, wrapper) => { 144 | el.parentNode.insertBefore(wrapper, el); 145 | wrapper.appendChild(el); 146 | }; 147 | 148 | const data = (el, prop, val) => { 149 | el.hcOffcanvasNav = el.hcOffcanvasNav || {}; 150 | 151 | if (typeof val !== 'undefined') { 152 | el.hcOffcanvasNav[prop] = val; 153 | } 154 | else { 155 | return el.hcOffcanvasNav[prop]; 156 | } 157 | }; 158 | 159 | const clone = (el, withEvents, deepWithEvents) => { 160 | const cloned = el.cloneNode(deepWithEvents || false); 161 | const srcElements = el instanceof Element ? [el].concat(Array.prototype.slice.call(el.getElementsByTagName('*'))) : []; 162 | const destElements = cloned instanceof Element ? [cloned].concat(Array.prototype.slice.call(cloned.getElementsByTagName('*'))) : []; 163 | 164 | const cloneCopyEvent = (src, dest) => { 165 | for (let s = 0; s < src.length; s++) { 166 | if (src[s]._eventListeners) { 167 | for (const type in src[s]._eventListeners) { 168 | for (let i = 0; i < src[s]._eventListeners[type].length; i++) { 169 | dest[i].addEventListener(type, src[s]._eventListeners[type][i].fn, src[s]._eventListeners[type][i].options); 170 | } 171 | } 172 | } 173 | } 174 | }; 175 | 176 | if (!withEvents) { 177 | srcElements.shift(); 178 | destElements.shift(); 179 | } 180 | 181 | if (deepWithEvents) { 182 | cloneCopyEvent(srcElements, destElements); 183 | } 184 | 185 | return cloned; 186 | }; 187 | 188 | const customEventObject = (type, target, currentTarget, args) => { 189 | function Event(type) { 190 | this.bubbles = false; 191 | this.cancelable = false; 192 | this.composed = false; 193 | this.currentTarget = currentTarget; 194 | this.data = args ? {} : null; 195 | this.defaultPrevented = false; 196 | this.eventPhase = 0; 197 | this.isTrusted = false; 198 | this.target = target; 199 | this.timeStamp = Date.now(); 200 | this.type = type; 201 | 202 | for (const prop in args) { 203 | this.data[prop] = args[prop]; 204 | } 205 | } 206 | 207 | return new Event(type); 208 | }; 209 | 210 | const hasListener = (el, type) => { 211 | return (type ? (el._eventListeners || {})[type] : el._eventListeners) || false; 212 | }; 213 | 214 | const addRemoveListener = (op) => { 215 | const f = Node.prototype[op + 'EventListener']; 216 | 217 | return function (name, cb, opts) { 218 | if (!this) return; 219 | 220 | const eventName = name.split('.')[0]; 221 | 222 | this._eventListeners = this._eventListeners || {}; 223 | 224 | if (op === 'add') { 225 | this._eventListeners[name] = this._eventListeners[name] || []; 226 | 227 | const lstn = {fn: cb}; 228 | 229 | if (opts) { 230 | lstn.options = opts; 231 | } 232 | 233 | this._eventListeners[name].push(lstn); 234 | 235 | // call native addEventListener 236 | f.call(this, eventName, cb, opts); 237 | } 238 | else { 239 | // remove single event listener 240 | if (typeof cb === 'function') { 241 | // call native addEventListener 242 | f.call(this, eventName, cb, opts); 243 | 244 | for (const e in this._eventListeners) { 245 | this._eventListeners[e] = this._eventListeners[e].filter((l) => { 246 | return l.fn !== cb; 247 | }); 248 | 249 | if (!this._eventListeners[e].length) { 250 | delete this._eventListeners[e]; 251 | } 252 | } 253 | } 254 | else { 255 | // remove all event listeners 256 | if (this._eventListeners[name]) { 257 | for (let i = this._eventListeners[name].length; i--;) { 258 | // call native addEventListener 259 | f.call(this, eventName, this._eventListeners[name][i].fn, this._eventListeners[name][i].options); 260 | 261 | this._eventListeners[name].splice(i, 1); 262 | } 263 | 264 | if (!this._eventListeners[name].length) { 265 | delete this._eventListeners[name]; 266 | } 267 | } 268 | } 269 | } 270 | 271 | return; 272 | }; 273 | }; 274 | 275 | Node.prototype.addEventListener = addRemoveListener('add'); 276 | Node.prototype.removeEventListener = addRemoveListener('remove'); 277 | 278 | const debounce = (func, wait, immediate) => { 279 | let timeout; 280 | 281 | return function() { 282 | const context = this; 283 | const args = arguments; 284 | const later = function() { 285 | timeout = null; 286 | 287 | if (!immediate) { 288 | func.apply(context, args); 289 | } 290 | }; 291 | const callNow = immediate && !timeout; 292 | 293 | clearTimeout(timeout); 294 | timeout = setTimeout(later, wait); 295 | 296 | if (callNow) { 297 | func.apply(context, args); 298 | } 299 | }; 300 | }; 301 | 302 | const createElement = (tag, props = {}, content) => { 303 | const el = document.createElement(tag); 304 | 305 | for (const p in props) { 306 | if (p !== 'class') { 307 | if (!(!props[p] && props[p] !== 0)) { 308 | el.setAttribute(p, props[p]); 309 | } 310 | } 311 | else { 312 | el.className = props[p]; 313 | } 314 | } 315 | 316 | if (content) { 317 | if (!Array.isArray(content)) { 318 | content = [content]; 319 | } 320 | 321 | for (let i = 0; i < content.length; i++) { 322 | if (typeof content[i] === 'object' && content[i].length && !content[i].nodeType) { 323 | for (let l = 0; l < content[i].length; l++) { 324 | el.appendChild(content[i][l]); 325 | } 326 | } 327 | else { 328 | el.appendChild(typeof content[i] === 'string' ? document.createTextNode(content[i]) : content[i]); 329 | } 330 | } 331 | } 332 | 333 | return el; 334 | }; 335 | 336 | const getElements = (el) => { 337 | let node = null; 338 | 339 | if (typeof el === 'string') { 340 | node = document.querySelectorAll(el); 341 | } 342 | else if (window.jQuery && el instanceof window.jQuery && el.length) { 343 | node = el.toArray(); 344 | } 345 | else if (el instanceof Element) { 346 | node = [el]; 347 | } 348 | 349 | return node; 350 | }; 351 | 352 | const getElementCssTag = (el) => { 353 | return typeof el === 'string' 354 | ? el 355 | : el.getAttribute('id') 356 | ? `#${el.getAttribute('id')}` 357 | : el.getAttribute('class') 358 | ? el.tagName.toLowerCase() + '.' + el.getAttribute('class').replace(/\s+/g, '.') 359 | : getElementCssTag(el.parentNode) + ' > ' + el.tagName.toLowerCase(); 360 | }; 361 | 362 | const printStyle = (id) => { 363 | const $style = createElement('style', {id: id}); 364 | let rules = {}; 365 | let media = {}; 366 | 367 | document.head.appendChild($style); 368 | 369 | const parseRules = (text) => { 370 | if (text.substr(-1) !== ';') { 371 | text += text.substr(-1) !== ';' ? ';' : ''; 372 | } 373 | return text; 374 | }; 375 | 376 | return { 377 | reset: () => { 378 | rules = {}; 379 | media = {}; 380 | }, 381 | add: (selector, declarations, query) => { 382 | selector = selector.trim(); 383 | declarations = declarations.trim(); 384 | 385 | if (query) { 386 | query = query.trim(); 387 | media[query] = media[query] || {}; 388 | media[query][selector] = parseRules(declarations); 389 | } 390 | else { 391 | rules[selector] = parseRules(declarations); 392 | } 393 | }, 394 | remove: (selector, query) => { 395 | selector = selector.trim(); 396 | 397 | if (query) { 398 | query = query.trim(); 399 | if (typeof media[query][selector] !== 'undefined') { 400 | delete media[query][selector]; 401 | } 402 | } 403 | else { 404 | if (typeof rules[selector] !== 'undefined') { 405 | delete rules[selector]; 406 | } 407 | } 408 | }, 409 | insert: () => { 410 | let cssText = ''; 411 | 412 | for (let breakpoint in media) { 413 | cssText += `@media screen and (${breakpoint}) {\n`; 414 | 415 | for (let key in media[breakpoint]) { 416 | cssText += ` ${key} { ${media[breakpoint][key]} }\n`; 417 | } 418 | 419 | cssText += '}\n'; 420 | } 421 | 422 | for (let key in rules) { 423 | cssText += `${key} { ${rules[key]} }\n`; 424 | } 425 | 426 | $style.innerHTML = cssText; 427 | } 428 | }; 429 | }; 430 | 431 | const insertAt = ($insert, n, $parent) => { 432 | const $children = children($parent); 433 | const count = $children.length; 434 | 435 | n = n === 'first' ? 0 : n; 436 | n = n === 'last' ? count : n; 437 | 438 | const i = n > -1 439 | ? Math.max(0, Math.min(n, count)) 440 | : Math.max(0, Math.min(count + n, count)); 441 | 442 | if (i === 0) { 443 | $parent[0].insertBefore($insert, $parent[0].firstChild); 444 | } else { 445 | $children[i - 1].insertAdjacentElement('afterend', $insert); 446 | } 447 | }; 448 | 449 | const getAxis = (position) => ['left', 'right'].indexOf(position) !== -1 ? 'x' : 'y'; 450 | 451 | const setTransform = (() => { 452 | const transform = browserPrefix('transform'); 453 | 454 | return ($el, val, pos) => { 455 | if (val === false || val === '') { 456 | $el.style.transform = ''; 457 | } 458 | else { 459 | if (getAxis(pos) === 'x') { 460 | const x = pos === 'left' ? val : -val; 461 | $el.style.transform = `translate3d(${formatSizeVal(x)},0,0)`; 462 | } 463 | else { 464 | const y = pos === 'top' ? val : -val; 465 | $el.style.transform = `translate3d(0,${formatSizeVal(y)},0)`; 466 | } 467 | } 468 | }; 469 | })(); 470 | 471 | const deprecated = (() => { 472 | const pluginName = 'HC Off-canvas Nav'; 473 | 474 | return (what, instead, type) => { 475 | console.warn( 476 | '%c' + pluginName + ':' 477 | + '%c ' + type 478 | + "%c '"+ what + "'" 479 | + '%c is now deprecated and will be removed in the future. Use' 480 | + "%c '" + instead + "'" 481 | + '%c option instead. See details about plugin usage at https://github.com/somewebmedia/hc-offcanvas-nav.', 482 | 'color: #fa253b', 483 | 'color: default', 484 | 'color: #5595c6', 485 | 'color: default', 486 | 'color: #5595c6', 487 | 'color: default'); 488 | }; 489 | })(); 490 | 491 | hcOffcanvasNav.Helpers = { 492 | supportsPassive, 493 | isIos, 494 | isTouchDevice, 495 | isNumeric, 496 | formatSizeVal, 497 | toMs, 498 | stopPropagation, 499 | preventDefault, 500 | preventClick, 501 | browserPrefix, 502 | children, 503 | wrap, 504 | data, 505 | clone, 506 | customEventObject, 507 | hasListener, 508 | debounce, 509 | createElement, 510 | getElements, 511 | getElementCssTag, 512 | printStyle, 513 | insertAt, 514 | getAxis, 515 | setTransform, 516 | deprecated 517 | }; 518 | 519 | })(window); 520 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HC Off-canvas Nav 2 | =============== 3 | 4 | [![Version](https://img.shields.io/npm/v/hc-offcanvas-nav.svg)](https://www.npmjs.com/package/hc-offcanvas-nav) [![Downloads](https://img.shields.io/npm/dt/hc-offcanvas-nav.svg)](https://www.npmjs.com/package/hc-offcanvas-nav) 5 | 6 | JavaScript library for creating off-canvas multi-level navigations, using ARIA. Dependency free, but also works as a jQuery plugin. [Demo](https://somewebmedia.github.io/hc-offcanvas-nav/) 7 | 8 | 9 | 10 | 11 | 12 | ### Features 13 | - Multi-level menu support 14 | - Endless nesting of navigation elements 15 | - Custom content inside menu items 16 | - Push/Slide DOM elements of choice 17 | - Touch swipe guestures 18 | - Different navigation positions 19 | - No dependencies 20 | - Flexible, simple markup 21 | - A number of exposed [Options](#options), [Methods](#methods) and [Events](#events) 22 | - 2 [Themes](#themes) 23 | - Cross-browser compatibility 24 | - Full ARIA keyboard support 25 | - It relies on ARIA Design pattern for Dialogs 26 | - The tab key loops through all of the keyboard focusable items within the offcanvas navigation 27 | - You can close it using Esc 28 | 29 | 30 | 31 | ## Quick start 32 | 33 | ### Install 34 | 35 | This package can be installed with: 36 | 37 | - [npm](https://www.npmjs.com/package/hc-offcanvas-nav): `npm install --save hc-offcanvas-nav` 38 | 39 | Or download the [latest release](https://github.com/somewebmedia/hc-offcanvas-nav/tags). 40 | 41 | 42 | 43 | ### Including HC Off-canvas Nav 44 | 45 | #### Script and Css tag 46 | ```html 47 | 48 | 49 | 50 | ``` 51 | 52 | #### Webpack/Browserify 53 | 54 | In the script, including HC Off-canvas Nav will usually look like this: 55 | 56 | ```js 57 | const hcOffcanvasNav = require('hc-offcanvas-nav'); 58 | ``` 59 | 60 | #### Babel 61 | 62 | ```js 63 | import hcOffcanvasNav from 'hc-offcanvas-nav'; 64 | ``` 65 | 66 | #### AMD (Asynchronous Module Definition) 67 | 68 | If using AMD, the module will be automatically defined as `hcOffcanvasNav`. 69 | 70 | #### SCSS 71 | 72 | ```scss 73 | @import 'hc-offcanvas-nav/src/scss/core'; 74 | @import 'hc-offcanvas-nav/src/scss/toggle'; 75 | @import 'hc-offcanvas-nav/src/scss/theme-default'; 76 | ``` 77 | 78 | 79 | ## Usage 80 | 81 | Be sure to call the Nav once your menu element is available in the DOM. 82 | 83 | #### Vanilla JS 84 | 85 | ```js 86 | document.addEventListener('DOMContentLoaded', function() { 87 | 88 | var Nav = new hcOffcanvasNav('#main-nav', { 89 | disableAt: 1024, 90 | customToggle: '.toggle', 91 | navTitle: 'All Categories', 92 | levelTitles: true, 93 | levelTitleAsBack: true 94 | }); 95 | 96 | }); 97 | ``` 98 | 99 | #### jQuery 100 | 101 | ```js 102 | jQuery(document).ready(function($) { 103 | 104 | $('#main-nav').hcOffcanvasNav({ 105 | disableAt: 1024, 106 | customToggle: $('.toggle'), 107 | navTitle: 'All Categories', 108 | levelTitles: true, 109 | levelTitleAsBack: true 110 | }); 111 | 112 | }); 113 | ``` 114 | 115 | For HC Off-canvas Nav to work as a jQuery plugin, jQuery has to be a property of global `window` object, so be careful when using it in combination with Babel/Webpack/Browserify and jQuery. 116 | 117 | #### Example HTML menu structure 118 | 119 | ```html 120 | 141 | ``` 142 | 143 | 144 | ## Themes 145 | 146 | HC Off-canvas Nav currently has 2 themes, the default and Carbon. To use Carbon theme simply call the Carbon theme css instead of the default one: 147 | 148 | ```html 149 | 150 | ``` 151 | 152 | Or if compiling the SCSS from the `src` dir, `@include` it from there: 153 | 154 | ```scss 155 | @import 'hc-offcanvas-nav/src/scss/core'; 156 | @import 'hc-offcanvas-nav/src/scss/toggle'; 157 | @import 'hc-offcanvas-nav/src/scss/theme-carbon'; 158 | ``` 159 | 160 | 161 | ## Options 162 | 163 | | Property | Default | Type | Description | 164 | |----------|---------|------|-------------| 165 | | **width** | `280` | int / str | Width of the nav. Used for `left` and `right` positions. | 166 | | **height** | `'auto'` | int / str | Height of the nav. Used for `top` and `bottom` positions. | 167 | | **disableAt** | `false` | int / bool | Resolution above which to hide the offcanvas menu, and show the original. | 168 | | **pushContent** | `null` | str / Element obj | Content element (string selector or HTML Element object) that will be pushed when the navigation is open. | 169 | | **expanded** | `false`| bool | Initialize menu in expanded mode. It won't push content. | 170 | | **position** | `'left'` | str | Position on which the menu will open. Available options: `'left'`, `'right'`, `'top'` and `'bottom'`. | 171 | | **swipeGestures** | `true`| bool | Enable open/close swipe gestures like in native apps. Works only for `left` and `right` positions. | 172 | | **levelOpen** | `'overlap'` | str | Submenu levels open effect. Available options: `'overlap'`, `'expand'`, `'none'` or `false`. | 173 | | **levelSpacing** | `40` | int | If levels are overlaped, this is the spacing between them, if they are expanding or always open, this is the text indent of the submenus. | 174 | | **levelTitles** | `true` | bool | Show titles for submenus, which is the parent item name. Works only for overlaped levels. | 175 | | **navTitle** | `null` | str / Element obj | Main navigation (first level) title. Can also be HTML object like an image (logo). | 176 | | **navClass** | `''` | str | Custom navigation class. | 177 | | **disableBody** | `true` | bool | Disable body scroll when navigation is open. | 178 | | **closeOpenLevels** | `true` | bool | Should all open sub levels be closed when the nav closes. | 179 | | **closeActiveLevel** | `false` | bool | Should initially active sub level (see [`data-nav-active`](#data-attributes)) be cleared when the nav closes. | 180 | | **closeOnClick** | `true` | bool | Close the navigation when links are clicked. | 181 | | **closeOnEsc** | `true` | bool | Close the navigation on Esc button. | 182 | | **customToggle** | `null` | str / Element obj | Custom navigation toggle element. | 183 | | **activeToggleClass** | `null` | str | Custom active toggle class. | 184 | | **insertClose** | `true` | bool / int | Insert navigation close button. You can also use an integer representing 0-based index that will be the position of the button in the list. Negative numbers are also supported. | 185 | | **insertBack** | `true` | bool / int | Insert back buttons to submenus. You can also use an integer representing 0-based index that will be the position of the button in the list. Negative numbers are also supported. Works only for overlaped levels. | 186 | | **labelClose** | `''` | str | Label for the close button. | 187 | | **labelBack** | `'Back'` | str | Label for the back buttons. | 188 | | **levelTitleAsBack** | `true` | bool | Use level titles as back labels. | 189 | | **rtl** | `false` | bool | Set the content direction to right-to-left. | 190 | | **bodyInsert** | `'prepend'` | str | Choose to prepend or append navigation to body. | 191 | | **keepClasses** | `true` | bool | Should original menus and their items classes be preserved or excluded. | 192 | | **removeOriginalNav** | `false` | bool | Remove original menu from the DOM. Don't use this if planning to update the nav! | 193 | | **ariaLabels** | `{...}` | obj | Labels for the ARIA attributes. If using HC Off-canvas Nav in different language than English, you should translate all the properties. See the next section. | 194 | 195 | ARIA labels for the `aria-label` attributes on specific elements which will provide a text alternative to the elements that have no visible text on the screen. 196 | 197 | ```js 198 | ariaLabels: { 199 | open: 'Open Menu', 200 | close: 'Close Menu', 201 | submenu: 'Submenu' 202 | } 203 | ``` 204 | 205 | 206 | ## Methods 207 | 208 | The HC Off-canvas Nav API offers a couple of methods to control the offcanvas and are publicly available to all active instances. 209 | 210 | #### Vanilla JS 211 | 212 | ```js 213 | var Nav = new hcOffcanvasNav(); 214 | ``` 215 | 216 | #### jQuery 217 | 218 | ```js 219 | var $nav = $('#main-nav').hcOffcanvasNav(); 220 | var Nav = $nav.data('hcOffcanvasNav'); 221 | ``` 222 | 223 | ### .getSettings() 224 | 225 | Returns current settings. 226 | 227 | ```js 228 | var currentSettings = Nav.getSettings(); 229 | ``` 230 | 231 | ### .isOpen() 232 | 233 | Checks if the nav is open, and returns boolean. 234 | 235 | ```js 236 | if (Nav.isOpen()) { 237 | // do something 238 | } 239 | ``` 240 | 241 | ### .update(options, updateDOM) 242 | 243 | Updates just the specified settings with the new ones. 244 | 245 | ```js 246 | Nav.update({ 247 | disableAt: 1024, 248 | navTitle: 'All pages' 249 | }); 250 | ``` 251 | 252 | Updates nav DOM. You don't have to pass empty settings object, the method is smart. Use this when original nav has been altered. 253 | 254 | ```js 255 | Nav.update(true); 256 | ``` 257 | 258 | Updates both settings and nav DOM. Use this when original nav was changed and you also want to update some specific settings. 259 | 260 | ```js 261 | Nav.update({ 262 | disableAt: 1024, 263 | navTitle: 'All pages' 264 | }, true); 265 | ``` 266 | 267 | ### .open(level, index) 268 | 269 | Opens the nav if closed. 270 | 271 | ```js 272 | Nav.open(); 273 | ``` 274 | 275 | Open the nav and also a specific sub menu. Each level sub menu has its own index that is relative to that level, not the parent menu. 276 | 277 | ```js 278 | Nav.open(2, 1); 279 | ``` 280 | Above code will open the nested menu in the example structure bellow: 281 | 282 | ```html 283 | 318 | ``` 319 | 320 | ### .close() 321 | 322 | Closes the nav if open. 323 | 324 | ```js 325 | Nav.close(); 326 | ``` 327 | 328 | ### .toggle() 329 | 330 | Toggles (open/close) the nav. 331 | 332 | ```js 333 | Nav.toggle(); 334 | ``` 335 | 336 | ### .on(eventName, cb) 337 | 338 | Attach [Event](#events) listener to the nav. 339 | 340 | ```js 341 | Nav.on('close', function() { 342 | // do something on close 343 | }); 344 | ``` 345 | 346 | ### .off(eventName, cb) 347 | 348 | Remove [Event](#events) listener from the nav. 349 | 350 | ```js 351 | // remove specific function 352 | Nav.off('close', onCloseFunction); 353 | 354 | // remove all event listeners 355 | Nav.off('close'); 356 | ``` 357 | 358 | ## Events 359 | 360 | | Event | Description | 361 | |-------|-------------| 362 | | **open** | Triggers each time after nav is opened. | 363 | | **open.level** | Triggers each time after any level is opened. | 364 | | **close** | Triggers each time after nav is closed. | 365 | | **close.once** | Triggers only the first time after nav is closed, and than it detaches itself. | 366 | | **close.level** | Triggers each time after any level is closed. | 367 | | **toggle** | Triggers each time nav is triggered to be opened or closed. | 368 | 369 | All events return Event object as first argument, and the plugin Settings object as second argument. 370 | 371 | - `open.level` and `close.level` return the newly opened level and index under the `Event.data` property. 372 | - `toggle` event returns the action under the `Event.data` property. 373 | 374 | Open and close events are triggered after the nav animation is over, whie toggle event gets triggered imediatelly. 375 | 376 | Examples: 377 | 378 | ```js 379 | // change nav open position after each close 380 | Nav.on('close', function(e, settings) { 381 | Nav.update({ 382 | position: settings.position === 'left' ? 'right' : 'left' 383 | }); 384 | }); 385 | 386 | // will change nav open position only once 387 | Nav.on('close.once', function(e, settings) { 388 | Nav.update({ 389 | position: settings.position === 'left' ? 'right' : 'left' 390 | }); 391 | }); 392 | 393 | Nav.on('open.level', (e, settings) => { 394 | localStorage.setItem('NavLevel', e.data.currentLevel); 395 | localStorage.setItem('NavIndex', e.data.currentIndex); 396 | }); 397 | 398 | Nav.on('close.level', (e, settings) => { 399 | localStorage.setItem('NavLevel', e.data.currentLevel); 400 | localStorage.setItem('NavIndex', e.data.currentIndex); 401 | }); 402 | 403 | Nav.on('toggle', (e, settings) => { 404 | if (e.data.action == 'open') { 405 | // do something when `open` action is triggered 406 | } 407 | }); 408 | ``` 409 | 410 | 411 | ## Data Attributes 412 | 413 | | Attr | Accepts | HTML Element | Description | 414 | |------|---------|--------------|-------------| 415 | | **data-nav-active** | | `