How Child Themes Work with WordPress
No one theme can do everything you want.
Nor should it. Trying to be “one size fits all” actually makes a theme less useful. The more features that are built into a theme, the more complicated the interface gets, the slower the site runs, and the buggier the code becomes.
A child theme allows you to start with a well designed, stable theme that is not bloated with bells and whistles and then add the missing nuances yourself. A child theme lets you create the site you want by extending an existing WordPress theme with your own personal touch.
Most importantly, a child theme does not restrict you to the few custom options the theme provides. It becomes a blank canvas on which you can paint anything you want, and Child Theme Configurator makes it easier.
This tutorial explains five important concepts of WordPress child themes:
- The Terms “stylesheet” and “template” have specific meanings for WordPress themes.
- WordPress runs the active theme first. If the active theme is using another theme as a parent, WordPress then runs the parent theme (and the active theme officially becomes a “child” theme).
- Themes and plugins should use the “wp_enqueue_scripts” action so WordPress can control the order in which stylesheets and scripts are loaded.
- The Active theme’s “style.css” file should be loaded last, whether or not it is used by the theme.
- Some themes and plugins do not follow Concepts 3 and 4, but there are workarounds.
Concept 1: The Terms “stylesheet” and “template” Have Specific Meanings for WordPress Themes.
We normally use the term “stylesheet” to mean “a CSS file that defines how elements should be drawn by the browser.”
However, in the context of WordPress themes, “stylesheet” refers to the active theme’s directory name inside the theme root.
For example, if “Twenty Fifteen” is the active theme, the function get_stylesheet()
would return “twentyfifteen”. get_stylesheet()
always returns the active theme’s directory name inside the theme root whether or not the active theme is a child theme.
We usually use the term “template” to mean “a PHP file used to render output sent to the browser.” Often a single response is the combined result of several templates.
Unfortunately, in the context of WordPress themes, “template” refers to the theme used as a parent, or fallback theme. It is a specific “header” property used in a theme’s style.css
file. It is also what makes WordPress consider a theme to be a “child” theme.
The function get_template()
returns the parent theme’s directory name inside the theme root if the active theme is a child theme, but returns the active theme’s directory name otherwise.
Read more about confusing WordPress theme functions and “header” properties.
Why This Is Important:
- “Template” refers to the “parent” theme when describing a theme directory.
- “Stylesheet” refers to the “child” or “active” theme when describing a theme directory.
- For the purpose of this tutorial, only the terms “parent,” “child” or “active” are used to describe themes. The term “template” always refers to a PHP file used to render output to the browser, and “stylesheet” always refers to specific a CSS file.
Concept 2: WordPress runs the active theme first, then runs the parent theme.
WordPress first reads the active theme’s stylesheet (style.css
) to get the theme’s “header” properties. It then checks if the theme has a functions file (functions.php
) and executes it if it exists.
If the theme’s “header” properties indicate another theme should be used as a parent it then looks for a functions file in the parent theme and executes it as well.
This is the most important behavior of a WordPress child theme: two sets of functions are executed, first the Child, then the Parent.
Next, WordPress determines the “template” to use based on the nature of the web site request. Once it decides the type of output to render, it first checks the active theme directory for the most appropriate “template” file.
If it does not find it there, and the active theme is a child theme, it then checks the parent theme directory for an appropriate “template” file. Read more about how WordPress determines the most appropriate “template” file for the job.
WordPress begins to render the template file, executing instructions as it goes. Each time an additional template is required, WordPress checks the theme directories, first the child, then the parent, for the most appropriate match and runs it.
Throughout this process, WordPress fires various “actions” that branch off to other sections of code. The next section explains how actions are used with themes to control stylesheets and scripts.
Why This Is Important:
- WordPress will use the child version of a template if it exists. This means you can customize the child version without changing the parent version.
- WordPress will use the parent theme template if it does not exist in the child theme. This means you only need to create child theme templates you want to customize.
- The child theme runs first so you can “override” specific functions in the child theme functions file (assuming the parent functions are coded correctly, see Concept 5).
Concept 3: Themes and plugins should use the “wp_enqueue_scripts” action to load stylesheets.
WordPress was designed to be extended. One way it accomplishes this is through the WordPress Plugin API, using “actions.” An “action” is a queue (list) of functions to be run at a specific point in the WordPress program flow.Themes and Plugins can add functions to an action queue and they will be run in order of priority when when WordPress executes that particular action. By default, they will run in the order they were added to the queue.
The priority can be set to a specific value to place it higher or lower in the queue. This allows Themes and plugins to influence when a function runs in relation to other functions in the program flow.
The most important action when it comes to loading stylesheets and scripts is the “wp_enqueue_scripts” action. As WordPress runs, themes, plugins and other components add functions to this action so that they are all output to the browser in a controlled sequence at one time.
Using the wp_enqueue_scripts
action allows a child theme to override the default styles of the theme, thereby customizing the appearance. This is explained in more detail in the next section.
Some themes still hard-code stylesheet links into the template file. As a result WordPress cannot control the order stylesheets load which leads to other issues. This is discussed in more detail in Concept 5.
Why This Is Important:
- Using
wp_enqueue_scripts
to load stylesheets and scripts is recommended because it allows WordPress to optimize the load order and prevent conflicts. - This method also allows themes and plugins to influence how stylesheets and scripts load in relation to one another.
- Hard-coding stylesheet links in the header template causes stylesheets to load in the wrong order (see Concept 5)
Concept 4: The Active theme’s “style.css” file should be loaded last, whether or not it is used by the theme.
Some themes do not use the conventional style.css
file for their styles. Although this is perfectly acceptable, the theme should enqueue the active theme’s style.css
anyway to enable the styles to be customized by a child theme.
Even if a theme does not load the active style.css
file, Child Theme Configurator provides ways to make it work.
What does CSS Mean?
CSS is short for “Cascading Style Sheets”, a language that defines how elements are drawn on in the browser. As CSS is read from top-to-bottom, rules “cascade” down to the rules below them, in other words, rules that are defined later “inherit” the rules defined earlier.
This also applies to multiple stylesheets as well. For example, lets assume a web page uses two stylesheets. In the HTML, suppose they are loaded like this:
<link rel="stylesheet" src="/path/to/stylesheet1.css?x71836" />
<link rel="stylesheet" src="/path/to/stylesheet2.css?x71836" />
This means that the rules in stylesheet2.css inherit the rules in stylesheet1.css. In addition, rules in stylesheet2.css take priority, or “override,” rules in stylesheet1.css.
Therefore, the rules in stylesheet2.css are the “final word” for how elements are drawn, but any rules in stylesheet1.css will be used if they are not defined in stylesheet2.css.
CSS in WordPress
The example above is important because in order to be able to change the rules of a style, the changed rule must load after the style being changed. (Unless you use !important, you may be thinking.)Therefore, WordPress must be able to load first the parent styles, then the child styles, in that order, so that the CSS “cascades” correctly.
This can be accomplished several ways, but three are commonly used:
- The Child theme enqueues the Parent stylesheet, then the Parent theme enqueues the active (child) theme’s stylesheet. This is compatible with most themes, and is the default method used by Child Theme Configurator.
- The Parent theme enqueues the parent stylesheet if the active theme is a child theme, and then enqueues the active (child) theme’s stylesheet. As suggested by Justin Tadlock, this is the ideal solution, but is not used as often as it should.
- The Parent theme enqueues the active (child) theme’s stylesheet, which uses
@import
to load the parent stylesheet before loading the rest of the stylesheet. This method is no longer recommended.
Child Theme Configurator provides several options to handle loading the stylesheets.
Why is @import no longer recommended?
Some articles suggest that Google and other search engines penalize sites that use @import
to load stylesheets, and others claim that it impedes performance.
Whether or not this is true, WordPress cannot control the order stylesheets are loaded when a stylesheet imports another stylesheet. Any styles in the imported file immediately take priority over styles loaded before it and this may have unintended consequences.
However, because some themes still hard-code the stylesheet link in the template file, the only way to ensure the active stylesheet will be able to override the parent stylesheet is use @import
to import it via the active stylesheet.
For this reason, Child Theme Configurator provides option to use the older @import
method, but it should only be used if absolutely necessary.
Why This Is Important:
- Stylesheets inherit from and take priority over styles loaded before them by the browser.
- For a child theme to control the styles of a site, the active stylesheet must load after the other stylesheets.
- Child Theme Configurator provides several options for handling stylesheets depending on the way the theme is written.
Concept 5: Some themes and plugins do not follow Concepts 3 and 4, but there are workarounds.
WordPress has evolved quickly in the last several years, and methods that were common practice before have been replaced by newer, better practices. Themes that are listed in the theme repository on WordPress.org undergo a thorough vetting process and in our experience we see the most issues with “premium” themes. Even so, any theme can have issues, and Child Theme Configurator provides ways to work around common problems.These are the most common mistakes made by themes, in order of severity:
- Placing the
wp_head()
anywhere except just before the closing</head>
tag. (See wp_head() in the Codex.)
Linking stylesheets or scripts after thewp_head
action will almost always cause them to load in a way that no child theme or plugin can override them using actions. The only way to use a child theme in this scenario is to copy theheader.php
to the child theme using the Files tab and manually editing it so thewp_head()
function appears just before the</head>
tag. - Hard coding the stylesheet link in the template instead of using
wp_enqueue_scripts
in a theme function.
Because the linked stylesheets load before WordPress outputs the enqueued stylesheets, the child theme cannot link the parent styles ahead of the active stylesheet. This means the child stylesheet must import the parent stylesheets (using@import
) in order to override them.Using the @import option in CTC when creating a child theme will allow you to customize the main stylesheet, but you may still be unable to customize the other stylesheets.
Another solution is modify the template to link the parent stylesheet first. Copy the
header.php
template to the child theme using the Files tab and edit the line that loads the active stylesheet so that it loads the parent instead. In CTC, select the “Enqueue child stylesheet” option to enable the child theme styles. You can then create overrides for any of the stylesheets that are loaded by the parent theme.<link rel="stylesheet" href="<?php echo get_template_directory_uri() . '/style.css'; ?>" type="text/css" media="screen" />
Note: this is only suggested as a workaround for themes that already hard-code the stylesheet. Using the
wp_enqueue_scripts
method is always recommended. - Using
get_template()
orget_bloginfo('template_url')
instead ofget_stylesheet_uri()
to link the theme stylesheet.
Even if correctly enqueued, WordPress will never load the child theme stylesheet if used as a parent theme. Use the “Enqueue child stylesheet” option in CTC to enable the child theme styles. - Loading
style.css
before other stylesheets
Selecting the “Enqueue parent stylesheet” option in CTC will work, but you will not be able to customize any stylesheets that load afterstyle.css
. - Not loading
style.css
at all.
This is easily fixed by selecting the “Enqueue child stylesheet” option in CTC to enable the child theme styles. - Not wrapping functions in
if !(function_exists()))
This means the theme functions cannot be overridden by a child theme. This is not a major concern unless you plan to make significant changes to the PHP, in which case you should probably use a different theme. - Some themes will not work as parent themes without modifications.
- Child Theme Configurator provides workarounds for many common issues with child themes.
- WordPress Template Hierarchy (Codex)
- WordPress Child Themes (Codex)
- WordPress Plugin API (Codex)
- Justin Tadlock, Loading parent styles for child themes
Why This Is Important:
Resources