Responsive Navbar toggles automatically when resizing viewport

So, i have had this issue for a rather long time, i always come across this issue every time i make a navbar and i just never been able to find a solution to this... So, when i resize the viewport, the menu should be hidden and the hamburger button should appear, but when i resize, it shows the navbar for like 0.5 seconds and then it instantly closes. i am using interpolate-size: allow-keywards; to transition between height: 0; > height: auto; i am also using transition-behavior: allow-discrete; to allow discrete animations (display:none; > display:block;) and i am also using @starting-style. Here is my code i also add a video below to also show the issue.
Tim
CodePen
Untitled
...
14 Replies
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Still in need of help with this ๐Ÿ™‚
Chris Bolson
Chris Bolsonโ€ข3w ago
It shows the menu precisely because you are using allow-discrete. In the case of display, it applies it style once the tranistion has completed. As you have the menu-container set to display: flex on larger viewports, when you reduce the width to below 1000px (your breakpoint) it sets that to display: none but, due to the tranistion and the allow-discreet, this takes 0.5s to take effect. To resolove this, you could remove the transition-behaviour from the CSS and, as you are using JS to toggle the nav, you could extend this to apply it (the transition-behaviour )when you apply the "active" class, taking into account that the JS will need to wait that extra .5s before removing it when the nav is toggled closed. Alternatively, you could change your CSS to use display:grid and animate the grid-template-rows from 0fr to 1fr. This would require an extra wrapper around the ul to hide the overflow but it would achieve the same effect without added JS.
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Aah alright, thanks, and yeah, i am aware of the old grid-template-rows solution, that's what i used before interpolate-size: allow-keywords; existed, but i thought now that we have interpolate-size property i should be using that. But yeah alright, seems like there is no css only solution to the problem then, i wanted to avoid JS and the old grid-template-rows method, but seems like that is the only solution then. Thank you very much ๐Ÿ™‚ So, i solved it by doing this
const toggleMenu = document.querySelector(".toggleMenu")
const menu = document.querySelector(".menu-container")
const loginPanel = document.getElementById('login')
const navbar = document.querySelector('nav')
let toggled = 0

toggleMenu.addEventListener("click", event => {
menu.classList.toggle("active")
if(toggled === 0) {
menu.style.transitionBehavior = "allow-discrete"
toggled = 1
}else if(toggled === 1) {
setTimeout(() => {
menu.style.transitionBehavior = "normal"
toggled = 0
}, 500)
}
})


document.addEventListener('click', event => {
if (loginPanel.matches(':popover-open') &&
!loginPanel.contains(event.target) &&
!navbar.contains(event.target)) {
loginPanel.hidePopover()
}
})
const toggleMenu = document.querySelector(".toggleMenu")
const menu = document.querySelector(".menu-container")
const loginPanel = document.getElementById('login')
const navbar = document.querySelector('nav')
let toggled = 0

toggleMenu.addEventListener("click", event => {
menu.classList.toggle("active")
if(toggled === 0) {
menu.style.transitionBehavior = "allow-discrete"
toggled = 1
}else if(toggled === 1) {
setTimeout(() => {
menu.style.transitionBehavior = "normal"
toggled = 0
}, 500)
}
})


document.addEventListener('click', event => {
if (loginPanel.matches(':popover-open') &&
!loginPanel.contains(event.target) &&
!navbar.contains(event.target)) {
loginPanel.hidePopover()
}
})
Seems to be working perfectly fine ๐Ÿ™‚
แผ”ฯฯ‰ฯ‚
don't set a timeout you can watch for a transition end event instead
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Aaahh... Yeah that sounds familiar, i think i have seen it done before, but i don't remember how to do it, but i will look it up ๐Ÿ™‚ Thank you for the recommendation ! My JS experience is kinda low haha
แผ”ฯฯ‰ฯ‚
since you're learning, you should know the advantages and disadvantages advantages: - works regardless of the delay - the css controls when the js code will run - you need to implement what happens when the menu is toggled before the transition ends disadvantages: - the transition MUST exist for the event to trigger - if transitions aren't supported, then the code will never run
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Thanks ! ๐Ÿ™‚ and yeah, i'm not really learning js anymore, i only use the experience i already have hahaha, i decided a few years ago to put all my focus on css to always stay up to date ๐Ÿ™‚ but i appreciate the info very much ! ๐Ÿ™‚
แผ”ฯฯ‰ฯ‚
it's still a very important consideration and honestly, it's better to be informed than just doing what someone says without knowing the "why"
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Yeah, i agree to 100% on that, but yeah the reason for this decision is because i dont write code because i want to find a job, i write code because i love it and have no interest finding a web dev job, so therefore i focus on what i love to work with which is css ๐Ÿ™‚
แผ”ฯฯ‰ฯ‚
that's perfectly fine i also don't love fiddling with events
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Web dev jobs is just all about js and frameworks and tailwind nowdays which is why it does not interest me, i love writing css haha
แผ”ฯฯ‰ฯ‚
but, there's always the poo when you get a puppy, and you gotta deal with it tailwind ๐Ÿคข
Tok124 (CSS Nerd)
Tok124 (CSS Nerd)OPโ€ข3w ago
Yeah, indeed ๐Ÿ™‚
แผ”ฯฯ‰ฯ‚
and now you can go enjoy writing more css

Did you find this page helpful?