Reputation: 85
I'm trying to avoid use !important to override the WooCommerce styles. Right now I have enqueued WooCommerce styles and trying to queue them after my child template but nothing seems to work.
// Dequeue Woocommerce Style
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
// Dequeue Parent themes
function understrap_remove_scripts() {
wp_dequeue_style( 'understrap-styles' );
wp_deregister_style( 'understrap-styles' );
wp_dequeue_script( 'understrap-scripts' );
wp_deregister_script( 'understrap-scripts' );
// Removes the parent themes stylesheet and scripts from inc/enqueue.php
}
add_action( 'wp_enqueue_scripts', 'understrap_remove_scripts', 20 );
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
// Get the theme data
$the_theme = wp_get_theme();
wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
wp_enqueue_script( 'jquery');
wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'woocommerce_theme_styles' );
function woocommerce_theme_styles() {
wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');
}
Here's a live version of the web: http://ufctrashtalk.com
What am I doing wrong?
Thanks!!
Upvotes: 1
Views: 4261
Reputation:
To control the order in which .css files are loaded you just need to specify the $deps argument of wp_enqueue_style()
wp_enqueue_style( string $handle, string $src = '', array $deps = array(), string|bool|null $ver = false, string $media = 'all' )
The algorithm that WordPress uses to create the ordered list of .css files to use is very simple and is only 46 lines.
/**
* Determines dependencies.
*
* Recursively builds an array of items to process taking
* dependencies into account. Does NOT catch infinite loops.
*
* @since 2.1.0
* @since 2.6.0 Moved from `WP_Scripts`.
* @since 2.8.0 Added the `$group` parameter.
*
* @param mixed $handles Item handle and argument (string) or item handles and arguments (array of strings).
* @param bool $recursion Internal flag that function is calling itself.
* @param int|false $group Group level: (int) level, (false) no groups.
* @return bool True on success, false on failure.
*/
public function all_deps( $handles, $recursion = false, $group = false ) {
if ( !$handles = (array) $handles )
return false;
foreach ( $handles as $handle ) {
$handle_parts = explode('?', $handle);
$handle = $handle_parts[0];
$queued = in_array($handle, $this->to_do, true);
if ( in_array($handle, $this->done, true) ) // Already done
continue;
$moved = $this->set_group( $handle, $recursion, $group );
$new_group = $this->groups[ $handle ];
if ( $queued && !$moved ) // already queued and in the right group
continue;
$keep_going = true;
if ( !isset($this->registered[$handle]) )
$keep_going = false; // Item doesn't exist.
elseif ( $this->registered[$handle]->deps && array_diff($this->registered[$handle]->deps, array_keys($this->registered)) )
$keep_going = false; // Item requires dependencies that don't exist.
elseif ( $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $new_group ) )
$keep_going = false; // Item requires dependencies that don't exist.
if ( ! $keep_going ) { // Either item or its dependencies don't exist.
if ( $recursion )
return false; // Abort this branch.
else
continue; // We're at the top level. Move on to the next one.
}
if ( $queued ) // Already grabbed it and its dependencies.
continue;
if ( isset($handle_parts[1]) )
$this->args[$handle] = $handle_parts[1];
$this->to_do[] = $handle;
}
return true;
}
Removing all the error checking this simplifies to
public function all_deps( $handles, $recursion = false, $group = false ) {
foreach ( $handles as $handle ) {
$this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $new_group ) )
$this->to_do[] = $handle;
}
}
The ordered list is the array $this->to_do[]. To understand this observe that all_deps() is a recursive function and processes dependencies first
$this->all_deps( $this->registered[$handle]->deps, true, $new_group )
only after dependencies are processed does it add the item to $this->to_do[]
$this->to_do[] = $handle;
So, the order in which .css files are enqueued is not as important as the dependency relationship and you only need the dependency relationship to achieve the desired relative ordering of .css files.
As a last resort you can modify this $this->to_do[] array before WordPress uses it to send .css files using the filter 'print_styles_array'.
add_filter( 'print_styles_array', function( $todo) {
error_log( print_r( $todo, true ) );
return $todo;
} );
Here I am using it only to dump the $this-to_do[] array but you can modify it before returning.
Upvotes: 0
Reputation: 2960
You mentioned in your question that you're trying to override some WooCommerce css rules, but you just removed all WooCommerce stylesheets from loading with this line of code:
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
If you want to keep them into page, remove the line of code provided above.
Two ways to achieve your goal - load your stylesheet(s) after WooCommerce default ones. First of all, you don't need this part of code:
add_action( 'wp_enqueue_scripts', 'woocommerce_theme_styles' );
function woocommerce_theme_styles() {
wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');
}
Even by default, if you delete the function above, the WooCommerce will load it's files before Theme's one. It's coming from WordPress functions. First loading all plugins, and only after it Themes.
WooCommerce loading them by default, when the plugin is active. woocommerce.css
stylesheet may not be loaded, and instead of it load twenty-seventeen.css
, if the Theme of your site is Twenty Seventeen
.
Make the priority of your add_action()
higher:
add_action( 'some-hook', 'some_function', 20 );
Here 20 is priority. By default, it's 10. Increasing the priority will fire your function later, which mean that your .css
, .js
files will loaded in the DOM later( after all .css
, .js
files, which was called with default priority or lower of your ).
Your function will be:
//priority 20 is higer, then WooCommerce ones( 10 )
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles', 20 );
function theme_enqueue_styles() {
// Get the theme data
$the_theme = wp_get_theme();
wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
wp_enqueue_script( 'jquery');
wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
This will load your child-theme.min.css
file after all woocommerce files.
Use dependences for your wp_enqueue_style()
function. For ex., if you want to load your stylesheet only after woocommerce-smallscreen.css
stylesheet, use it's handler as dependence for your file:
wp_enqueue_style( 'some-handler', 'some-url-of-file', array('depends-on', 'another-dependence') );
So, you can just use on woocommerce-smallscreen.css
file using it's handler woocommerce-smallscreen
:
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
// Get the theme data
$the_theme = wp_get_theme();
//Here we use dependences
wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array('woocommerce-smallscreen'), $the_theme->get( 'Version' ) );
wp_enqueue_script( 'jquery');
wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
Note: If the file on which your stylesheet dependence not loaded( not exists, plugin not activated ), then your file will not loaded, too, because of broken dependences.
So, after one of steps your stylesheet will load after WooCommerce one's. But even after it you css rules will not override WooCommerce ones because you're using weaker rules, and WooCommerce use strongest ones. Ex.:
WooCommerce: .woocommerce a.button{}
Your's: .button.add_to_cart_button{}
Try to use this: .woocommerce a.button{}
and it will be overriden. You can also check this question.
Upvotes: 1
Reputation: 1661
Not sure why you de-queued WooCommerce styles, but this should solve your problem:
// Dequeue Woocommerce Style
// add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
// Dequeue Parent themes
function understrap_remove_scripts() {
// wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
// wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
// wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');
// Removes the parent themes stylesheet and scripts from inc/enqueue.php
wp_dequeue_style( 'understrap-styles' );
wp_deregister_style( 'understrap-styles' );
wp_dequeue_script( 'understrap-scripts' );
wp_deregister_script( 'understrap-scripts' );
// Get the theme data
$the_theme = wp_get_theme();
wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
wp_enqueue_script( 'jquery');
wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'ufctrashtalk_scripts' );
If it doesn't solve the issue, un-comment commented functions, which I doubt is necessary unless you have a reason.
Upvotes: 0