Skip to content

Instantly share code, notes, and snippets.

@leojojo
Last active May 21, 2020 02:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leojojo/59e09e2e2fe9303b11dc348559a2f334 to your computer and use it in GitHub Desktop.
Save leojojo/59e09e2e2fe9303b11dc348559a2f334 to your computer and use it in GitHub Desktop.
Pure CSS Vue hamburger menu
$black: #111;
$white: #ddd;
$grey: lighten($black, 25%);
$primary: #a18e4d;
$hamburger-size: 50px;
$hamburger-hitbox-size: $hamburger-size * 1.2;
$hamburger-span-margin: ($hamburger-size / 3) / 2;
$hamburger-span-height: $hamburger-span-margin * 0.75;
<template>
<nav>
<input :checked="checkboxValue" type="checkbox" @click="checkInvert" />
<div>
<span></span>
<span></span>
<span></span>
</div>
<ul class="overlay">
<li v-for="item in items" :key="item.id">
<a :href="item.href" @click="checkInvert">
{{ item.text }}
</a>
</li>
</ul>
</nav>
</template>
<script>
export default {
name: 'Nav',
data() {
return {
items: [
{
text: 'ItemA',
href: '#itema'
},
{
text: 'ItemB',
date: '#itemb'
},
{
text: 'ItemC',
href: '#itemc'
}
],
checkboxValue: false
}
},
methods: {
checkInvert() {
this.checkboxValue = !this.checkboxValue
}
}
}
</script>
<style scoped lang="scss">
nav {
position: fixed;
display: grid;
width: 100vw;
}
input {
display: block;
width: $hamburger-hitbox-size;
height: $hamburger-hitbox-size;
left: 50%;
margin-left: $hamburger-hitbox-size / -2;
margin-top: $hamburger-hitbox-size;
position: absolute;
cursor: pointer;
opacity: 0;
z-index: 3;
-webkit-touch-callout: none;
&:checked {
& ~ div span {
opacity: 1;
transform: rotate(45deg) translate(2px, -2px);
&:nth-child(2) {
opacity: 0;
transform: rotate(0deg) scale(0.2, 0.2);
}
&:last-child {
transform: rotate(-45deg) translate(1px, -1px);
}
}
& ~ ul {
&.slide {
transform: none;
}
&.overlay {
visibility: visible;
opacity: 1;
}
}
}
}
div {
display: grid;
justify-self: center;
position: absolute;
margin-top: $hamburger-hitbox-size;
}
span {
position: sticky;
width: $hamburger-size;
height: $hamburger-span-height;
margin-top: $hamburger-span-margin / 5;
margin-bottom: $hamburger-span-margin;
background: $white;
border-radius: 2px;
z-index: 2;
transform-origin: ($hamburger-span-margin / 2) 0px;
transition: all 0.5s cubic-bezier(0.77, 0.2, 0.05, 1);
}
ul {
width: 100vw;
margin: 0;
padding: ($hamburger-hitbox-size * 2) 0 $hamburger-size;
list-style-type: none;
background-color: rgba(1, 0, 0, 0.9);
z-index: 1;
transition: all 0.5s cubic-bezier(0.77, 0.2, 0.05, 1);
&.slide {
display: grid;
justify-self: center;
-webkit-font-smoothing: antialiased;
transform-origin: 0% 0%;
transform: translate(0, -150%);
}
&.overlay {
position: fixed;
visibility: hidden;
top: 0;
left: 0;
bottom: 0;
opacity: 0;
}
}
li {
padding: ($hamburger-size / 2) $hamburger-size;
a {
font-size: $hamburger-size;
transition: all 0.25s cubic-bezier(0.77, 0.2, 0.05, 1);
&:hover {
color: $primary;
font-size: $hamburger-hitbox-size;
}
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment