How to use wp_dequeue_style() for style enqueued in WP_Widget class

widget() method is called when widget is rendered, so the style you’re enqueuing are printed in the footer (header is already printed at that time).

Even if majority of browser can render styles linked from page body, that’s invalid HTML because, according to HTML standards, unlike scrypts, styles must be placed in page <head>. (Try to validate your markup, and you’ll see errors).

That’s also the reason why 'widgets_init' and 'wp_enqueue_scripts' can’t be used to remove the style: these hooks are fired before widget() method is called, and you can’t remove a style that is not added yet.

There are 2 solutions.

Solution 1

The first solution assumes you want to keep your approach, even if not HTML standards compliant: once style is printed to footer, users may use 'wp_footer' hook to dequeue the style.

Assuming style is added like:

public function widget( $args, $instance ) {
    wp_enqueue_style('fpw_styles_css');
}

can be removed with:

add_action('wp_footer', function() {
   wp_dequeue_style('fpw_styles_css');
});

Solution 2

If you want that your plugin doesn’t print invalid HTML, the solution is to use is_active_widget() to check if the widget is active and enqueue the style if so:

add_action( 'wp_enqueue_scripts', function() {
  if ( is_active_widget(false, false, $widgetid) ) {
      wp_enqueue_style('fpw_styles_css');
  }
}, 5); // used priority 5 to make possible dequeue using default 10 priority

Doing so, the style will be added inside <head>, and users will be able to dequeue the style using standard approach: wp_dequeue_style() hooked into 'wp_enqueue_scripts'.

The only problem is that is_active_widget() doesn’t check if the widget is actually printed to page, but only if any instance of the widget is configured in backend, in any sidebar. It means is possible that style will be added even if widget is not actually printed to page.

However, users can easily remove the style for specific pages, because conditional tags work fine when 'wp_enqueue_scripts' is fired. Example:

add_action( 'wp_enqueue_scripts', function() {
  if (! is_front_page()) { // allow widget style only in front page
      wp_dequeue_style('fpw_styles_css');
  }
});

Leave a Comment