Skip to content

Instantly share code, notes, and snippets.

@Shekey
Created August 25, 2021 11:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shekey/13e6cca8b7ef80cb840ded6a0eb3a992 to your computer and use it in GitHub Desktop.
Save Shekey/13e6cca8b7ef80cb840ded6a0eb3a992 to your computer and use it in GitHub Desktop.
Multimenu dropdown with animations (HUGO)
$breakpoints: (
'xs': 576px,
'sm': 768px,
'md': 1010px,
'lg': 1200px,
'xl': 1440px,
'xxl': 1640px,
'xxxl': 1920px
);
@mixin breakpoint-up($breakpoint) {
$value: map-get($breakpoints, $breakpoint);
@if $value != null {
@media (min-width: $value) {
@content;
}
}
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Please make sure it is defined in `$breakpoints` map.";
}
}
@mixin breakpoint-down($breakpoint) {
$value: map-get($breakpoints, $breakpoint);
@if $value != null {
@media (max-width: ($value - 1)) {
@content;
}
}
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Please make sure it is defined in `$breakpoints` map.";
}
}
$color-black: #000;
$color-night: #080808;
$color-white: #fff;
$color-red: #e11d39;
$color-grey: #e6e7ea;
$color-grey-light: #f7f7f7;
$color-mint: #9dfdb4;
.text-night {
color: $color-night !important;
}
.text-white {
color: $color-white !important;
}
.bg-night {
background-color: $color-night !important;
}
.bg-mint {
background-color: $color-mint !important;
}
.bg-grey {
background-color: $color-grey !important;
}
{{ $extraClass := cond .IsHome "" "header--transparent" }}
<header class="header {{ $extraClass }}">
<div class="container">
<a href="/" aria-label="Homepage" class="header__logo">
logo here
</a>
{{- if .Site.Menus.main }}
{{ partial "menu" .}}
{{ partial "search" .}}
{{- end }}
</div>
</header>
.header {
background: rgba($color-black, 0.5);
color: $color-white;
transition: background 0.5s ease;
position: relative;
.drop-icon {
color: $color-mint;
display: inline-block;
margin-left: 8px;
font-size: 20px;
@include breakpoint-down('md') {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: flex-end;
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
}
span {
display: none;
&:first-of-type {
display: inline-block;
}
}
}
.container {
display: flex;
align-items: center;
position: relative;
flex-wrap: wrap;
@include breakpoint-down('md') {
padding: 0;
}
}
&__logo {
position: relative;
z-index: 11;
svg {
display: inline-block;
margin-right: 56px;
fill: $color-white;
width: 166px;
height: 32px;
@include breakpoint-down('lg') {
margin-right: 20px;
}
@include breakpoint-down('lg') {
width: 126px;
height: 24px;
}
@include breakpoint-down('md') {
width: 104px;
height: 20px;
margin-right: 0;
margin-left: var(--container-padding);
}
}
}
input[type="checkbox"] {
display: none;
}
input[id="search"]:checked {
& + .search {
.icon-search-wrap {
color: rgba($color-night, 0.8);
transition: none;
max-height: initial;
max-width: initial;
background-color: $color-grey;
padding: 19px;
z-index: 0;
opacity: 1;
}
label:first-of-type {
border: none;
}
.icon-search {
transition: max-height 0.3s ease, max-width 0.3s ease, z-index 0s ease, opacity 0.3s ease 0.2s;
max-height: 0;
max-width: 0;
z-index: -100;
opacity: 0;
padding: 0;
}
.search__input {
top: 58px;
transition: opacity 0.2s ease, z-index 0s ease, top 0.2s ease, width 1s ease 0.4s;
opacity: 1;
width: 100%;
z-index: 100;
input {
transition: width 0.5s ease;
&::placeholder {
opacity: 1;
transition: opacity 0.3s ease 0.8s;
}
}
@include breakpoint-up('md') {
top: 84px;
width: 100%;
width: calc(100% - 2 * var(--container-padding));
}
}
}
}
.menu-text {
@include breakpoint-up('md') {
margin: 0 12px;
}
@include breakpoint-up('xxl') {
margin: 0 20px;
}
}
ul {
list-style: none;
}
&--transparent {
background: transparent;
color: $color-night;
.drop-icon {
color: $color-night;
}
svg {
fill: $color-night;
}
}
}
input[id="burger"] {
display: none;
&:checked + .body-overflow {
@include breakpoint-down('xxl') {
overflow: hidden;
height: 100vh;
}
.header {
@include breakpoint-down('xxl') {
background: $color-white;
color: $color-night;
transition: background 0.5s ease;
}
&__logo svg {
@include breakpoint-down('xxl') {
fill: $color-night;
}
}
.search__input {
@include breakpoint-down('xxl') {
opacity: 0 !important;
transition: width 0.4s ease, top 0.2s ease 0.4s, opacity 0.3s ease 0.2s, z-index 0s ease 0.6s;
z-index: -1 !important;
}
}
.search {
@include breakpoint-down('xxl') {
flex: 1;
padding: 28px 0;
}
@include breakpoint-down('md') {
padding: 0;
}
label:first-of-type {
@include breakpoint-down('xxl') {
border: none;
}
}
}
.icon-search-wrap {
@include breakpoint-down('xxl') {
display: none;
}
}
.container {
.menu__button {
justify-content: center;
border: 1px solid $color-night;
@include breakpoint-down('md') {
border: none;
background: $color-grey;
transition: background 0.5s ease-in;
}
span {
@include breakpoint-down('xxl') {
display: none;
}
&:last-of-type {
@include breakpoint-down('xxl') {
transition: max-height 0.3s ease, height 0.3s ease 0s, z-index 0s ease, opacity 0.3s ease 0.2s;
height: auto;
max-height: initial;
z-index: 10;
opacity: 1;
width: 24px;
display: flex;
justify-content: center;
}
@include breakpoint-down('md') {
justify-content: center;
}
}
}
}
.drop-icon {
@include breakpoint-down('xxl') {
color: $color-night;
}
}
.menu {
transition: max-height 0.3s ease, height 0.3s ease 0s, z-index 0s ease, background 0.5s ease, opacity 0.3s ease 0.2s;
height: calc(100vh - 56px);
max-height: 100vh;
z-index: 10;
opacity: 1;
padding-top: 32px;
box-shadow: inset 1px 3px 16px 0 rgba($color-night, 0.15);
@include breakpoint-up('md') {
display: block;
overflow-y: auto;
flex-basis: calc(100% + 2 * var(--container-padding));
order: 2;
margin: 0 calc(-1 * var(--container-padding));
}
@include breakpoint-up('xxl') {
flex: 1;
opacity: 1;
order: initial;
max-height: initial;
height: initial;
z-index: initial;
display: flex;
overflow: initial;
box-shadow: none;
margin: 0;
padding: 0;
}
@include breakpoint-down('xxl') {
background: $color-grey-light;
}
}
.menu__sublist {
margin: 0;
width: calc(100% + 2 * var(--container-padding));
max-width: calc(100% + 2 * var(--container-padding));
background: transparent;
&::after {
@include breakpoint-down('xxl') {
content: none;
}
}
a:hover {
@include breakpoint-down('xxl') {
background-color: $color-grey;
}
}
}
.menu__list {
@include breakpoint-down('xxl') {
display: block;
}
}
.menu__item {
@include breakpoint-down('xxl') {
margin: 0;
a:hover {
background-color: $color-grey;
}
}
&.big {
@include breakpoint-down('xxl') {
font-size: 20px;
line-height: 32px;
}
}
.menu__link {
@include breakpoint-down('xxl') {
padding: 16px var(--container-padding);
}
@include breakpoint-down('md') {
padding: 16px;
}
}
}
.menu__list-right {
@include breakpoint-down('xxl') {
z-index: 1;
max-height: initial;
height: initial;
overflow: hidden;
transition: opacity 0.3s, max-height 0.3s ease 0.3s, height 0.3s ease 0.3s, z-index 0s ease 0.3s;
opacity: 1;
overflow-y: auto;
display: block;
position: relative;
}
@include breakpoint-up('xxl') {
display: flex;
flex: 1;
justify-content: flex-end;
border-top: none;
}
&::before {
@include breakpoint-down('xxl') {
content: '';
position: absolute;
left: var(--container-padding);
width: calc(100% - 2 * var(--container-padding));
height: 1px;
top: 0;
border-top: 1px solid rgba($color-night, 0.25);
}
}
ul {
@include breakpoint-down('xxl') {
margin: 0;
display: block;
}
}
}
.menu__dropdown input[type="checkbox"] {
@include breakpoint-down('xxl') {
~ .menu__sublist {
display: none;
}
}
&:checked ~ .menu__link {
@include breakpoint-down('xxl') {
color: $color-night;
background-color: $color-grey;
}
.drop-icon span {
@include breakpoint-down('xxl') {
display: inline-block;
&:first-of-type {
display: none;
}
}
}
& ~ .menu__sublist {
@include breakpoint-down('xxl') {
border: none;
visibility: visible;
transition: none;
opacity: 1;
display: block;
position: relative;
padding: 0;
}
@include breakpoint-down('md') {
background-color: $color-grey-light;
}
}
}
}
}
}
}
}
<nav class="menu">
<ul class="menu__list">
{{- $currentNode := . }}
{{- range .Site.Menus.main }}
{{- if .Name }}
{{ if eq .Weight 50 }}
<li class="menu__list-right">
<ul>
{{- end }}
{{- if .HasChildren }}
<li class="menu__item menu-text big menu__dropdown{{ if in $currentNode.RelPermalink .URL }} menu__item--active{{ end }}">
<input type="checkbox" id="{{ .Name }}">
<a class="menu__link" href="{{ .URL }}">
<span class="menu__text">{{ .Name }}</span>
<label class="drop-icon" for="{{ .Name }}"><span>+</span><span>-</span></label>
</a>
<ul class="menu__sublist">
{{ range .Children }}
<li class="menu__item{{ if or ($currentNode.IsMenuCurrent " main" .) ($currentNode.HasMenuCurrent "main" .)
}} menu__item--active{{ end }}">
<a class="menu__link" href="{{ .URL }}">
<span class="menu__text">{{ .Name }}</span>
</a>
</li>
{{ end }}
</ul>
</li>
{{- else }}
<li class="menu__item menu-text big{{ if in $currentNode.RelPermalink .URL }}
menu__item--active{{ end }}">
<a class="menu__link" href="{{ .URL }}">
<span class="menu__text">{{ .Name }}</span>
</a>
</li>
{{- end }}
{{ if eq .Weight 70 }}
</ul>
</li>
{{- end }}
{{- end }}
{{- end }}
</ul>
</nav>
.menu {
flex-basis: 100%;
transition: opacity 0.3s, max-height 0.3s ease 0.3s, height 0.3s ease 0.3s, z-index 0s ease 0.3s;
opacity: 0;
@include breakpoint-down('md') {
order: 2;
height: 0;
max-height: 0;
z-index: -100;
overflow-y: auto;
}
@include breakpoint-up('md') {
flex: 1;
opacity: 1;
display: flex;
box-shadow: none;
}
&__button {
display: none;
@include breakpoint-down('xxl') {
display: flex;
align-items: center;
justify-content: flex-end;
width: 56px;
height: 56px;
padding: 0;
font: inherit;
color: inherit;
background: transparent;
border: 0;
outline: 0;
}
@include breakpoint-down('md') {
justify-content: center;
}
span {
font-size: 18px;
line-height: 16px;
transition: none;
height: auto;
max-height: initial;
z-index: 11;
opacity: 1;
width: 24px;
display: flex;
justify-content: flex-end;
&:last-of-type {
transition: none;
height: 0;
max-height: 0;
z-index: -100;
opacity: 0;
width: 0;
display: inline-block;
}
}
}
&__link {
display: flex;
padding: 16px;
color: inherit;
text-decoration: none;
position: relative;
@include breakpoint-up('md') {
padding: 44px 0;
}
&:hover {
text-decoration: none;
}
}
.menu__sublist {
background: $color-white;
color: $color-night;
visibility: hidden;
opacity: 0;
position: absolute;
top: 100%;
max-width: 20rem;
min-width: 240px;
transition: all 0.5s ease;
z-index: 101;
border: 1px solid rgba($color-night, 0.1);
border-top: 1px solid $color-mint;
display: block;
@include breakpoint-down('md') {
transition: none;
background: $color-white;
}
&:hover,
&:focus {
visibility: visible;
opacity: 1;
display: block;
margin: 0;
}
&::after {
@include breakpoint-up('md') {
content: '';
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid $color-mint;
display: inline-block;
transform: rotate(228deg);
top: -6px;
left: -6px;
position: absolute;
}
}
li:first-of-type {
@include breakpoint-up('md') {
margin-top: 16px;
}
}
.menu__link {
font-size: 16px;
@include breakpoint-up('md') {
font-size: 14px;
padding: 8px 16px;
}
}
a {
padding-left: 16px;
padding-right: 16px;
@include breakpoint-up('md') {
padding: 0;
}
&:hover {
background-color: $color-grey;
color: $color-night;
@include breakpoint-up('md') {
background-color: $color-mint;
}
}
&:first-child {
border: 0;
}
}
}
&__list {
display: block;
margin-top: 16px;
margin-bottom: 24px;
@include breakpoint-up('md') {
padding: 0;
position: relative;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
visibility: visible;
border: 0;
-webkit-transform: none;
transform: none;
margin-bottom: 0;
}
.menu__dropdown:hover {
& > .menu__sublist,
&:focus-within > .menu__sublist {
visibility: visible;
opacity: 1;
display: block;
margin: 0;
}
}
@include breakpoint-up('md') {
display: flex;
margin: 0;
flex: 1;
}
}
&__list-right {
display: flex;
flex: 1;
justify-content: flex-end;
border-top: none;
ul:not(.menu__sublist) {
display: flex;
margin: 0;
}
@include breakpoint-down('xxl') {
z-index: -100;
max-height: 0;
height: 0;
overflow: hidden;
transition: opacity 0.3s, max-height 0.3s ease 0.3s, height 0.3s ease 0.3s, z-index 0s ease 0.3s;
opacity: 0;
overflow-y: auto;
display: none;
}
@include breakpoint-down('xxl') {
margin-top: 16px;
padding-top: 16px;
}
.menu-text:first-of-type {
@include breakpoint-down('md') {
margin-top: 16px;
}
}
}
&__item--active {
position: relative;
&::after {
content: '';
top: 32px;
left: -16px;
width: calc(100% + 32px);
bottom: 32px;
position: absolute;
background: $color-mint;
z-index: -1;
}
@include breakpoint-down('md') {
background: $color-grey;
}
}
}
{
"main": [
{
"identifier": "a",
"name": "Aktualno",
"url": "/aktualno/",
"weight": 10
},
{
"identifier": "b",
"name": "E-mobilnost",
"url": "/e-mobilnost/",
"weight": 20
},
{
"identifier": "c",
"name": "Zakaj Porsche Slovenija",
"url": "/zakaj-porsche-slovenija/",
"weight": 70
},
{
"name": "aa",
"url": "aa",
"parent": "a",
"weight": 10
},
{
"name": "b",
"url": "bb",
"parent": "b",
"weight": 20
},
{
"name": "cc",
"url": "cc",
"weight": 10,
"parent": "c"
}
]
}
<input type="checkbox" id="search">
<div class="search">
<label role="button" aria-label="Išči" for="search"><i class="icon-search icon-search-wrap"></i></label>
<label role="button" aria-label="Zapri iskanje" for="search"><i class="icon-close icon-search-wrap"></i></label>
<label role="button" class="menu__button" aria-label="Meni" for="burger" aria-haspopup="true" aria-expanded="false" tabindex="0">
<span tabindex="-1"><i class="icon-hamburger"></i></span>
<span tabindex="-1"><i class="icon-close"></i></span>
</label>
<div class="search__input">
<input type="text" aria-label="Iskalno polje za članke" placeholder="Poiščite po vsebini">
</div>
</div>
.search {
display: flex;
flex: 1;
justify-content: flex-end;
@include breakpoint-up('md') {
flex: initial;
}
label {
&:not(.menu__button) {
display: flex;
align-items: center;
position: relative;
&:focus {
outline: 0;
}
&:first-of-type {
@include breakpoint-up('md') {
border: 1px solid $color-white;
}
}
}
&[for="search"] {
.icon-close {
transition: max-height 0.3s ease, max-width 0.3s ease, z-index 0s ease, opacity 0.4s ease 0.2s;
max-height: 0;
max-width: 0;
z-index: -100;
opacity: 0;
display: inline-block;
margin: 0;
font-size: 18px;
overflow: hidden;
}
.icon-search {
transition: max-height 0.3s ease, max-width 0.3s ease, z-index 0s ease, opacity 0.3s ease 0.2s;
max-height: initial;
max-width: initial;
z-index: 0;
opacity: 1;
display: inline-block;
font-size: 18px;
padding: 18px;
overflow: hidden;
@include breakpoint-down('md') {
margin: 0 20px;
padding: 0;
}
}
}
}
&__input {
position: absolute;
right: var(--container-padding);
top: 24px;
opacity: 0;
transition: width 0.4s ease, top 0.2s ease 0.4s, opacity 0.3s ease 0.2s, z-index 0s ease 0.6s;
width: 57px;
z-index: -1;
@include breakpoint-down('md') {
top: 44px;
right: 0;
}
&::before {
content: "\e901";
font-family: 'icomoon', sans-serif;
top: 16px;
right: 16px;
position: absolute;
color: rgba($color-night, 0.6);
font-size: 18px;
z-index: 10;
@include breakpoint-up('md') {
top: 20px;
right: 20px;
}
}
input {
transition: width 0.5s ease;
width: 100%;
padding: 16px 0;
text-indent: 16px;
position: relative;
border: none;
border-bottom: 1px solid $color-night;
@include breakpoint-up('md') {
text-indent: 32px;
padding: 20px 0;
}
&::placeholder {
opacity: 0;
transition: opacity 0.1s ease 0.1s;
}
&:focus {
outline: 0;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment