Flickering responsive nav menu on screen resize

So I'm working on a responsive nav menu, and it flickers on the resizing of the screen. See added video. It also does it when there is no JS. Codepen of a very simplified version of the nav (the same still happens): https://codepen.io/-evecodes/pen/GRYpKmW I tried following one of Kevin's nav tutorials for it. His navigation does work without the flickering, but when I try to make it, it fails. The tutorial was this one: https://www.youtube.com/watch?v=HbBMp6yUXO0 Any help/thoughts on how to possibly fix this are welcome!
Kevin Powell
YouTube
Responsive navbar tutorial using HTML CSS & JS
You can find the Frontend Mentor project here: https://www.frontendmentor.io/challenges/space-tourism-multipage-website-gRWj1URZ3 And the free Scrimba course here: https://scrimba.com/learn/spacetravel šŸ”— Links āœ… Why I use HSL: https://youtu.be/Ab9pHqhsfcc āœ… More on feature queries (@supports): https://youtu.be/wPI8CEoheSk āœ… More info on .sr-...
4 Replies
-eve
-eveā€¢14mo ago
Managed to fix it. I removed the translateX, and used the left/right/etc properties instead. Also added the transition on those.
.nav-items-box {
position: fixed;
overflow: hidden;
top: 0;
left: -60%;
right: auto;
bottom: 0;
flex-direction: column;
background-color: var(--main-color-90percent);
align-items: start;
z-index: 1500;
transition: left 250ms ease-out;
}

[data-nav-mobile="active"] {
left: 0;
}
.nav-items-box {
position: fixed;
overflow: hidden;
top: 0;
left: -60%;
right: auto;
bottom: 0;
flex-direction: column;
background-color: var(--main-color-90percent);
align-items: start;
z-index: 1500;
transition: left 250ms ease-out;
}

[data-nav-mobile="active"] {
left: 0;
}
Kevin Powell
Kevin Powellā€¢14mo ago
As a bit of a heads up, it's generally preferred to transition/animate transform rather than positioning properties for performance reasons. Worst case is to use JS to deactivate all transitions when the browser is being resized
-eve
-eveā€¢14mo ago
Ah, I didn't know that, thanks! I'll look into a JS based solution.
-eve
-eveā€¢14mo ago
So, I managed to make a JS solution to this problem as well. I noticed that the glitching only happened when my media query triggered so I focused towards that. I split the transition css seperate, and using data-attributes (with setAttribute) instead of classes, I added it to a JS media query (same width as my regular mq). This solved the issue in Chrome and Edge. Firefox was still being glitchy unless I resized my browser really really slow. The CSS added was: (before mq)
[data-nav-links-transition="off"] {
transition: none;
}
[data-nav-links-transition="off"] {
transition: none;
}
(mq)
[data-nav-links-transition="active"] {
transition: transform 250ms ease-out;
}
[data-nav-links-transition="active"] {
transition: transform 250ms ease-out;
}
For Firefox I had to add a setTimeout/clearTimeout, the timeout set to 0, this helped with the glitching here. Final JS code for the glitch fix:
const mediaQueryNavWidth = window.matchMedia('(min-width: 78.5em)');

function transitionToggle(mediaQueryNavWidth) {
if (mediaQueryNavWidth.matches){
clearQuickTimer()
NavItemsBox.setAttribute('data-nav-links-transition', 'off');
} else {
quickTimerSetAttribute();
}
}

function quickTimerSetAttribute() {
setTimeout( e=> {
NavItemsBox.setAttribute('data-nav-links-transition', 'active');
}, 0 );
}

function clearQuickTimer() {
clearTimeout(setTimeout);
}

transitionToggle(mediaQueryNavWidth);

mediaQueryNavWidth.addEventListener('change', transitionToggle);
const mediaQueryNavWidth = window.matchMedia('(min-width: 78.5em)');

function transitionToggle(mediaQueryNavWidth) {
if (mediaQueryNavWidth.matches){
clearQuickTimer()
NavItemsBox.setAttribute('data-nav-links-transition', 'off');
} else {
quickTimerSetAttribute();
}
}

function quickTimerSetAttribute() {
setTimeout( e=> {
NavItemsBox.setAttribute('data-nav-links-transition', 'active');
}, 0 );
}

function clearQuickTimer() {
clearTimeout(setTimeout);
}

transitionToggle(mediaQueryNavWidth);

mediaQueryNavWidth.addEventListener('change', transitionToggle);
Here's a codepen with the live code: https://codepen.io/-evecodes/pen/QWZyXEB In summary, my best guess for this glitching happening was that the added classes/attributes weren't acting fast enough when the media query triggered? From what I noticed the data-attributes were the fastest, but I read online that usually classes are? It's a bit of a headscratcher for sure haha.