Skip to content
ExponaBLOG
WORDPRESS DEVELOPMENT & PLUGINS · DAY 029 / 100

Child themes: what every WordPress developer should know

Customize without losing updates.

Expona Admin6 min read

Child themes: what every WordPress developer should know

You've just pushed a custom feature to production—a modified archive template, adjusted styling, and a few new hooks. Two weeks later, the parent theme updates and your changes vanish. Child themes: what every WordPress developer should know represents the difference between sustainable customization and constant firefighting. When you understand how child themes work, you protect your code while staying current with parent theme improvements.

Why child themes — Parent updates do not overwrite your changes

The core problem is straightforward. When you modify files directly in a production theme folder, you're editing the parent theme itself. The next time that theme updates—whether automatically or manually—your changes get overwritten. You lose custom functionality, broken layouts, frustrated clients, and hours of debugging.

Child themes solve this by creating a separate theme that inherits from the parent. WordPress loads the child theme first, then falls back to the parent for anything not defined in the child. This inheritance model means you can customize almost everything without touching parent files.

Think of it like extending a class in object-oriented programming. The parent theme is your base; the child theme is your subclass. When WordPress looks for a template file or function, it checks the child first. If the file exists there, it uses it. If not, it uses the parent version. When the parent theme updates, only files in the parent directory update. Your child theme remains untouched.

Real example: you're working on an e-commerce site using the Storefront theme. The client wants custom product archive filtering. Rather than editing Storefront files directly, you create a child theme called Storefront Child. When Storefront updates next month with bug fixes or new features, your filtering logic stays intact because it lives in the child theme, not in Storefront's files.

style.css header — Template points to the parent

Every WordPress theme needs a style.css file with a header comment block. For a child theme, this header tells WordPress which theme is the parent.

Here's what a minimal child theme structure looks like:

php
/wp-content/themes/
  └── my-site-child/
      ├── style.css
      └── functions.php

And here's the required header comment in style.css:

php
/*
Theme Name: My Site Child
Theme URI: https://example.com
Description: Custom child theme for My Site
Author: Your Agency
Author URI: https://example.com
Template: my-site-parent
Version: 1.0.0
License: GPL v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: my-site-child
Domain Path: /languages
*/

The critical line is Template: my-site-parent. The value must match the exact parent theme's folder name, not its display name. If the parent theme folder is called storefront, you'd write Template: storefront. WordPress uses this line to establish the parent-child relationship.

You don't need to enqueue the parent's stylesheet manually—WordPress does that automatically. However, you should enqueue the child theme's stylesheet in functions.php to ensure proper cascade. Here's the standard approach:

php
get( 'Version' )
    );
}
add_action( 'wp_enqueue_scripts', 'my_site_child_enqueue_styles' );
?>

This function enqueues the parent stylesheet first, then the child stylesheet, with the parent registered as a dependency. This ensures CSS rules in the child theme cascade over the parent correctly.

Override templates — Copy files into the child theme

Child themes inherit all template files from the parent. To customize a template, copy it to your child theme directory, maintaining the exact same directory structure.

Example: the parent theme has wp-content/themes/my-site-parent/template-parts/header.php. To override it, create wp-content/themes/my-site-child/template-parts/header.php. WordPress now loads the child version instead.

This works for any template file in the parent's structure:

  • home.php, single.php, archive.php (top-level templates)
  • template-parts/ (partial templates)
  • inc/ or custom subdirectories (if the parent includes them via get_template_part())

Common override scenario: your client's site uses a parent theme with a generic footer that loads three widget areas. You want a custom footer with specific branding, email signup form, and social links. Copy footer.php from the parent into your child theme and modify it freely. Future parent updates won't touch your custom footer.

One important note: if the parent theme uses get_template_part() with the correct parameters, the child theme can override those partials. However, not all parent themes are built with extensibility in mind. Always check the parent's documentation and code to understand how it structures templates.

You can also override theme files like functions.php, but with a caveat: both the parent and child functions.php load. This means you're adding to the parent's functions, not replacing them. To avoid conflicts, either name your functions uniquely or use conditional checks before defining them.

Block themes — Child themes can override theme.json too

Modern WordPress block themes (like Twenty Twenty-Three or Twenty Twenty-Four) use a different architecture. Instead of PHP templates, they rely on block templates stored in JSON and controlled by theme.json for global styles and settings.

Child themes can override block-based templates and the theme.json file itself.

Structure for a block theme child:

php
/wp-content/themes/
  └── my-site-block-child/
      ├── style.css
      ├── functions.php
      ├── theme.json
      └── templates/
          ├── home.html
          ├── single.html
          └── parts/
              └── header.html

If you need to customize global styles, colors, typography, or spacing, copy the parent's theme.json into your child theme and edit it. WordPress merges child and parent theme.json settings intelligently, with child settings taking precedence.

For example, if your parent theme's theme.json defines brand colors, you can override them in the child's theme.json:

php
{
  "$schema": "https://schemas.wordpress.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "color": "#2563eb",
          "name": "Primary",
          "slug": "primary"
        }
      ]
    }
  }
}

Block templates are stored as HTML files in templates/ or templates/parts/. To override a parent block template, create the same file structure in your child theme. This allows you to customize block layouts without writing PHP.

Common mistakes

  • Wrong Template value: If WordPress doesn't recognize your child theme, double-check the Template: header. It must be the parent folder name, case-sensitive on many servers. Typos are the most common cause.
  • Forgetting to enqueue stylesheets: If your child theme's CSS doesn't load, you likely haven't enqueued it properly in functions.php. Never use @import in style.css to load the parent—use wp_enqueue_style() with proper dependencies.
  • Overriding without understanding parent code: Copying a template into the child theme means you now own it. If the parent updates that template with security fixes or new features, you won't get those improvements unless you manually merge them. Always review what you're overriding and stay aware of parent updates.
  • Breaking parent hooks: If the parent theme uses hooks for extensibility, using child theme to override templates might remove those hooks unintentionally. Consider whether using hooks in functions.php is a better approach than copying entire templates.
  • Modifying theme.json without understanding inheritance: Block theme theme.json files merge, not replace. If you're not careful about the structure, you might accidentally disable features or create conflicting settings.

Key takeaways

  • Child themes separate your customizations from parent theme files, so updates don't overwrite your changes.
  • The style.css header's Template: line establishes the parent relationship—it must match the parent folder name exactly.
  • Override any template file by copying it to the child theme with the same directory structure.
  • Enqueue stylesheets in functions.php, not in style.css, to ensure proper CSS cascade and parent-child dependency management.
  • Block themes use theme.json and HTML block templates; child themes can override both while maintaining the parent's updates elsewhere.
  • Only override what you need to customize—rely on parent hooks and functions when possible to minimize maintenance burden.
  • Document what you've overridden and why, so future you (or the next developer) understands the inheritance chain.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles