WordPress Child Themes
A WordPress child theme (sub-theme) is an additional theme that allows you to modify/add the features and appearance of the main theme. The main theme remains untouched, meaning it can be updated without fear of losing the changes made.
A child theme is a theme created based on a parent theme. "Based on" means that if the requested theme file is not available, it will be taken from the parent theme: the parent theme essentially backs up the child theme. From a technical standpoint, when creating a child theme, it becomes the main theme, while the parent theme becomes the supplementary theme.
Why is a child theme needed?
Child themes are needed so that theme developers can update/improve their themes, while users can update themes without losing their changes.
Therefore, if you are using a ready-made WordPress theme whose author is still developing it, do not edit the theme files directly; instead, create a child theme and modify the main theme through the child theme.
What can be changed in a child theme?
You can change almost everything in it, but you need to understand how things work (see below). However, to change certain things, the parent theme must be created with possible changes in mind. If the developer of the parent theme does not consider possible changes, then altering some aspects will be either difficult or impossible.
From this, we can conclude that there are good and bad parent themes. Often, only a few adjustments are needed: styles, changing the footer, and other minor details, and this can be done for any parent theme without significant problems.
There was a question about sub-themes, I recommend reading: How to make changes to the child theme templates?
Creating a Child Theme
Creating a sub-theme is easy! Below, a child theme for twentyfifteen
is created.
-
Create a folder with any name in the themes directory:
wp-content/themes
. Let's call ittwentyfifteen-child
. -
Create a file
style.css
in the new folder. With the content:/** * Theme Name: My Child Theme * Template: twentyfifteen * * Optional parameters: * Theme URI: http://example.com/ * Description: Child theme for the twentyfifteen theme * Author: Kama * Author URI: http://example.com/about/ * Version: 1.0 */ /* importing the parent theme styles */ @import url("../twentyfifteen/style.css"); /* Your additional styles */ .foo{ color:red; }
- Go to
Appearance › Themes
and activate the new theme "My Child Theme".
It is mandatory to specify the line Template: twentyfifteen
(the line is case-sensitive), it indicates that this is a child theme of the twentyfifteen theme.
The @import directive must be the first rule in style.css. If you write rules before it, it will not work and the styles of the parent theme will not be loaded.
The @import directive significantly slows down page loading, so it is better to connect styles differently.
As a result, we should have the following structure:
wp-content └── themes ├── twentyfifteen (parent theme) └── twentyfifteen-child (sub-theme; can have any name) └── style.css
twentyfifteen-child
can also contain other files, among them:
-
style.css — (mandatory) completely replaces the same file of the parent theme.
-
functions.php — supplements the functions.php of the parent theme (loaded before it).
-
template files — index.php, home.php, etc., which exist/do not exist in the parent theme. If a file exists in the child theme, it will completely replace the parent file. For example: by creating footer.php and copying the content of footer.php from the parent theme into it, we can change the output without modifying the parent theme file.
- other files — any other files/folders/anything. For example, the child theme can use new images that are included in additional CSS rules.
File style.css
style.css
is the only mandatory file in the child theme. It provides information to WordPress to identify the child theme.
The style.css
of the child theme completely replaces the style.css of the parent theme, i.e., the stylesheet file of the parent theme is not loaded at all.
In the information header, which must be at the beginning of the file, the mandatory parameter is Template:
. This is how WP understands that this is a child theme and what the parent theme is called.
Example of the style.css of the child theme.
/** * Theme Name: My Child Theme * Template: twentyfifteen * Theme URI: http://example.com/ * Description: Child theme for the twentyfifteen theme * Author: Kama * Author URI: http://example.com/about/ * Version: 1.0 */ // parent theme styles @import url("../twentyfifteen/style.css"); // additional styles .foo{ color:red; }
Theme Name
— (mandatory) the name of the child theme.-
Template
— (mandatory) case-sensitive name of the parent theme's folder.Note: when changing, you need to reset the setting, for this you need to switch to another theme and return back.
Theme URI
— the address of the child theme's website.Description
— the description of the child theme.Author URI
— the address of the child theme author's website.Author
— the name of the child theme author.Version
— the version of the child theme.
File functions.php
I recommend reading the article: the functions.php template file in WordPress.
Unlike other files in the child theme, functions.php does not replace the parent file but complements it: it is automatically loaded right before the parent theme's functions.php file.
That is, in the case of a child theme, both the child and parent theme's functions.php files are connected and work in PHP.
This means that to modify the parent theme, you can use hooks in functions.php and "override" functions if they are designed to be overridden in the parent theme's functions.php.
Using Hooks
In the footer.php file of the twentyfifteen theme, there is an event twentyfifteen_credits. To add your text to the footer, you can use this event, for this we will add the following code to the child theme's functions.php:
add_action( 'twentyfifteen_credits', function() { echo 'Company © 2015'; } );
Overriding a Function
In the functions.php file of the parent theme twentyfifteen, there is a function twentyfifteen_fonts_url() - registers Google fonts. It looks like this:
if( ! function_exists( 'twentyfifteen_fonts_url' ) ){ function twentyfifteen_fonts_url(){ // function code ... } }
The condition ! function_exists('twentyfifteen_fonts_url')
- if the function does not exist, allows you to define the same function in the child theme's functions.php.
In this case, only our defined function will be triggered, and not the function from the parent theme - it will not be registered in PHP due to the condition...
For example, by adding this code to the child theme's functions.php, we will disable the font loading:
function twentyfifteen_fonts_url() { return ''; }
Note for theme developers: allow the ability to override functions in child themes, for this, when creating a theme, wrap functions in a condition:
if( ! function_exists('theme_function') ){ function theme_function() { // Code. } }
In this case, the child theme can override the parent theme's function simply by declaring it in its functions.php.
Template Files
In the child theme, you can use all the same theme files as in any WP theme. For a complete list, read the article “Theme Template Hierarchy”.
A template file in the child theme, like style.css, replaces the file of the parent theme. That is, in the child theme, you can replace any parent file simply by creating a file with the same name.
A few examples of creating a template file in the child theme:
#1 Adding a template that is missing in the parent theme
Let's create a template for a page "sitemap". For this, in the child theme, we will create a file page-sitemap.php, and on the site, we will create a page with the slug sitemap. Done!
#2 Modifying a template that exists in the parent theme
Suppose we have home.php in the parent theme and we need to modify it.
-
Create home.php in the child theme.
-
Copy the code from the parent theme's file into it.
- Modify the copied code as needed.
How it works: step by step
The process of how a child theme works from the WordPress side:
-
WP opens the style.css of the theme set in the system settings and reads the headers.
-
The Template: directive declares that the theme has a parent theme and specifies its name. Now WP works with the theme as a child theme.
- Next, all files except functions.php are included using locate_template(): it checks whether the file exists in the child theme; if not, it is included from the parent theme.
The presence of a parent theme for the child theme is recorded in the site's option template
. For example, if the child theme has the option template=basetheme, then the theme basetheme will be the parent for the current theme.
This connection is established when the theme is activated.
Localization of Child Themes
For localization, WP will use the translation files of the parent theme. And of course, the necessary translation strings may not be there. Therefore, for the child theme, you need to create a translation file and include it in the child theme's code.
To include it, there is a special function: load_child_theme_textdomain(). We will use it in the child theme's functions.php:
add_action( 'after_setup_theme', 'my_child_theme_setup' ); function my_child_theme_setup() { load_child_theme_textdomain( 'my_child_theme', get_stylesheet_directory() . '/languages' ); }
Also, you need to create a translation file in the child theme: languages/en_US.mo
.
Now you can use localization functions of WordPress in the child theme:
_e( 'This needs to be translated into English.', 'my_child_theme' );
Thus, for the child theme, we will have separate translation files, while the parent will use its native files.
WordPress Functions Related to Child Themes
-
get_stylesheet_directory_uri() — gets the URL of the current theme (child, not parent).
-
get_template_directory_uri() — gets the URL of the current theme (parent, not child).
-
get_stylesheet_directory() — gets the path to the current theme (child, not parent).
-
get_template_directory() — gets the path to the current theme (parent, not child).
-
get_stylesheet() — gets the name of the current theme's directory (child, not parent).
-
get_template() — gets the name of the current theme's directory (parent, not child).
- get_stylesheet_uri() — gets the ready URL for the style.css file of the current theme. If a child theme is used, it will get the link to the styles of the child theme. In this case, there is no such function in WordPress for the parent theme.
That is, if you need to get a link to the theme file, but a child theme is being used, the URLs from get_stylesheet_directory_uri() and get_template_directory_uri() will differ: the first will be for the child theme, and the second for the parent theme...
Notes
Post Formats
The function add_theme_support( 'post-formats' ) will override the formats set by the parent theme, rather than supplement them.
@import in the child theme's style.css
Even though it is written everywhere to use @import in the child theme's style.css, I do not recommend doing this. Because in this case, the browser cannot load both stylesheet files (from the parent theme and the child theme) in parallel: it will have to load them sequentially: first the styles of the child theme, then it will see @import and only then will start loading the styles of the parent theme... As a result, we lose about 200ms in page loading speed. This is the time it takes to load the stylesheet file. By loading, I mean sending a request to the server, waiting for a response, and loading the file...
It is better to include stylesheet files separately in HTML: first the styles of the parent theme, and then the child theme, so they are lower in the HTML code and override the parent styles. This is done like this:
add_action('wp_enqueue_scripts', 'my_theme_styles' ); function my_theme_styles() { wp_enqueue_style('parent-theme-css', get_template_directory_uri() .'/style.css' ); // not mandatory, the correct parent theme will connect it itself. //wp_enqueue_style('child-theme-css', get_stylesheet_directory_uri() .'/style.css', array('parent-theme-css') ); }
As a result, in the HEAD part of the HTML document, we will get two links to two stylesheet files, which will be loaded in parallel, not sequentially. This will save us time on one request to the server from the browser.
For more about this type of loading, read the separate article: Alternative to @import in child themes