<div class="MobileNav" data-mobile-nav>
<div class="MobileNav-overlay" data-mobile-nav-overlay></div>
<div class="MobileNav-inner">
<div class="MobileNav-trigger" data-mobile-nav-trigger>
<div class="MobileNav-trigger-inner"></div>
</div>
<ul class="MobileNav-nav" data-mobile-nav-list>
<li class="MobileNav-item" data-mobile-nav-item="1">
<div class="MobileNav-item-title">
<a href="#">About</a>
</div>
</li>
<li class="MobileNav-item" data-mobile-nav-item="2">
<div class="MobileNav-item-title">
<a href="#">Products</a>
</div>
</li>
<li class="MobileNav-item" data-mobile-nav-item="3">
<div class="MobileNav-item-title">
<a href="#">Services</a>
</div>
</li>
<li class="MobileNav-item" data-mobile-nav-item="4">
<div class="MobileNav-item-title">
<a href="#">Work</a>
</div>
</li>
<li class="MobileNav-item" data-mobile-nav-item="5">
<div class="MobileNav-item-title">
<a href="#">Contact</a>
</div>
</li>
</ul>
</div>
</div>
<header class="Header" data-header>
<div class="Header-inner" data-header-nav>
<div class="logo">
<img src="https://i.imgur.com/F0k8l7N.png" alt="">
</div>
<nav class="Header-nav" data-nav>
<div class="Header-nav-item" data-nav-item="1">
<a href="#">About</a>
</div>
<div class="Header-nav-item" data-nav-item="2">
<a href="#">Products</a>
</div>
<div class="Header-nav-item" data-nav-item="3">
<a href="#">Services</a>
</div>
<div class="Header-nav-item" data-nav-item="4">
<a href="#">Work</a>
</div>
<div class="Header-nav-item" data-nav-item="5">
<a href="#">Contact</a>
</div>
</nav>
<button class="MobileNav-trigger" data-mobile-nav-trigger>
<div class="MobileNav-trigger-inner"></div>
</button>
</div>
</header>
<div class="container">
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?1);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?2);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?3);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?4);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?5);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?6);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?7);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?8);"></div>
<div class="card" style="background-image: url(https://picsum.photos/1920/1080?9);"></div>
</div>
$header-transition: 0.4s ease;
body {
align-items: center;
background: #524fae;
display: flex;
justify-content: center;
margin: 0;
padding-top: 150px;
width: 100vw;
}
.Header {
align-items: center;
background: white;
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
display: flex;
height: 100px;
justify-content: center;
position: fixed;
text-align: center;
top: 0;
width: 100%;
z-index: 10;
&.has-mobile-button {
.MobileNav-trigger {
display: flex;
}
}
&-inner {
display: flex;
justify-content: space-between;
transition: height $header-transition;
width: 80vw;
}
.logo {
align-self: center;
display: flex;
height: 80px;
margin-right: 60px;
width: 200px;
img {
height: 100%;
object-fit: contain;
width: 100%;
}
}
&-nav {
display: flex;
flex-wrap: wrap;
height: 0;
justify-content: space-between;
max-height: 105px;
max-width: 940px;
overflow: hidden;
width: 100%;
&-item {
align-items: center;
align-self: center;
color: darkblue;
display: flex;
flex-shrink: 0;
font-family: Lato, sans-serif;
font-size: 20px;
font-weight: bold;
height: 100%;
line-height: 32px;
margin: 0 40px;
transition: font-size $header-transition, padding $header-transition;
&:last-child {
margin-right: 0;
}
a {
color: black;
text-decoration: none;
}
&:hover {
color: darkblue !important;
}
}
&:hover {
.Header-nav-item {
color: rgba(darkblue, 0.5);
}
}
}
@media screen and (min-width: 481px) {
&-nav {
height: auto;
}
}
}
.container {
align-content: flex-start;
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-around;
width: 80vw;
.card {
aspect-ratio: 16 / 9;
background: white;
background-position: center;
background-size: cover;
border-radius: 20px;
flex-shrink: 0;
margin-bottom: 10%;
width: 100%;
}
}
.MobileNav {
height: calc(100% - 55px);
left: 0;
pointer-events: none;
position: fixed;
top: 70px;
width: 100%;
z-index: 9;
&-inner {
background: white;
display: flex;
flex-direction: column;
height: 100%;
max-width: 100%;
overflow-y: scroll;
position: absolute;
right: 0;
transform: translate(0, -105%);
transition: transform $header-transition, visibility $header-transition;
visibility: hidden;
width: 100%;
.Button {
letter-spacing: 1px;
line-height: 3.8;
margin: 20px -8px 20px;
width: 100%;
}
.MobileNav-trigger {
display: none;
position: absolute;
right: 38px;
top: 30px;
}
}
&-item {
color: navy;
display: none;
font-family: Lato, sans-serif;
font-size: 24px;
font-weight: bold;
margin: 26px 0;
transition: opacity 0.3s ease;
&.is-visible {
display: block;
}
&-title {
display: flex;
justify-content: space-between;
width: 100%;
a {
color: black;
flex-shrink: 0;
text-decoration: none;
}
span {
min-width: 32px;
position: relative;
width: 100%;
&::after {
border-left: 2px solid lightgray;
border-top: 2px solid lightgray;
content: "";
display: block;
height: 14px;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-75%) rotate(225deg);
transition: transform 0.2s ease;
width: 14px;
}
}
}
}
&-overlay {
height: 100%;
left: 0;
position: absolute;
top: 0;
transition: background $header-transition;
width: 100%;
}
&-trigger {
align-items: center;
align-self: center;
background: none;
border: none;
cursor: pointer;
display: none;
flex-shrink: 0;
height: 100%;
&-inner {
height: 12px;
position: relative;
width: 24px;
&::after {
background: #524fae;
content: "";
height: 2px;
left: 0;
position: absolute;
top: 0;
transform-origin: 0% 50%;
transition: transform 0.2s ease;
width: 100%;
}
&::before {
background: #524fae;
bottom: 0;
content: "";
height: 2px;
left: 0;
position: absolute;
transform-origin: 0% 50%;
transition: transform 0.2s ease;
width: 100%;
}
}
&.is-active {
.MobileNav-trigger-inner {
&::after {
transform: translateY(-4px) rotate(45deg);
}
&::before {
transform: translateY(3px) rotate(-45deg);
}
}
}
}
@media screen and (min-width: 481px) {
height: 100%;
top: 0;
z-index: 11;
&-inner {
padding-top: 90px;
transform: translate(100%, 0);
width: 375px;
.MobileNav-trigger {
display: block;
}
}
&-trigger {
display: none;
}
}
@media screen and (min-width: 871px) {
&-inner {
padding-top: 160px;
}
}
}
.is-mobilenav-open {
overflow-y: hidden;
.MobileNav {
pointer-events: all;
&-inner {
transform: translate(0, 0);
visibility: visible;
}
&-overlay {
background: rgba(0, 0, 0, 0.25);
}
}
}
View Compiled
function isOverflown({ clientWidth, clientHeight, scrollWidth, scrollHeight }) {
return scrollHeight > clientHeight || scrollWidth > clientWidth;
}
function isVisible(parent, child) {
return !(
(child.offsetLeft - parent.offsetLeft >= parent.offsetWidth)
|| (child.offsetTop - parent.offsetTop >= parent.offsetHeight)
);
}
function init() {
const page = document.querySelector('[data-main-page]');
const header = document.querySelector('[data-header]');
const topbar = document.querySelector('[data-topbar]');
const nav = header.querySelector('[data-nav]');
const navItems = nav.querySelectorAll('[data-nav-item]');
const mobileNavList = document.querySelector('[data-mobile-nav-list]');
const mobileNavItems = document.querySelectorAll('[data-mobile-nav-item]');
const mobileNavTriggers = document.querySelectorAll('[data-mobile-nav-trigger]');
const mobileNavOverlay = document.querySelector('[data-mobile-nav-overlay]');
const showMobileNavButton = () => {
const navHidden = getComputedStyle(nav, null).display === 'none';
if (navHidden) {
mobileNavItems.forEach((item) => {
item.classList.add('is-visible');
});
}
const resizeObserver = new window.ResizeObserver((entries) => {
for (const entry of entries) {
header.classList.toggle('has-mobile-button', isOverflown(nav));
navItems.forEach((item) => {
const navItems = Array.from(mobileNavItems);
const matchingNavItem = navItems.find(el => el.dataset.mobileNavItem === item.dataset.navItem);
matchingNavItem.classList.toggle('is-visible', !isVisible(nav, item));
});
}
});
resizeObserver.observe(nav);
};
mobileNavTriggers.forEach((trigger) => {
trigger.addEventListener('click', () => {
mobileNavTriggers.forEach((trigger) => trigger.classList.toggle('is-active'));
document.body.classList.toggle('is-mobilenav-open');
});
});
mobileNavOverlay.addEventListener('click', () => {
mobileNavTriggers.forEach((trigger) => {
trigger.classList.remove('is-active');
});
document.body.classList.remove('is-mobilenav-open');
});
showMobileNavButton();
}
init();