feat: integrated menu on mobile (closes #3)

This commit is contained in:
Corentin 2024-05-21 11:22:10 +02:00
parent e830a247b5
commit 0d28c2ffeb
6 changed files with 180 additions and 86 deletions

View File

@ -1,3 +1,5 @@
import './nav.js'
class ToggleMenuButton extends HTMLElement {
connectedCallback() {
this.addEventListener('click', this.onClick.bind(this))

43
src/assets/js/nav.js Normal file
View File

@ -0,0 +1,43 @@
class NavBar extends HTMLElement {
connectedCallback() {
document.addEventListener("scroll", this.onScroll.bind(this))
}
onScroll(evt) {
const scrollThreshold = this.getAttribute('scroll-threshold')
if(window.scrollY > scrollThreshold) {
this.classList.add("nav-bar__scrolled")
}
else {
this.classList.remove("nav-bar__scrolled")
}
}
}
class ToggleNavBarButton extends HTMLElement {
connectedCallback() {
this.addEventListener('click', this.onClick.bind(this))
const windowsChangeEvent = ('onorientationchange' in window) ? 'orientationchange':'resize';
window.addEventListener(windowsChangeEvent, this.close.bind(this))
}
get navbar() {
const navbar = this.closest('nav-bar')
console.assert(navbar !== undefined)
return navbar
}
onClick(evt) {
this.navbar.classList.toggle('nav-bar__open')
evt.preventDefault()
}
close() {
this.navbar.classList.remove('nav-bar__open')
}
}
window.customElements.define('nav-bar', NavBar)
window.customElements.define('toggle-nav-bar-button', ToggleNavBarButton)

View File

@ -7,13 +7,13 @@ body {
color: var(--color);
}
.content {
margin: -60px auto 0 auto;
padding: 0 var(--space-small);
max-width: 1100px;
@media ($mobile-breakpoint) {
margin-top: 0;
}
* {
box-sizing: border-box;
}
.content {
margin: 0 auto;
padding: 0 var(--space-small);
max-width: 1100px;
}

View File

@ -1,33 +1,36 @@
<nav class="nav" id="nav">
<div class="nav--content">
<div class="nav--menu">
<ul class="nav--menu-section">
<li class="nav--menu-item">
<a href="#" class="nav--menu-link">Collective</a>
<nav-bar class="nav-bar" id="nav-bar">
<div class="nav-bar--content">
<div class="nav-bar--menu">
<ul class="nav-bar--menu-section">
<li class="nav-bar--menu-item">
<a href="#" class="nav-bar--menu-link">Collective</a>
</li>
<li class="nav--menu-item">
<a href="#" class="nav--menu-link">Games</a>
<li class="nav-bar--menu-item">
<a href="#" class="nav-bar--menu-link">Games</a>
</li>
<li class="nav--menu-item">
<a href="#" class="nav--menu-link">News</a>
<li class="nav-bar--menu-item">
<a href="#" class="nav-bar--menu-link">News</a>
</li>
<li class="nav--menu-item">
<a href="#" class="nav--menu-link">Contact</a>
<li class="nav-bar--menu-item">
<a href="#" class="nav-bar--menu-link">Contact</a>
</li>
</ul>
<ul class="nav--menu-section">
<li class="nav--menu-item">
<a href="#" class="nav--menu-link">Itch.io</a>
<ul class="nav-bar--menu-section">
<li class="nav-bar--menu-item">
<a href="#" class="nav-bar--menu-link">Itch.io</a>
</li>
</ul>
</div>
<div class="nav--title">
<img class="nav--logo" src="img/nav-logo.png" title="Frog Collective"></img>
<div class="nav-bar--brand">
<div class="nav-bar--logo-wrapper">
<img class="nav-bar--logo" src="/img/nav-logo.png"></img>
</div>
</div>
<toggle-menu-button target="nav" class="nav--toggle-button">
<toggle-nav-bar-button class="nav-bar--toggle-button">
<s class="bar"></s>
<s class="bar"></s>
</toggle-menu-button>
<s class="bar"></s>
</toggle-nav-bar-button>
</div>
</nav>
</nav-bar>

View File

@ -1,24 +1,67 @@
.nav {
.nav-bar {
--background: var(--dark);
--mobile-nav-height: 47px;
display: grid;
position: sticky;
top: 0;
overflow: hidden;
padding: 0 var(--space-small);
height: 82px;
padding: 0;
&--title {
grid-area: 1 / 1 / 3 / 2;
background: var(--background);
padding: var(--space-small);
box-shadow: var(--box-shadow);
grid-template-columns: auto minmax(0px, var(--width)) auto;
background: var(--background);
box-shadow: var(--box-shadow);
@media ($mobile-breakpoint) {
height: var(--mobile-nav-height);
margin-bottom: 65px;
}
&--content {
max-width: var(--width);
margin: 0 auto;
margin: 0;
display: grid;
grid-template-columns: auto 1fr auto;
grid-template-rows: auto auto;
grid-area: 1 / 2 / 2 / 3;
grid-template-columns: 155px 1fr auto;
}
&--brand {
position: relative;
grid-area: 1 / 1 / 2 / 2;
padding: 0;
transition: margin-top 0.2s ease-out;
@media ($mobile-breakpoint) {
width: 100px;
}
}
&__scrolled &--brand {
margin-top: -80px;
}
@media ($mobile-breakpoint) {
&__scrolled &--brand, &__open &--brand {
margin-top: -52px;
}
}
&--logo-wrapper {
width: 100%;
background: var(--dark);
position: absolute;
display: grid;
box-shadow: var(--box-shadow);
padding: var(--space-small);
transition: padding-bottom 0.2s ease-out;
}
&__scrolled &--logo-wrapper {
padding-bottom: 0;
box-shadow: none;
}
&--logo {
width: 100%;
}
&--menu {
@ -28,13 +71,10 @@
display: grid;
grid-template-columns: 1fr auto;
box-shadow: var(--box-shadow);
/* make the nav background full page width */
margin: 0 -50vw;
padding: 0 50vw;
@media ($mobile-breakpoint) {
position: absolute;
top: var(--mobile-nav-height);
width: 100%;
max-height: 0;
display: flex;
flex-direction: column;
@ -42,6 +82,10 @@
}
}
&__open &--menu {
max-height: 230px;
}
&--menu-section {
display: flex;
flex-direction: row;
@ -50,6 +94,10 @@
margin: 0;
@media ($mobile-breakpoint) {
flex-direction: column;
&:not(:last-child) {
border-bottom: 2px solid var(--primary-color);
}
}
}
@ -57,19 +105,26 @@
list-style: none;
flex-grow: 1;
display: flex;
}
&--menu-link {
flex-grow: 1;
padding: var(--space-large) var(--space-small);
display: flex;
justify-content: center;
align-items: center;
font-family: Knewave;
font-size: var(--fz-4);
color: var(--primary-color);
text-transform: uppercase;
text-align: center;
text-decoration: none;
@media ($mobile-breakpoint) {
padding: var(--space-small);
justify-content: start;
}
&:hover {
background: var(--primary-color);
color: var(--on-primary);
@ -77,50 +132,41 @@
}
&--toggle-button {
display: none;
cursor: pointer;
margin: 0 var(--space-small);
align-self: center;
grid-area: 1 / 3 / 2 / 4;
@media ($mobile-breakpoint) {
display: block;
}
}
&__open &--menu {
@media ($mobile-breakpoint) {
max-height: 100vh;
}
}
}
toggle-menu-button {
width: 34px;
height: 34px;
position: absolute;
top: 0;
right: 0;
display: none;
cursor: pointer;
.bar {
display: block;
background-color: #777;
width: 20px;
height: 2px;
border-radius: 100px;
position: absolute;
top: 18px;
right: 7px;
transition: all 0.5s;
&:first-child {
transform: translateY(-6px);
}
}
.nav__open & {
.bar {
transform: rotate(45deg);
display: block;
position: initial;
background-color: var(--primary-color);
width: 25px;
height: 3px;
transition: all 0.3s ease-out;
margin: 5px 0;
}
}
&__open &--toggle-button {
.bar {
opacity: 0;
&:first-child {
transform: rotate(-45deg);
opacity: 1;
transform: translateY(8px) rotate(-45deg);
}
&:last-child {
opacity: 1;
transform: translateY(-8px) rotate(45deg);
}
}
}
}
}

View File

@ -8,7 +8,7 @@
<link href="https://fonts.googleapis.com/css2?family=Knewave&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//brick.freetls.fastly.net/Montserrat:300">
<link rel="stylesheet" href="/style.css"/>
<script type="module" src="index.js"></script>
<script type="module" src="js/index.js"></script>
</head>
<body>
{% include "lib/nav.html" %}