Versioning @import of parent theme’s style.css


I built a child theme based on Twenty Thirteen which works quite well. After updating the parent theme to version 1.3, I noticed strange behavior with the styling which was caused by a cached parent theme’s style.css.

Here is the content of my child theme’s style.css (omitting headers)

/* =Imports styles from the parent theme
-------------------------------------------------------------- */
@import url('../twentythirteen/style.css');

So the child theme’s style.css does nothing more than import the parent theme’s style.css.

I also have another css file with my child theme’s customizations which I enqueue like so in functions.php:

// Enqueue parent theme's style.css (faster than using @import in our style.css)
$themeVersion = wp_get_theme()->get('Version');

// Enqueue child theme customizations
wp_enqueue_style('child_main', get_stylesheet_directory_uri() . '/css/main.css',
    null, $themeVersion);

This gives me a very nice css url like this: that makes sure the style sheet is reloaded when the child theme is updated.

Now the problem

The statement @import url('../twentythirteen/style.css'); is completely independent of the underlying parent theme’s version. In fact, the parent theme can be updated without updating the child theme but browsers will still use cached versions of the old ../twentythirteen/style.css.

Relevant code in Twenty Thirteen that enqueues the style.css:

function twentythirteen_scripts_styles() {
    // ...

    // Add Genericons font, used in the main stylesheet.
    wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.03' );

    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
    // Note usage of get_stylesheet_uri() which actually enqueues child-theme/style.css

    // Loads the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentythirteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentythirteen-style' ), '2013-07-18' );
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

I can think of a few ways to solve this problem but none are really satisfactory:

  1. Update my child theme every time the parent theme is updated to change a version string in style.css (e.g. @import url('../twentythirteen/style.css?ver=NEW_VERSION');). This creates an unnecessary and annoying link between parent theme version and child.

  2. In my child’s functions.php, 1) wp_dequeue_style the included child theme’s style.css and 2) wp_enqueue_style the parent theme’s style.css directly WITH version string. This messes up the order of queued css in the parent theme.

  3. Use the style_loader_tag filter to modify the generated css <link> tag for style.css and modify the path to point directly to the parent theme’s style.css WITH a version string. Seems rather obscure for such a common need (cache busting).

  4. Dump the parent theme’s style.css in my child theme’s style.css. Same as (1) really, but a bit faster.

  5. Make my child theme’s style.css be a symlink to the parent theme’s style.css. This seems quite hackish…

Have I missed something? Any suggestions?


Added genericicons.css and ie.css style sheets in parent theme to clarify why I can’t change the @import css statement to wp_enqueue_style in my child theme. Currently, with an @import statement in my child theme’s style.css, I have this order in generated pages:

  1. twentythirteen/genericons/genericons.css -> enqueued by parent theme
  2. child-theme/style.css -> enqueued by parent theme, @imports twentythirteen/style.css
  3. twentythirteen/css/ie.css -> enqueued by parent theme
  4. child-theme/css/main.css -> enqueued by child theme

If I enqueue the parent’s style.css as a dependency of main.css, this will become:

  1. twentythirteen/genericons/genericons.css -> enqueued by parent theme
  2. child-theme/style.css -> empty, enqueued by parent theme
  3. twentythirteen/css/ie.css -> enqueued by parent theme
  4. twentythirteen/style.css -> enqueued by child theme as dependency of main.css
  5. child-theme/css/main.css -> enqueued by child theme

Note that ie.css is now included before the parent theme’s style.css. I do not want to change the enqueuing order of the parent theme’s css files because I cannot presume that this won’t cause problems with the priority of css rules.


You don’t have to use @import. It’s best not to, actually. Using an enqueued approach is probably better all around.

Here’s the relevant part of twentythirteen’s code:

function twentythirteen_scripts_styles() {
    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

Here’s what you do in your code:

function child_scripts_styles() {
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

If your main.css has to come after the parent’s style.css, then you just make it dependent on that.

Now, if you also have a B.css in the child, then you set up the dependencies accordingly:

function child_scripts_styles() {
    wp_enqueue_style( 'child-B-style', get_stylesheet_directory_uri().'/B.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('child-B-style'), 'YOUR_THEME_VERSION' );
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Make the dependencies that you define for each item actually reflective of what those dependencies really are. If main.css must come after B.css, then it depends on it. If B.css must come after the parent’s style.css, then B depends on that. The enqueue system will sort it out for you.

And if you’re not actually using the child’s style.css for anything, then you don’t have to enqueue it at all. It can be just a placeholder to hold your theme’s header information. Not using it? Don’t load it.

Also, what exactly are you doing that is so dependent on ordering here? CSS doesn’t care about load order in most situations. CSS is more dependent on specificity of the selectors. If you want to override something, you make your selector for it more specific. It can come first, or last, or anything in between, the more specific selector always wins.


Reading your comments and looking closer at the code, I see where the mistake is here. The twenty-thirteen code is enqueueing the “get_stylesheet_uri()”, which in a child theme case, would be your child theme’s style.css file, not the parent’s file. That’s why the @import works, and keeps the same ordering (which again, does not matter nearly as much as you think it does).

In that case, if you don’t want to use import, I would recommend enqueueing the parent’s style.css directly. Like so:

function child_scripts_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css', array() );
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Code in the child theme’s functions.php runs first, so your own wp_enqueue_scripts will run first, and this will enqueue the parent theme’s style.css, which the parent theme is not doing itself (because it’s actually enqueueing your child’s style.css). By not making it depend on anything, same as the parent, then it simply gets put in the output correctly. Note that the order of this file and the genericons.css does not matter, because the original “twentythirteen-style” does not have the genericons.css as a listed dependency.

Your own child’s style.css will load, and honestly, this is where you should put your changes for the child theme, not into a separate main.css. There’s nothing preventing you from putting your changes there, but there’s no real reason to have an extra css file.

Leave a Comment