Themes are the presentation layer of a WordPress website. A well-coded theme should be completely replaceable. That is, you should be able to activate a different theme compatible with your content and still have a functioning website. No critical functionality should be dependent on a theme. Critical functionality should be added with plugins.
The previous paragraph describes the golden grail of WordPress development. The reality is messier. Ready-to-go mega-themes sold on sites like ThemeForest sacrifice this ideal for simplicity and speed of configuration. They bring along many problems, one of them being “theme lock-in”. Your website becomes dependent on the specific theme.
Other themes act as separate creation frameworks inside WordPress. The most obvious examples are page builders, like bricks builder or divi. They also introduce theme lock-in, but typically allow for more customization and can be good options in certain circumstances.
This section is concerned purely with what themes are and how they work. The canonical and up-to-date info on themes is available in the official WordPress Theme Handbook.
style.css
style.css is the first of 2 files required for a theme to even show up in the Themes tab of the admin panel. Contrary to its name, its primary purpose is not to define styles. It’s to define metadata about the theme. WordPress parses this file’s comments looking for things such as theme name, version, author, etc. This file needs to exist, but doesn’t need to have any content for the theme to work. Example structure:
/*
Theme Name: Twenty Twenty
Theme URI: https://wordpress.org/themes/twentytwenty/
Author: the WordPress team
Author URI: https://wordpress.org/
Description: Our default theme for 2020 is designed to take full advantage of...
Tags: blog, one-column, custom-background, custom-colors, custom-logo, custom-menu, editor-style
Version: 1.3
Requires at least: 5.0
Tested up to: 5.4
Requires PHP: 7.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: twentytwenty
*/Keep in mind, style.css is not automatically loaded on the frontend. If you want to use it to write CSS, you have to explicitly enqueue it. More information, along with descriptions of each property, is available in the official WordPress style.css documentation.
index.php (or index.html)
index.php (or index.html for a block theme) is the second of 2 files required for the theme to show up in the Themes tab. It’s the fallback template for every template hierarchy. You should make it work like a generic posts archive. index.html needs to be placed in the /templates/ directory for a block theme to work.
functions.php
functions.php is an optional, but extremely useful theme file. It’s loaded in wp-settings.php when loading the WordPress core into memory. You can put any php code in there, but you probably shouldn’t. Remember – presentation only.
Some of the most common use cases of the file are:
- Enqueuing scripts and styles.
- Registering features supported by the theme.
- Theme-specific customizations with hooks and filters.
- Defining custom helper functions/classes.
Theme Support
add_theme_support( $feature, $args ) is an important function that allows your theme to specify support for certain opt-in WordPress features. $feature is a pre-defined name of the feature and $args is an array with options required for some features.
The list of all features is long, but here are a couple of the most important ones (full list of features is available in the add_theme_support() documentation):
- align-wide (enables wide and full-width alignment for blocks)
- title-tag (enables plugins and themes to manage the <title> tag)
- post-thumbnails (enables featured images)
- html5
- automatic-feed-links
- post-formats
- custom-background
- custom-header
- custom-logo
What this function does is it adds the feature to a global $_wp_theme_features array. The feature name becomes the key and the $args array becomes the value. You should not interact with this array directly. To check theme support, the current_theme_supports() function is used. The core WordPress code is full of conditional checks with this function, i.e., if ( current_theme_support( ‘post-thumbnails’) ).