Child Themes
A child theme inherits from a parent theme and lets you override templates, styles, and functions without editing the parent — so the next parent update doesn’t blow away your changes. Required for any production WordPress site that customises a third-party theme.
style.css, functions, overrides, FSE
EXAMPLE
<?php
// 1) Directory layout
// wp-content/themes/
// parent-theme/ (the theme you bought / downloaded)
// parent-theme-child/ (your child theme)
// style.css
// functions.php
// screenshot.png (optional preview)
// templates/ (FSE overrides)
// parts/ (FSE template parts)
// 2) Minimum child theme — classic theme
// parent-theme-child/style.css
/*
Theme Name: Parent Child
Theme URI: https://example.com/parent-child
Description: Child theme of Parent
Author: Mara
Author URI: https://example.com
Template: parent-theme <-- exact directory name of the parent
Version: 1.0.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: parent-child
*/
// 3) functions.php — enqueue parent + child styles correctly
add_action( 'wp_enqueue_scripts', function () {
$theme = wp_get_theme();
$parent = $theme->parent();
// Parent stylesheet
wp_enqueue_style(
'parent-style',
get_template_directory_uri() . '/style.css',
array(),
$parent->get( 'Version' )
);
// Child stylesheet (depends on parent)
wp_enqueue_style(
'child-style',
get_stylesheet_uri(), // returns the CHILD theme's style.css
array( 'parent-style' ),
$theme->get( 'Version' )
);
} );
// IMPORTANT: child stylesheet declares 'parent-style' as a dependency so it loads AFTER.
// 4) Override a template — copy + customise
// Parent file: parent-theme/single.php
// Child file: parent-theme-child/single.php <-- WordPress picks the child's version
// Same for: page.php, archive.php, header.php, footer.php, sidebar.php, comments.php
// Including arbitrary template parts loaded via get_template_part()
// 5) Override a template part (more robust than copying the whole template)
// In the parent: get_template_part( 'template-parts/content', 'page' );
// Just create: parent-theme-child/template-parts/content-page.php — WordPress prefers child
// 6) Add a custom template (page template)
// parent-theme-child/templates/landing.php
<?php
/**
* Template Name: Custom landing
*/
get_header(); ?>
<main class="landing">
<?php while ( have_posts() ) : the_post(); the_content(); endwhile; ?>
</main>
<?php get_footer(); ?>
// Editors can now select 'Custom landing' from Page Attributes -> Template.
// 7) Override or extend functions.php
// • Child functions.php runs BEFORE parent functions.php
// • Parent functions still run UNLESS you remove/override their hooks
// Add a feature
add_action( 'after_setup_theme', function () {
add_theme_support( 'custom-units', array( 'rem' ) );
} );
// Remove a parent action
add_action( 'init', function () {
remove_action( 'wp_head', 'wp_generator' );
}, 11 );
// Replace a parent filter
add_filter( 'excerpt_length', function () { return 30; }, 20 ); // override parent's default
// 8) Override a pluggable function
// If the parent defines its function in a pluggable wrapper:
// if ( ! function_exists( 'parent_logo' ) ) { function parent_logo() { … } }
// In the child, define BEFORE the parent loads:
function parent_logo() { /* your version */ }
// 9) Add child-only scripts
add_action( 'wp_enqueue_scripts', function () {
$theme = wp_get_theme();
wp_enqueue_script(
'child-extras',
get_stylesheet_directory_uri() . '/assets/extras.js',
array( 'jquery' ),
$theme->get( 'Version' ),
array( 'in_footer' => true )
);
} );
// 10) Block themes (FSE — Full Site Editing) — child overrides
// Parent theme has templates/ as .html files. Child overrides by placing the same file.
//
// parent-theme/templates/single.html — parent
// parent-theme-child/templates/single.html — child (wins)
//
// theme.json overrides — duplicate the file and modify; WP merges parent + child
// parent-theme/theme.json
// parent-theme-child/theme.json
//
// Within theme.json, child values are MERGED into parent (deep merge for objects).
// 11) Useful helper functions
// get_template_directory() -> /path/to/parent-theme
// get_template_directory_uri() -> https://site/wp-content/themes/parent-theme
// get_stylesheet_directory() -> /path/to/parent-theme-child
// get_stylesheet_directory_uri() -> https://site/wp-content/themes/parent-theme-child
// get_stylesheet_uri() -> https://site/wp-content/themes/parent-theme-child/style.css
// 12) Translation files
// parent-theme-child/languages/parent-child-en_AU.po
// In functions.php:
add_action( 'after_setup_theme', function () {
load_child_theme_textdomain( 'parent-child', get_stylesheet_directory() . '/languages' );
} );
// 13) Workflow tips
// • Version your child theme — bump version on every release to bust cache
// • Use a child theme generator (Astra, Ocean, Generate) for a quick start
// • Keep customisations small + commented; large overrides hint that the parent isn't a good fit
// • Use Composer + autoloading for complex PHP logic — child themes are essentially packages
// 14) Common bugs
// • Forgot 'Template:' header in style.css — child theme appears broken
// • Used @import in style.css instead of wp_enqueue_style — slow + deprecated
// • Forgot dependency on parent-style — child CSS loads BEFORE parent, gets overridden
// • Template hierarchy not picking the child's file — file name mismatch (case-sensitive on Linux)
// • theme.json conflicts between parent + child — review with Site Editor preview
// • Child uses get_template_directory() for its own assets — that's the PARENT's path
// • Plugin loaded as a 'must-use' overrides child theme — order matters
// • Editing parent directly 'just for a quick fix' — next parent update wipes it
Why it matters
Always customise a third-party theme through a child theme — never edit the parent. Override templates by file name, enqueue parent and child stylesheets in the right order, and use FSE-style theme.json overrides for block themes. Future-you (and your update workflow) will thank present-you.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// Inherits parent's templates; override file by file. // style.css: Template: parent-theme-slugTry it Yourself »
Discussion
Loading…