My website has fixed header and a mobile burger menu. On desktop, the layout looks fine, but when I open the site on a mobile device (or refresh the page in responsive mode), the burger menu seems to "jump" or flash for a split second before snapping into their correct positions.
It looks like a Flash of Unstyled Content (FOUC), where the browser is rendering the desktop layout (flexbox) before the media query kicks in to position things for mobile.
My Setup:
HTML: Standard header with a logo, desktop nav-links, and a burger div.
CSS: I'm using display: flex with justify-content: space-between for the header. On mobile (max-width: 768px), I hide the nav-links and show the burger.
JS: A simple script that toggles a .nav-active class on the menu when the burger is clicked.
The Problem:
The burger menu is part of the flex flow on desktop (hidden). On mobile, when it becomes display: block, it fights for space with the logo and the hidden nav-links for a millisecond, causing the header elements to shuffle/jump.
What I've tried:
Moving the script to the bottom of the body.
Using DOMContentLoaded listeners in JS.
Adding transition: transform to the menu.
const navSlide = () => {
const burger = document.querySelector('.burger');
const socialLinks = document.querySelector('.social-links');
// Toggle menu on burger click
burger.addEventListener('click', (e) => {
e.stopPropagation();
socialLinks.classList.toggle('nav-active');
});
// Close menu when clicking anywhere on the page
document.addEventListener('click', (e) => {
if (socialLinks.classList.contains('nav-active') && !socialLinks.contains(e.target)) {
socialLinks.classList.remove('nav-active');
}
});
// Prevent clicks inside the menu from closing it
socialLinks.addEventListener('click', (e) => {
e.stopPropagation();
});
}
navSlide();
/* Stack to one column on mobile */
@media screen and (max-width: 768px) {
.info-grid {
grid-template-columns: 1fr;
gap: 1.5rem;
}
}
.burger {
display: none;
cursor: pointer;
width: 25px;
flex-shrink: 0;
}
/* Burger Menu Icon UI*/
.burger div {
width: 100%;
height: 3px;
background-color: #f5f5f5;
margin: 5px 0;
}
.burger:hover div {
background-color: #ccc;
}
@media screen and (max-width: 768px) {
body {
overflow-x: hidden;
}
.nav-links {
display: flex;
justify-content: center;
gap: 2.5rem;
margin: 0 auto;
padding: 10px 0 10px 5rem;
height: 39px;
align-items: center;
}
/* Social links popup for mobile*/
.social-links {
position: absolute;
right: 5px;
height: 19vh;
top: 11vh;
background-color: #1f1f1f;
display: flex;
flex-direction: column;
align-items: center;
width: 13%;
padding: 10px;
transform: translateX(110%);
transition: transform 0.3s ease-in;
}
.burger {
display: block;
}
}
.nav-active {
transform: translateX(0%);
}
<nav>
<img class="logo" src="https://placehold.co/32x32/orange/black?text=LOGO">
<div class="burger">☰</div>
<div class="social-links"></div>
</nav>