Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop Navigation flashes briefly on load before Mobile Navigation JS kicks in #58724

Closed
tomxygen opened this issue Feb 6, 2024 · 12 comments · Fixed by #59149
Closed

Desktop Navigation flashes briefly on load before Mobile Navigation JS kicks in #58724

tomxygen opened this issue Feb 6, 2024 · 12 comments · Fixed by #59149
Assignees
Labels
[Block] Navigation Affects the Navigation Block [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended

Comments

@tomxygen
Copy link

tomxygen commented Feb 6, 2024

Description

If the Gutenberg plugin is installed, when loading any page of a website on mobile, the mobile menu is briefly shown ad it is on desktop, and then collapsed in the hamburger menu.
See the attached screen recording.

Step-by-step reproduction instructions

  1. add a navigation menu
  2. open any page on mobile, the menu should look fine in its hamburger menu
  3. install the Gutenberg plugin
  4. reopen any page on mobile.

Screenshots, screen recording, code snippet

Screen.Recording.2024-02-06.at.12.39.07.PM.mov

Environment info

No response

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@tomxygen tomxygen added the [Type] Bug An existing feature does not function as intended label Feb 6, 2024
@t-hamano t-hamano added the [Block] Navigation Affects the Navigation Block label Feb 6, 2024
@jordesign jordesign added the Needs Testing Needs further testing to be confirmed. label Feb 6, 2024
@tomxygen
Copy link
Author

tomxygen commented Feb 9, 2024

@jordesign I saw the "needs testing" flag.
is there any way I can help with that?

@tomxygen
Copy link
Author

the issue is now present in WordPress 6.5 beta 1, even without the Gutenberg plugin installed.
cc. @jordesign @fabiankaegy

@fabiankaegy fabiankaegy changed the title if Gutenberg plugin is installed, mobile menu is briefly shown ad desktop Feb 16, 2024
@fabiankaegy
Copy link
Member

I am able to replicate this in Beta 1 also. Thaks for the ping!

You can see it happen if you enable network throteling. My assumption is that it happes because the JS only gets loaded initialized after the page loads here.

CleanShot.2024-02-16.at.08.49.50.mp4

Pinging some of the Interactivity API folks: @luisherranz @juanmaguitar @gziolo @DAreRodz @c4rl0sbr4v0 @michalczaplinski

@fabiankaegy fabiankaegy removed the Needs Testing Needs further testing to be confirmed. label Feb 16, 2024
@fabiankaegy
Copy link
Member

As far as I can tell the issue here is that the logic that determines whether the mobile menu should be shown now happens entirely in JS. It is invoked by the data-wp-init directive which calls this callback here:

initNav() {
const context = getContext();
const mediaQuery = window.matchMedia(
`(max-width: ${ NAVIGATION_MOBILE_COLLAPSE })`
);
// Run once to set the initial state.
context.isCollapsed = mediaQuery.matches;
function handleCollapse( event ) {
context.isCollapsed = event.matches;
}
// Run on resize to update the state.
mediaQuery.addEventListener( 'change', handleCollapse );
// Remove the listener when the component is unmounted.
return () => {
mediaQuery.removeEventListener( 'change', handleCollapse );
};

I don't think we can pre set the isCollapsed context on the server since we don't know the actual viewport there.

But I wonder if there isn't a way thtough a script in the head of the document to set the propper context not after the compoent renders but before it renders.

@DAreRodz
Copy link
Contributor

DAreRodz commented Feb 16, 2024

Thanks for the ping, @fabiankaegy. 😊

I'm also able to reproduce the issue. Regarding what you mentioned about setting the context in advance, it wouldn't work either because the context is consumed during the interactive blocks hydration. You would need to wait for the browser to download and execute the Interactivity API runtime to see the Navigation block collapse.

However, I guess all this logic could be implemented using only CSS... 🤔

Pinging @scruffian as he was involved in the implementation.

@cbravobernal
Copy link
Contributor

I can confirm that this error is not happening in 6.4.
I'm taking a look at it right now.

@cbravobernal
Copy link
Contributor

cbravobernal commented Feb 16, 2024

It seems that this issue is caused by this PR.
#57520

Should we revert it or try to set the context before it renders?

@fabiankaegy
Copy link
Member

@c4rl0sbr4v0 awesome find :) If we can revert that without too much hasstle I think we should. Unless anyone has an alternative fix for the issue that we can get tested and reployed in the next few days so that we can get it into 6.5 during the beta cycle :)

@DAreRodz
Copy link
Contributor

A potential fix would be to add the .is-collapsed class to the <nav> element with an inline script. Such script would have to compute the mediaQuery, locate the nav.wp-block-navigation element, and add the .is-collapsed class to it, so the visitor doesn't have to wait for the Interactivity API runtime to be downloaded and executed.

In this case, though, I feel returning to a CSS-only implementation would be more appropriate than using directives to add/remove the .is-collapsed class. 🤔

@cbravobernal
Copy link
Contributor

I feel returning to a CSS-only implementation would be more appropriate than using directives to add/remove the .is-collapsed class. 🤔

I've been investigating and it seems that people want the breakpoint to be an editable field. So for that case the CSS should be added in the render_callback rather than a file.

@huubl
Copy link
Contributor

huubl commented Feb 17, 2024

How about implementing something similar as the x-cloak directive in AlpineJS? This directive hides elements until the framework is fully loaded.

@cbirdsong
Copy link

Scripts can still fail to run for a lot of reasons even if they're inline. It would be best to handle as much of this as possible in CSS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Navigation Affects the Navigation Block [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended
8 participants