Residual Styling

Knowledgebase Docs » UberMenu 3
USEFUL? 15
UberMenu 3

Residual styling occurs when the theme’s CSS styles override UberMenu’s styles. As a result, UberMenu may not work or look as intended. To resolve this, the styles from the theme must be removed, neutralized, or overridden – generally the simplest solution is either Manual Integration or using the Custom Style Prefix / Specificity Booster.

A quick way to test whether you have residual styling which will be resolved by manual integration is to view UberMenu in the Sandbox (click the link near the top of the Control Panel > View Menu in Sandbox, or from the Appearance > Menus page). If the Sandbox menu is working properly, but your replaced theme location menu is not, this indicates that a wrapper from the theme is the source of the interference

New! Residual Styling Detection Tool

Need help locating the source of residual styling from your theme and where to add your manual integration code? Check out the Residual Styling Detection / Manual Integration Tool (included since v3.2.3)

Understanding the issue

Example

As a very simple example, let’s say UberMenu has a style which makes your menu links red:

.ubermenu a{
  color: red;
}

But your theme has a style which makes all header links blue

#header a{
  color:blue;
}

Because the theme’s style has a higher specificity than UberMenu’s, the link will appear blue, even though UberMenu tells it to be red. Unfortunately, there’s nothing UberMenu can do to prevent theme styles from affecting the menu.

The more serious case is when the theme’s menu styles override the layout of UberMenu. For example, in a normal flyout menu, third level items will be hidden even while second level items are visible. If the CSS responsible for the hidden third level items overrides UberMenu’s CSS, the columns in the mega submenu will be hidden.

Why modular coding is important, and how modularly coded themes avoid this issue entirely

For most themes, residual styling isn’t an issue, and automatic integration works nicely. For some themes, which are less modularly coded, their styles will continue to affect the menu after UberMenu is integrated, requiring manual integration to avoid interference from the theme.

The WordPress menu system provides the wp_nav_menu() function, which all themes should be using. This function provides all the necessary parameters to ensure that the theme’s menu is entirely modular – meaning that the wp_nav_menu function produces all the menu markup, and when it is replaced, the theme’s CSS no longer targets the replacement menu.

Here’s an example of how a menu can be coded modularly vs non-modularly:

Target Output

Here’s what the result should look like on the site:

<nav class="primary-nav">
  <ul class="menu">
    <li class="menu-item"><a href="/home">Home</a></li>
    <li class="menu-item"><a href="/about">About</a></li>
  </ul>
</nav>

All menu styles will be based on the .primary-nav class. So there will be styles such as:

.primary-nav{
  background:#333;
}
.primary-nav .menu-item a{
  color:#eee;
}
A Modular Theme Menu System

Using the wp_nav_menu function alone, this can be achieved:

<?php wp_nav_menu( array(
  'container_class' => 'primary-nav',
  'container' => 'nav',
  'menu_class' => 'menu',
  'theme_location' => 'primary'
) ); ?>

This is all the PHP that is needed in the template to produce the desired output (above). The function includes parameters like container_class which will define the menu’s wrapper.

In this case, when UberMenu replaces the wp_nav_menu function automatically, we end up with:

<nav class="ubermenu">
  <ul class="ubermenu-nav">
    <li class="ubermenu-item"><a href="/home">Home</a></li>
    <li class="ubermenu-item"><a href="/about">About</a></li>
  </ul>
</nav>

The primary-nav class is no longer in the output, so the theme’s styles do not apply. This allows UberMenu to function without interference from the theme.

A Non-modular Theme Menu System

However, some themes choose to hard-code the wrapper and remove it from the function like this:

<nav class="primary-nav">
  <?php wp_nav_menu( array(
    'container' => false,
    'theme_location' => 'primary'
  ) ); ?>
</nav>

The container is hard-coded in the template. Note that when UberMenu is not present, this code produces identical output to the code shown in the modular system. But when UberMenu replaces the menu, we end up with:

<nav class="primary-nav">
  <nav class="ubermenu">
    <ul class="ubermenu-nav">
      <li class="ubermenu-item"><a href="/home">Home</a></li>
      <li class="ubermenu-item"><a href="/about">About</a></li>
    </ul>
  </nav>
</nav>

This is because UberMenu can only control the output of the wp_nav_menu() function – it can’t alter hard-coded markup in the theme template.

As a result, the styles based on .primary-nav will still be applied to UberMenu, and can break UberMenu’s functionality.

The solution

We need to stop the theme’s CSS from breaking UberMenu. To do this we have two options:

1. Eliminate the theme’s styles from applying to the menu by replacing the theme’s menu entirely via Manual Integration

or

2. Override the theme’s styles using the Custom Style Prefix / Specificity Booster

Manual integration is more commonly the preferred solution, but each case is different. See the pros and cons at the bottom of the Custom Style Prefix / Specificity Booster article.

In a case where there is residual styling from the theme after automatic integration, our recommended solution is generally to use Manual Integration. In any integration scenario, the goal is to replace the entire theme menu system with UberMenu. When the entire theme menu system is coded modularly and therefore encapsulated within the wp_nav_menu function, this can be done with Automatic Integration. When there is a hardcoded section of the menu to replace, it must be manually replaced within the theme template.

So in the non-modular example above, there are a few solutions. For reference, here’s the original header code:

<nav class="primary-nav">
  <?php wp_nav_menu( array(
    'container' => false,
    'theme_location' => 'primary'
  ) ); ?>
</nav>

Note that any changes should be made in a Child Theme

1. Remove the container from the markup

We could just delete the nav wrapper:


  <?php wp_nav_menu( array(
    'container' => false,
    'theme_location' => 'primary'
  ) ); ?>

This will eliminate the residual styling from the primary-nav class. Now we can use automatic integration.

2. Replace the entire system with UberMenu

Alternatively, we can just delete the entire theme menu system and use UberMenu’s PHP function:

<?php ubermenu( 'main' , array( 'theme_location' => 'primary' ) ); ?>

Again, residual styling is eliminated. Note that if we did not remove the hard-coded nav wrapper, this function would not do us any good.

3. Conditionally display UberMenu

Since we’re already editing a template file, it’s best to use as robust a solution as possible. This solution requires slightly more markup, but has the advantage of being able to enable and disable the UberMenu plugin to switch back to your theme’s menu.

In this case, we check to see if UberMenu is installed; if so, we call UberMenu, otherwise we use the theme’s menu:

<?php if( function_exists( 'ubermenu' ) ): ?>
  <?php ubermenu( 'main' , array( 'theme_location' => 'primary' ) ); ?>
<?php else: ?>
<nav class="primary-nav">
  <?php wp_nav_menu( array(
    'container' => false,
    'theme_location' => 'primary'
  ) ); ?>
</nav>
<?php endif; ?>

This is the most robust solution, and while any of the above will work, this is ideal.

For more information, please see Manual Integration

Other Notes

What about responsive menu systems?

Some themes use two menus, and as such they wrap them in a single container:

<nav class="nav-container">
  wp_nav_menu( array(
    'theme_location' => 'primary',
    'container_class' => 'primary-nav',
  ) );
  wp_nav_menu( array(
    'theme_location' => 'primary',
    'container_class' => 'primary-nav-responsive',
  ) );
</nav>

This is fine, but in such a case, the styles should still be dependent on .primary-nav and .primary-nav-responsive, rather than .nav-container, in order to keep the code modular.

Why doesn’t UberMenu use higher specificity selectors?

It might seem like the obvious thing to do is to increase the selector specificity of UberMenu’s styles. There are several reasons we don’t do this:

1. We can’t use IDs because IDs must be unique, and you can have multiple UberMenus.

2. The selectors are intended to be as simple as possible to make CSS customizations straightforward.

3. No matter how high you raise the specificity of a style, there’s no guarantee it will override a theme style anyway.

4. It is considered best practice, especially when developing for a modular system such as WordPress, to write style selectors using classes rather than IDs, to keep specificities as low as possible.

If you’d like to increase UberMenu’s specificity, you can use that by adding a prefix to the existing styles using the Custom Style Prefix / Specificity Booster