// Select the mobile menu style // styles include: sidebar, menu, none $nav-mobile-style: menu; // Responsive breakpoint $nav-min-width: $on-laptop; :root { //// Defaults // Padding defaults --nav-padding: .75ex; --nav-padding-ratio: 2.5; --nav-padding-y: var(--nav-padding); --nav-padding-x: calc(var(--nav-padding-y) * var(--nav-padding-ratio)); // Color defaults --color-nav: transparent; --color-nav-text: var(--color-text); --color-nav-menu: var(--color-grey-light); --color-nav-menu-top: var(--color-nav-menu); --color-nav-menu-top-text: var(--color-nav-text); --color-nav-highlight: var(--color-brand); --color-nav-highlight-text: #fff; --nav-active: transparent; // Icons --nav-icon-opacity: 0.5; --nav-icon-menu: "≡"; --nav-icon-right: "⯈"; --nav-icon-down: "▾"; // Styling defaults (shadow and rounded radius) --nav-menu-shadow: 2px 2px 2px rgba(var(--color-text), 0.125); --nav-menu-radius: 3px; // Animation timing defaults --nav-animation: 150ms; --nav-menu-animation: var(--nav-animation) * 2; --nav-mobile-menu-animation: all 300ms ease-in-out; // These should be set in theme.scss/theme.scss or minima already... // but just in case, we're defining fallbacks here --on-palm: 600px; --on-laptop: 800px; // Mobile menu colors --nav-mobile-text: white; --nav-mobile-text-shadow: 1px 1px 0 darken(var(--color-brand, ) 30%); --nav-mobile-menu: darken(var(--color-brand, ) 20%); --nav-mobile-menu-highlight: mix(var(--nav-mobile-menu, ) var(--nav-mobile-text, ) 80%); --nav-mobile-button-size: 32px; --nav-mobile-font-size: 16px; --nav-mobile-item-height: 48px; --nav-mobile-item-padding: 0 16px; --nav-mobile-menu-padding: 8px 0; --nav-mobile-menu-min-width: 56px * 3; // Native iOS or Android fonts when installed, else use website fonts --nav-mobile-font-family: -apple-system-font, "Roboto", "Droid Sans", var(--font-base-family); } //////////////////////////////////////////////////////////////////////// @mixin no-select { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .nav-check { display: none; } @media screen and (min-width: #{$nav-min-width + 1}) { nav.menu, %nav-menu { position: relative; z-index: 100; cursor: default; // Cleafix hack to make nav act more like block // without having to set an overflow property // (which would hide menus) &::after { content: ""; display: table; clear: both; } // Remove list styles ul, li { transition: all var(--nav-animation); list-style: none; margin: 0; padding: 0; } a, .not-a-link { transition: all var(--nav-menu-animation); display: block; color: var(--color-nav-text) !important; padding: var(--nav-padding-y) var(--nav-padding-x); text-decoration: none !important; } ul { background: var(--color-nav); ul { position: absolute; inset-inline-start: 0; inset-block-start: 100%; visibility: hidden; opacity: 0; box-shadow: var(--nav-menu-shadow); li { &:last-child { border-radius: 0 0 var(--nav-menu-radius) var(--nav-menu-radius); } &.nav-group:hover { border-radius: 0 0 0 var(--nav-menu-radius); } ul li:first-child { border-radius: 0 var(--nav-menu-radius) 0 0; } } ul { inset-inline-start: 100%; inset-block-start: 0; } } } li { float: left; position: relative; > ul { transform: scaleY(0); transform-origin: top left; ul { transform: scale(0); } } &:hover { background: var(--color-nav-menu); li { background: var(--color-nav-menu); } > ul { // Activate the immediate submenu visibility: visible; opacity: 1; // Make sure menus are on top (z-index is relative to parent z-index) z-index: 1; transform: scale(1); a, .not-a-link { margin: 0 calc(var(--nav-padding-x) * -1); padding: var(--nav-padding-y) calc(var(--nav-padding-x) * 2); } li:last-child a, .not-a-link { margin-block-end: calc(var(--nav-padding-y) * -4); padding-bottom: calc(var(--nav-padding-y) * 5); } } } li { width: 100%; white-space: nowrap; min-width: 10rem; &:hover, li:hover { background: var(--color-nav-highlight); > a { color: var(--color-nav-highlight-text) !important; } } } } > ul > li { &:hover { background: var(--color-nav-menu-top); > a { color: var(--color-nav-menu-top-text) !important; } } &.active { background: var(--nav-active); } &.nav-group > { a, .not-a-link { &::after { opacity: var(--nav-icon-opacity); content: var(--nav-icon-down); margin-inline-start: 1ex; } } } } li .nav-group > { a, .not-a-link { &::after { content: ""; display: inline-block; width: 3ex; } &::before { opacity: var(--nav-icon-opacity); content: var(--nav-icon-right); float: right; } } } } } @media screen and (max-width: $nav-min-width) { %sidebar { nav { font-family: var(--nav-mobile-font-family); font-size: var(--nav-mobile-font-size); z-index: 1000; cursor: default; ul, li { padding: 0; margin: 0; list-style: none; } li.active { background-color: var(--nav-mobile-menu-highlight); } > .nav-menu { transition: var(--nav-mobile-menu-animation); visibility: hidden; position: fixed; inset-block-start: 0; inset-inline-start: -100%; overflow: auto; height: 100vh; background-color: var(--nav-mobile-menu); z-index: 2; box-shadow: 0 0 6px rgba(var(--color-text), 0.25); min-width: 25vw; max-width: 75vw; padding: var(--nav-mobile-button-size) 0 0 1ex; > li { margin-block-start: 2ex; } ul { padding: 0 2ex 0 2ex; } a, .not-a-link { display: block; padding: 0 1ex; color: var(--nav-mobile-text) !important; text-shadow: var(--nav-mobile-text-shadow); } .not-a-link { opacity: 0.4; } } > .nav-screen { @include no-select; transition: var(--nav-mobile-menu-animation); opacity: 0; } .nav-toggle:before { transition: var(--nav-mobile-menu-animation); display: block; width: var(--nav-mobile-button-size); height: var(--nav-mobile-button-size); cursor: pointer; content: var(--nav-icon-menu); font-size: var(--nav-mobile-button-size); color: var(--color-nav-text); background: var(--color-nav-menu); z-index: 3; position: fixed; inset-block-start: 0; inset-inline-start: 0; padding: 0.5ex; line-height: var(--nav-mobile-button-size); border-radius: var(--nav-menu-radius); } } .nav-check:checked + nav > { .nav-menu { visibility: visible; inset-inline-start: 0; display: block; } .nav-screen { position: fixed; inset: 0; z-index: 1; background: var(--color-text); opacity: 0.5; } .nav-toggle:before { background: transparent; } } .hgroup { padding-inline-start: calc(calc(var(--nav-mobile-button-size)) + 1.5ex); } } %menu { & { display: flex; align-items: baseline; justify-content: space-between; } nav { font-family: var(--nav-mobile-font-family); font-size: var(--nav-mobile-font-size); z-index: 1000; cursor: default; position: relative; margin: 1rem; ul, li { padding: 0; margin: 0; list-style: none; } > .nav-menu { transition: all 100ms; visibility: hidden; transform: scale(0); transform-origin: calc(100% - 2.5ex) 2.5ex; position: absolute; inset-block-start: 0; inset-inline-end: 0; overflow: auto; background-color: var(--nav-mobile-menu); z-index: 2; box-shadow: 0 0 6px rgba(var(--color-text), 0.25); max-height: 75vh; padding: var(--nav-mobile-menu-padding); min-width: var(--nav-mobile-menu-min-width); ul { padding: 0 2ex 0 2ex; } a, .not-a-link { display: block; line-height: var(--nav-mobile-item-height); padding: var(--nav-mobile-item-padding); color: var(--nav-mobile-text) !important; text-shadow: var(--nav-mobile-text-shadow); text-decoration: none !important; } a:hover { background-color: rgba(var(--nav-mobile-menu-highlight,) 0.5); } .not-a-link { opacity: 0.4; } } li.active { background-color: var(--nav-mobile-menu-highlight); } .nav-toggle:before { transition: var(--nav-mobile-menu-animation); display: inline-block; width: var(--nav-mobile-button-size); height: var(--nav-mobile-button-size); cursor: pointer; content: var(--nav-icon-menu); font-size: var(--nav-mobile-button-size); color: var(--color-nav-text); z-index: 3; padding: 0.5ex; line-height: var(--nav-mobile-button-size); border-radius: var(--nav-menu-radius); } } .nav-check:checked + nav > { .nav-menu { visibility: visible; transform: scale(1); } // Invisible screen to capture clicks // (and not trigger page links) .nav-screen { @include no-select; position: fixed; inset: 0; z-index: 1; } .nav-toggle:before { background: transparent; } } } %none { background: none; } } //// Make the masthead a menu // It's also possible to extend nav.menu for other nav elements // ...or make nav elements with a class of menu in document bodies too .masthead { @extend %#{$nav-mobile-style}; nav { @extend %nav-menu; } }