How to load a WordPress theme style the right way

How to organize WordPress theme code to facilitate child theming without taking any special consideration in the base theme.

When building a WordPress theme, it is essential to include a style.css file in the root. It is customary to include core styling rules in this file too. What’s more important is how to load it into your templates. WordPress recommends the wp_enqueue_scripts hook and wp_enqueue_style() method and using these are great, but there is still some room for trouble.

Consider the following fragment for a theme MyTheme


add_action( 'wp_enqueue_scripts', function() {
	wp_enqueue_style( 'MyTheme', get_stylesheet_uri() );
} );

Now this works fine for a base theme, but what happens when I make a child theme called MyThemeChild? A quick crash course on WordPress theme references, in a base theme the template uri and stylesheet uri are the same, but in a base/child theme the template uri refers to the base theme and the stylesheet uri refers to the child. Because get_stylesheet_uri() implicitly uses the stylesheet uri the child theme’s stylesheet will be loaded and assigned the MyTheme handle.

This is bad. The child theme’s stylesheet is now attached to the base theme’s style handle (a plugin may specifically be interested in the base theme’s stylesheet) and now the base theme’s stylesheet isn’t loaded. This means that the child theme is now responsible for loading the base theme’s stylesheet. This can be corrected with some work. Following the example, this could be added to the child theme’s functions.php file.


add_action( 'wp_enqueue_scripts', function() {
	wp_dequeue_style( 'MyTheme' );
	wp_deregister_style( 'MyTheme' );
	wp_register_style( 'MyTheme', get_template_directory_uri() . '/style.css' );

	wp_enqueue_style( 'MyChildTheme', get_stylesheet_uri(), [ 'MyTheme' ] );
}, 11 ); // set to 11 to ensure being run after the base theme's hook which uses the default 10

Here we’ve restored the base theme’s stylesheet to its intended handle, and made it a dependency of our own child theme’s stylesheet. This is messy though; it’s pretty weird that the base theme loads the child theme’s stylesheet and the child theme loads the base theme’s stylesheet. and goes against the notion of child theme as an extension of the base theme. Let me show you a better way of loading base theme’s style to completely circumvent the issue.


/* Base Theme functions.php */
add_action( 'wp_enqueue_scripts', function() {
	wp_enqueue_style( 'MyTheme', get_template_directory_uri() . '/style.css' );
} );

/* Child Theme functions.php */
add_action( 'wp_enqueue_scripts', function() {
	wp_enqueue_style( 'MyChildTheme', get_stylesheet_uri(), [ 'MyTheme' ] );
} );

This is clean! There are no tangled concerns or necessary hook priority overrides to consider.

Note

I used get_stylesheet_uri() in the child theme code. This implicitly uses the stylesheet uri but this is ok in a child theme. WordPress doesn’t support chained themes as of the time of this writing so it is reasonable to expect that the child theme will never itself be a base theme – the child theme will always be the intended target of the stylesheet uri.