How to Create a Child Theme in WordPress (Step-by-Step)
- 16 Sep 2025
- 0 Comments
Creating a child theme is the safest, cleanest way to customize a WordPress theme while keeping the ability to update the parent theme. In this step-by-step guide you’ll learn exactly what a child theme is, when to use it, how to build one (files + code), and best practices to avoid common pitfalls.
What is a child theme — and why use one?
A child theme inherits the templates and styles of a parent theme but lets you override only the parts you want to change. Benefits:
- Keep parent theme updates without losing customizations.
- Work modularly — change CSS, templates or functions in an isolated place.
- Revert easily: deactivate the child theme and the site falls back to the parent.
Use a child theme when you want persistent customizations beyond a few CSS tweaks (for small CSS changes you can also use Appearance → Customize → Additional CSS).
Quick overview: What you’ll create
A minimal child theme needs:
- A folder inside
wp-content/themes/
style.css
with a theme header (must includeTemplate:
)functions.php
to enqueue parent & child styles
Optionally add: screenshot.png
, template overrides (header.php
, single.php
), custom assets/
folder, inc/
files.
Step 1 — Create the child theme folder
In your WordPress installation:
wp-content/themes/
├─ parent-theme/ (e.g. twentytwentyone)
└─ my-child-theme/ (create this folder)
Name the child folder whatever you want, but the Template:
in style.css
(next step) must match the parent theme folder name exactly.
Step 2 — Add the child style.css
(required)
Create wp-content/themes/my-child-theme/style.css
and include the header block. Replace values to match your project:
/*
Theme Name: My Child Theme
Theme URI: https://example.com/my-child-theme
Author: Your Name
Author URI: https://example.com
Description: Child theme of Parent Theme — customizations here
Version: 1.0.0
Template: parent-theme /* <-- folder name of the parent theme */
Text Domain: my-child-theme
*/
Important: the Template:
field must exactly match the parent theme’s folder name (case-sensitive on some filesystems).
Step 3 — Add functions.php
and enqueue the parent & child styles
Don’t use @import
inside the child style.css
. Instead enqueue styles properly.
Create wp-content/themes/my-child-theme/functions.php
:
<?php
/**
* Child theme enqueue — loads parent style then child style
*/
add_action( 'wp_enqueue_scripts', 'cv_child_enqueue_styles' );
function cv_child_enqueue_styles() {
$parent_handle = 'parent-style'; // handle for the parent style
// Enqueue parent style
wp_enqueue_style( $parent_handle, get_template_directory_uri() . '/style.css', array(), wp_get_theme( get_template() )->get( 'Version' ) );
// Enqueue child style, make it depend on parent style
wp_enqueue_style( 'child-style',
get_stylesheet_uri(),
array( $parent_handle ),
// use filemtime for cache busting in development:
filemtime( get_stylesheet_directory() . '/style.css' )
);
}
Notes:
get_template_directory_uri()
gets the parent theme URL.get_stylesheet_uri()
points to the child theme’sstyle.css
.- Using
filemtime()
is handy during development for automatic cache busting. For production, consider using version numbers.
Step 4 — Activate the child theme
- Log in to WordPress admin → Appearance → Themes.
- You should see My Child Theme. Click Activate.
The site will now use the child theme. If you did not override templates, the appearance is identical to the parent theme (unless you add CSS).
Step 5 — Add custom CSS to the child style.css
Add your style overrides below the header block:
/* Child theme custom styles */
.site-header { background: #0e6fbf; }
.entry-title { font-size: 1.8rem; }
Because the child style is enqueued after the parent, your rules will take precedence (unless specificity or !important
conflicts exist).
Step 6 — Override parent template files (PHP)
To change a template file (e.g., header.php
, single.php
, content.php
):
- Copy the file from the parent theme folder into your child theme folder keeping the same file-path.
- Example:
wp-content/themes/parent-theme/header.php
→wp-content/themes/my-child-theme/header.php
- Edit the copied file in the child theme.
WordPress will use the child file in preference to the parent file.
Important: only copy and override files you actually need to change. Copying everything prevents bugfixes/improvements in the parent from propagating.
Step 7 — Override parent functions & hooks (recommended approaches)
You cannot safely redeclare non-pluggable functions. Techniques:
- If parent uses
function_exists()
around a function, you can define that function in your child theme to override it (rare). - Preferred: remove_action() / remove_filter() then add your own callback.
- Or use actions/filters provided by the parent and change behavior via a hooked callback.
Example — removing a parent action and replacing it:
// In child functions.php, after parent has added its actions (use priority)
add_action( 'after_setup_theme', 'mct_child_replace_parent_hooks', 20 );
function mct_child_replace_parent_hooks() {
// Remove parent action (must know the parent callback)
remove_action( 'wp_head', 'parent_theme_custom_meta' );
// Add child replacement
add_action( 'wp_head', 'mct_child_custom_meta' );
}
function mct_child_custom_meta() {
echo '<!-- child meta -->';
}
If the parent does not expose hooks you need, consider contributing a filter/action to the parent theme (pull request) or use other extensibility options.
Step 8 — Enqueue child scripts (JS) and assets
For scripts specific to the child theme:
add_action( 'wp_enqueue_scripts', 'mct_child_enqueue_scripts' );
function mct_child_enqueue_scripts() {
wp_enqueue_script( 'child-main', get_stylesheet_directory_uri() . '/assets/js/main.js', array( 'jquery' ), filemtime( get_stylesheet_directory() . '/assets/js/main.js' ), true );
}
Use get_stylesheet_directory_uri()
(child) for child assets and get_template_directory_uri()
(parent) for parent assets.
Step 9 — Internationalization (i18n) in child themes
Load a textdomain if your child theme includes translatable strings:
add_action( 'after_setup_theme', 'mct_child_setup' );
function mct_child_setup() {
load_child_theme_textdomain( 'my-child-theme', get_stylesheet_directory() . '/languages' );
}
Step 10 — Copying template parts & partials
If parent uses get_template_part( 'template-parts/content', 'single' );
, you can create the corresponding file inside child theme:
wp-content/themes/my-child-theme/template-parts/content-single.php
Best practices & tips
- Keep customizations minimal: Override only what you must.
- Use version control (Git) for your child theme.
- Prefer hooks/filters over copying large templates. Filters are more update-friendly.
- Avoid editing parent theme files. Always use a child theme or plugin for changes.
- For functionality, prefer a plugin if the change is not presentation-related (search, custom post types, business logic).
- Document customizations inside
readme.txt
in child theme root. - Use staging/local dev before deploying to production.
When not to use a child theme
- If you only need to change a few CSS rules → use Customizer → Additional CSS.
- If you need to add functionality (not templates/styles) → build a plugin.
- For Full Site Editing block themes, child theme behavior is different — block themes use
theme.json
and HTML templates. Child concepts still exist but check compatibility with your parent block theme.
Conclusion
A child theme is the standard best practice when customizing a WordPress theme. It provides a safe sandbox for styling and template changes while preserving your ability to receive parent theme updates. Start small (CSS tweaks) and move template overrides into the child theme as your needs grow. For functionality and business logic, keep code in plugins so your features aren’t tied to the theme.
If you’d like, I can:
- Generate a ready-to-upload child theme zip for any parent theme you specify.
- Provide a starter
assets/
structure (Sass, JS build scripts). - Walk through converting a specific parent template into a child override step-by-step.
No Comment Found Yet !