11

I changed my WordPress site to use child themes, but the parent theme style has priority over any change I make on the child theme CSS. I can work around it using !important, however this is a patchy solution and the child themes should work as the site's first resource.

For example, in my site, the border that includes .wp-caption is the same color as the background using the !important tag, but won't work without it.

Does this have to do with the functions.php file?

This is the contents of my PHP file:

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
3
  • 1
    how are you adding your child theme's style.css?
    – Milo
    Feb 12, 2015 at 0:18
  • I am using the system that WordPress recomends in this post: codex.wordpress.org/Child_Themes
    – Dharkov
    Feb 12, 2015 at 1:06
  • it looks like your child theme stylesheet loads very early, are you enqueueing it or adding the link tag directly to header? it should be enqueued to appear after the parent stylesheet, so you can use the same CSS selectors to override the parent without !important or higher specificity. see rambillo's answer below.
    – Milo
    Feb 12, 2015 at 1:35

4 Answers 4

23

Try enqueuing your child theme's CSS like so:

// Queue parent style followed by child/customized style
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles', PHP_INT_MAX);

function theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/styles/child-style.css', array( 'parent-style' ) );
}

Notice a few things:

1) PHP_INT_MAX as priority so that this runs last

2) get_stylesheet_directory_uri() vs. get_template_directory_uri() which will point to the child theme's template folder instead of the parents.

I added a subfolder there, as well /styles/ because I keep my CSS in a subfolder of my theme normally.

3) followed by array( 'parent-style' ) to make the child CSS have the parent CSS as a dependency, which has the effect of putting the parent theme first in the head and the child theme CSS following it. Because of that, whatever also appears in the child theme that is already in the parent theme will overwrite the parent theme's version.

5
  • Thanks a lot, the new array works perfectly and it is also cleaner and more clear.
    – Dharkov
    Feb 13, 2015 at 17:36
  • still not working.. so weird. 40 minutes and 20 tutorials at least on teh twentysixteen theme. Cannot get styles to override. body, select { color: red !important; font-size:200% !important; } Mar 8, 2016 at 18:53
  • Go ahead and post a codepen, and we'll take a look.
    – rambillo
    Mar 10, 2016 at 6:02
  • 3
    The PHP_INT_MAX solved it in my case. It forces the child's css to be loaded after the parent's.
    – mefiX
    Oct 18, 2016 at 19:41
  • roberthuttinger did you ever solve this problem?
    – gjnave
    Apr 19, 2020 at 1:49
2

TLDR answer: first parameter of each wp_enqueue_style() should not be left as 'parent-style' and 'child-style'. They should be renamed to match the name of the parent theme and its child.

Problem

If you don't rename the parameters, you will get the child theme enqueued a second time can result in rules appearing twice in Firebug and changing values in the wrong one having no apparent effect, which may trick you into thinking your child rules don't override the parent.

The expectation

The Codex page on Child Themes correctly says that if you do nothing, the child CSS is linked automatically. It does, but only that. CSS workflow is a bit different: you want to override, not replace. It's logical (it works like the other theme files) but they could have had a note.

Solution

Rename the parameters. I do it like below to get (a little) more control, note that you should replace twentysixteen and twentysixteen-child with the names of your theme and child theme:

function theme_enqueue_scripts() {
    //FIRST
    wp_enqueue_style( 'twentysixteen-style', get_template_directory_uri() . '/style.css' );

    //...custom queueing of .js and .css for Javascript plugins and such here

    //LAST
    wp_enqueue_style( 'twentysixteen-child-style', get_stylesheet_directory_uri() . '/style.css', array( 'twentysixteen-style' ) );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_scripts' );

(Also note that you don't get control of the link order of some (all?) WP plugins in this action. They get linked after.)

Happy selector-hunting ;)

1
  • Seems to me that this is the correct answer because it's using correctly the Wordpress framework without forcing anything.
    – quasi
    Dec 8, 2019 at 13:09
0

You can use a more specific selector in your child theme's CSS so that it takes precedence.

So instead of:


.wp-caption {
     background: #2d2d2d !important;
}

Use:


.entry .wp-caption {
     background: #2d2d2d;
}

You'll also want to be sure to enqueue your child theme stylesheet in your functions.php file if you aren't already.

http://codex.wordpress.org/Function_Reference/wp_enqueue_style

0

The solution proposed by Rambillo didn't work for me. I did this, and now it's ok :

function my_theme_enqueue_styles() {
        wp_enqueue_style( 'name-child-style', get_stylesheet_directory_uri() . '/style.css' );
    }
    add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles', PHP_INT_MAX );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.