The dropdown menu in the header region flickers (shows for a very short time) when navigating between pages. It does not happen on every page load but when it does it is quite visible.

As I've noticed this behaviour even at https://backdropcms.org, I'm wondering if it's something you have to live with, or if there's a way to stop it (apart from showing only the primary menu items in the menu).

Most helpful answers

A more complete workaround, that consists of three components - php, js and css:

1. in your theme's template.php:

function YOURTHEME_preprocess_page(&$variables) {

  $variables['html_attributes']['class'][] = 'no-jscript';

}

2. in your custom theme js file (like js/yourtheme.js):

(function ($) {

  Backdrop.behaviors.YOURTHEME = {

    attach: function (context, settings) {
      $('html').removeClass('no-jscript');
    }
  }
})(jQuery);

3. in your theme's css file

.no-jscript .menu-dropdown ul {
  display: none;
}
.no-jscript .menu-dropdown li.expanded:hover ul {
  display: block;
}

This hides the submenus with css while the javascript isn't executed yet.

Confirmed: setting the element ul.menu-dropdown li ul via CSS to display: none fixes the issue for me as well. (I've used the CSS Injector module.)

It looks like submenus show up briefly before being hidden by CSS or the Smart Menus javascript, perhaps. I wonder if there's a way to start submenus off as explicitly hidden from the beginning?

Comments

Olafski's picture

I've also seen the menu flickering on some Backdrop sites, not only on backdropcms.org but also on some of my own sites. No idea so far why it's happening.

For reference I add a link to a GIF screencast with the flickering. As you will see, the flickering is quite visible when I click the 2nd time on the "Showcase" link:

It looks like submenus show up briefly before being hidden by CSS or the Smart Menus javascript, perhaps. I wonder if there's a way to start submenus off as explicitly hidden from the beginning?

I can confirm that it only happens if CSS aggregation and compression is enabled.

It seems now that I've managed to fix it by placing the following style definition in the head section of page.tpl.php:

<style>ul.menu-dropdown li ul {display:none;}</style>
indigoxela's picture

Does this only happen on sites with lots of menu items, or is the item count unrelated?

@simonp or @Olafski

How many menu items do you have on the sites you see the flickering?

Olafski's picture

@indigoxela, depends what you consider "a lot of". I'd say, it happens also on sites with not so many menu items.

One example is a site with five top level menu items, of which three have a sub-menu with the following number of items: 4, 2, and 6

indigoxela's picture

I'd agree, that's not really "a lot of". So probably the menu item count is unrelated.

What else could it be?

Olafski's picture

Confirmed: setting the element ul.menu-dropdown li ul via CSS to display: none fixes the issue for me as well. (I've used the CSS Injector module.)

indigoxela's picture

A more complete workaround, that consists of three components - php, js and css:

1. in your theme's template.php:

function YOURTHEME_preprocess_page(&$variables) {

  $variables['html_attributes']['class'][] = 'no-jscript';

}

2. in your custom theme js file (like js/yourtheme.js):

(function ($) {

  Backdrop.behaviors.YOURTHEME = {

    attach: function (context, settings) {
      $('html').removeClass('no-jscript');
    }
  }
})(jQuery);

3. in your theme's css file

.no-jscript .menu-dropdown ul {
  display: none;
}
.no-jscript .menu-dropdown li.expanded:hover ul {
  display: block;
}

This hides the submenus with css while the javascript isn't executed yet.

Thank you for your reply, @indigoxela. I've tested your code under the Thesis theme and I can confirm that it works. For some reason, though, it breaks the positioning of the submenu element, which can be corrected in css:

.js .menu-dropdown ul {top: 3.4em;}

(The original value was 1em.)

indigoxela's picture

Yes, sure, I should have noted that my example is the minimal setup needed, but probably (depends on the theme in use) it needs more tweaks.

Many thanks for the supplement.

Olafski's picture

setting the element ul.menu-dropdown li ul via CSS to display: none fixes the issue

Interestingly, there is already a CSS definition in the library styles (.sm ul { display: none; }), which should do the same. I don't understand why it doesn't lead to the same result.

indigoxela's picture

I don't understand why it doesn't lead to the same result.

I can explain that: it doesn't work because the "sm" class gets set via js.

core/modules/system/js/menus.js:

$(element).addClass('sm').smartmenus(settings);

So it won't work when the js execution is slow for whatever reason.

It works when setting the class via php, which is already done when the rendered page (html) is sent to the browser.

@Olafski, thanks for the follow-up and also for recommending the CSS Injector module.