
Every WordPress theme begins with a comment block at the top of its style.css file. It looks like an ordinary CSS comment, but WordPress treats it as the theme's metadata record — the equivalent of a package manifest. This header is what populates the Appearance → Themes screen, drives the update checker, links a child theme to its parent, and tells translation tooling where to find string files. If you have ever wondered why a theme refuses to appear in the admin, or why an update notice keeps nagging you, the answer almost always lives in these few lines.
Here is a complete, realistic example for a parent theme:
/*
Theme Name: Harbor
Theme URI: https://example.com/themes/harbor
Author: Coastline Studio
Author URI: https://example.com
Description: A lightweight block theme for editorial sites.
Version: 2.4.1
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: harbor
Tags: blog, news, full-site-editing, block-styles, wide-blocks
*/
WordPress does not run a full CSS parser over style.css to find this data. It reads only the first 8 KB of the file and runs a set of regular expressions against it, one per known field. The function responsible is get_file_data() in wp-includes/functions.php, called from wp_get_theme(). Each field is matched with a pattern that looks for the exact label, a colon, and everything up to the end of the line.
Three consequences follow from this mechanism, and they trip people up constantly:
Theme Name, not theme-name or ThemeName. A typo means the field is silently ignored, not flagged.The header must be the first thing in the file. It does not strictly have to be a CSS comment for the parser — get_file_data() just reads bytes — but you should always wrap it in /* ... */ so the browser doesn't try to render the metadata as a style rule.
This is the single most misunderstood part of the format. Only Theme Name is genuinely required for WordPress to recognize and let you activate a theme. A folder under wp-content/themes/ containing a style.css with nothing but a Theme Name line (plus, for a classic theme, an index.php) will install and activate without complaint.
Everything else is optional from core's perspective, even though leaving fields out is a bad idea in practice. Do not believe any guide that tells you Author URI is mandatory — it is not. The confusion comes from the WordPress.org theme review requirements, which are a separate, much stricter gate. To be accepted into the public directory a theme must declare a GPL-compatible License and License URI, a valid Text Domain, a Tested up to value, and more. Those are submission rules, not parser rules.
Most header fields are purely informational — they decide what text shows in the admin. A handful, however, actually alter how WordPress behaves:
WordPress compares this string against the version advertised by the update source (WordPress.org, or a custom update server a premium theme registers). If the remote value is higher, you get an update prompt. The comparison uses version_compare(), so stick to semantic dotted numbers like 2.4.1. A non-numeric version can make the updater behave unpredictably.
Since WordPress 5.5, these are enforced, not advisory. If the server's PHP is older than Requires PHP, or the WordPress install is older than Requires at least, the Activate link is replaced with a disabled, greyed-out notice explaining the mismatch. This is genuinely useful: it stops a site owner from white-screening their site by activating a theme that calls PHP 8 syntax on a PHP 7.2 host.
This is the handle WordPress uses to load translation files (.mo/.l10n.php) for the theme. Every __() and _e() call in the theme should pass this exact string as its second argument. By convention it matches the theme's folder name. Get it wrong and translations silently fail to load while everything else keeps working — a maddening bug to chase.
A child theme's header carries one field a parent never needs: Template.
/*
Theme Name: Harbor Child
Template: harbor
Version: 1.0.0
Text Domain: harbor-child
*/
The Template value must be the exact directory name of the parent theme — harbor, the folder, not Harbor, the display name. WordPress uses it to set the template directory so that any template file the child doesn't provide falls through to the parent. If Template points at a folder that isn't installed, WordPress shows a "broken theme" error and refuses to activate the child. This is the number one reason a freshly built child theme won't turn on: a capitalization or hyphenation mismatch between Template and the parent's actual folder name.
One modern wrinkle: with classic themes the child needs a functions.php that enqueues the parent stylesheet. With block themes (full-site-editing themes), the loading model is different — style.css isn't automatically enqueued at all, and child themes inherit templates and theme.json settings through the block theme hierarchy instead. The Template field still does the parent-linking job, but the old "enqueue parent style" boilerplate is often unnecessary.
Block themes added theme.json, a structured file that defines color palettes, typography, spacing, and layout settings. It is tempting to assume it supersedes the style.css header. It does not. theme.json carries design configuration; the header still carries identity and metadata. WordPress reads them at different times for different purposes, and a block theme with no valid style.css header will not register, no matter how complete its theme.json is. Keep both, and keep the header accurate.
Theme Name is present and unique — it is the only field that can block activation outright.Version to a clean semantic string so the updater compares correctly.Requires PHP honestly to match the lowest PHP version your code supports; it protects users from fatal errors.Text Domain match your folder name and your __() calls exactly.Template matches the parent's folder name character for character.License, License URI, Tested up to, and directory-approved Tags before you upload.The header is small, but it is load-bearing. Treat it as the contract between your theme and WordPress: a few precise lines that decide whether your theme installs, updates, translates, and inherits the way you expect.
Site
Tools
We do not sell your email. We do not spam.
© 2026 RevealTheme. All rights reserved.