WordPress CSS: Fixing Theme, Plugin and Builder Styles
A typical WordPress page pulls CSS from half a dozen places: the theme, a parent theme, the block editor, every active plugin, a page builder and a box of custom CSS someone pasted in years ago. That makes two problems common.
Pages carry stylesheets for features they do not use, and changes either vanish at the next update or refuse to show up at all. This guide shows how to find where each stylesheet comes from, where your own changes should live, how to stop plugins loading styles on every page, and how to deal with page builders and caching layers.
Where WordPress CSS comes from
Before changing anything, it helps to know the usual suspects. On a classic or block theme site you will typically find these:
| Source | How it appears in the page | Can you edit it? |
|---|---|---|
| Parent theme | <link> to /wp-content/themes/theme-name/style.css
or an assets folder | No: updates overwrite it |
| Child theme | <link> to /wp-content/themes/theme-name-child/style.css | Yes: this is where your code goes |
| Block editor styles | Handles such as wp-block-library and per-block stylesheets | Load behaviour can be changed |
| Global styles | An inline <style id="global-styles-inline-css"> built
from theme.json and the Site Editor | Through theme.json or the Styles
panel |
| Plugins | <link> tags from /wp-content/plugins/ | No, but you can control where they load |
| Page builders | Generated files such as per-post CSS in /wp-content/uploads/,
or inline blocks | Through the builder's settings |
| Additional CSS | An inline <style id="wp-custom-css"> on every page | Yes, in the Customizer or Site Editor |
WordPress prints each enqueued stylesheet with an id made of its handle plus -css.
A tag with id="contact-form-7-css" has the handle contact-form-7, which is
the name you need to control it from code.
The CSS Checker lists your stylesheets with their sizes, flags render-blocking and unused CSS, and reports validation errors. On WordPress, that list is really a list of plugins, theme parts and builder files, so the first job is to put a name against each one.
Finding which plugin or theme adds each stylesheet
From the page source
Open a page, view source and search for stylesheet. The folder in each address tells
you the owner: /themes/, /plugins/plugin-name/ or /uploads/ for
builder files. Note the handle from each id. Repeat on a few templates, because some plugins
only load on certain page types.
With Query Monitor
The free Query Monitor plugin adds a Styles panel to the admin bar that lists every enqueued stylesheet on the current page with its handle, source file, dependencies and version. It also shows which component registered it. Install it on a staging copy if you prefer not to run debugging tools on the live site.
In developer tools
The Network panel, filtered to CSS, shows each file's size and whether it arrived before first paint. The Coverage panel in Chrome shows how much of each file matched on the page. A contact form plugin stylesheet that is completely unused on your home page is an easy win.
Child themes: where your CSS belongs
Editing the parent theme's style.css works until the next theme update, which replaces
the file and wipes your changes. A child theme is a small theme that inherits everything from the parent
and holds only your changes, so updates leave it alone.
The minimum child theme
Create a folder such as /wp-content/themes/harbourview-child/ with a style.css
that names the parent folder in its Template line:
/*
Theme Name: Harbourview Child
Template: harbourview
Version: 1.0.0
*/
.site-header { border-bottom: 1px solid #e5e7eb; }
Then add a functions.php that loads the child stylesheet after the parent, with a version
taken from the file's modification time so browsers fetch the new copy whenever you save:
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'harbourview-child',
get_stylesheet_uri(),
array( 'harbourview-style' ),
filemtime( get_stylesheet_directory() . '/style.css' )
);
}, 20 );
Replace harbourview-style with the parent's real handle, which you found in the page
source. Listing it as a dependency guarantees your file loads after the parent's, so equal-strength selectors
in your file win. Some parent themes do not enqueue their own style.css and expect the child
to do it; check the parent's documentation, and avoid enqueueing the same file twice.
Block themes
In block themes, much of the design lives in theme.json and the Site Editor's Styles
panel rather than in a stylesheet. A child block theme can include its own theme.json that
overrides colours, typography and spacing from the parent. Use that first for design tokens; use a child
stylesheet for anything theme.json cannot express.
Additional CSS: fine for small things
The Additional CSS box in the Customizer or Site Editor is convenient, but its contents are printed inline in the head of every page and are tied to the active theme. A few lines are fine. Hundreds of lines belong in a child theme file, where they are cached by the browser and kept under version control.
The fix, step by step
Step 1
Map every stylesheet to its source
Run the CSS Checker on your home page, a post, a main service or product page and the contact page. Then view source or install Query Monitor on a staging copy and list every stylesheet handle, the theme or plugin that owns it, its size and the pages that genuinely need it. Use the Coverage panel in developer tools to confirm which files are unused on each template before deciding what to change.
Step 2
Move custom CSS into a child theme
Create
a child theme with a style.css naming the parent in its Template line and a
functions.php that enqueues the child stylesheet with the parent handle as a dependency
and a filemtime version. Move any edits made directly to parent theme files into it, along
with long blocks from Additional CSS, then activate the child theme on staging and compare every template
with the live site before switching over.
Step 3
Load plugin styles only where they are used
For each plugin whose stylesheet appears on pages that do not use it, first check its
settings or documentation for an option to load assets conditionally. If there is none, add a wp_dequeue_style()
call in your child theme on a wp_enqueue_scripts hook with a late priority, wrapped in a
condition such as is_page( 'contact' ). Test the pages where the plugin is still needed,
including forms, sliders and pop-ups.
Step 4
Trim block editor and WooCommerce styles
On classic themes, add a filter returning true for should_load_separate_core_block_assets
so WordPress loads styles only for blocks actually on the page, rather than the whole block library.
If the shop uses WooCommerce, keep its styles on shop, product, basket, checkout and account pages but
dequeue them elsewhere with a condition based on is_woocommerce(), is_cart(),
is_checkout() and is_account_page(). Leave them in place if a mini basket appears
in the header.
Step 5
Set page builder CSS to external files
In your page builder's settings, choose to output generated CSS as external files rather than inline blocks, so browsers can cache them between pages, and turn on any options that load widget styles only when those widgets are used. After changing global colours, fonts or layouts, use the builder's regenerate CSS tool so old files are replaced, then check a few pages to confirm spacing and typography still match the design.
Step 6
Use one optimisation plugin and clear every cache
Choose a single plugin to minify, combine, inline critical CSS or remove unused CSS, and switch those features off in any others, because two tools rewriting the same stylesheets cause broken layouts that are hard to trace. After every CSS change, clear the optimisation plugin cache, any server or host cache and your CDN, then check the page in a private window and run the CSS Checker again.
Stopping plugin CSS loading on every page
Many plugins enqueue their stylesheet on every front-end page because they cannot know in advance where you will use them. A form plugin used only on the contact page, a slider used only on the home page, and a gallery used on two posts can together add several files to every page on the site.
Check for a built-in option first
Some plugins let you turn off their CSS or load it only where their shortcode or block appears. Contact
Form 7, for example, supports a wpcf7_load_css filter to switch its stylesheet off completely,
which is useful if you style forms yourself. Built-in options survive plugin updates better than your
own code.
Dequeue conditionally from the child theme
<?php
add_action( 'wp_enqueue_scripts', function () {
// Contact form styles: only on the contact page
if ( ! is_page( 'contact' ) ) {
wp_dequeue_style( 'contact-form-7' );
}
// WooCommerce styles: only on shop-related pages
if ( function_exists( 'is_woocommerce' )
&& ! ( is_woocommerce() || is_cart() || is_checkout() || is_account_page() ) ) {
wp_dequeue_style( 'woocommerce-general' );
wp_dequeue_style( 'woocommerce-layout' );
wp_dequeue_style( 'woocommerce-smallscreen' );
}
}, 100 );
The late priority of 100 makes this run after plugins have enqueued their files. Use the handles you found on your own site; plugins change them occasionally, so recheck after major updates.
Plugins that manage this for you
Asset management plugins offer a per-page screen where you can unload stylesheets and scripts with
checkboxes. They are a reasonable choice if you are not comfortable editing functions.php.
Record what you unload, because those settings are easy to forget when something breaks months later.
Block editor, page builders and optimisation plugins
Block editor styles
Block themes load styles only for the blocks present on each page by default. Classic themes historically loaded the whole block library stylesheet on every page. You can change that in the child theme:
<?php
add_filter( 'should_load_separate_core_block_assets', '__return_true' );
If your site uses no blocks at all on the front end, for example it is built entirely with a page
builder, you may be tempted to dequeue wp-block-library altogether. Check first that no
widget areas, reusable content or plugin output use blocks, because they will lose their styling.
Page builders
Page builders generate CSS for each page from the settings you choose in their editors. The main options to review are whether that CSS is printed inline in each page or written to cached files, whether widget styles load only when those widgets are used, and whether the builder loads its own icon fonts and animation libraries on pages that do not need them. After a site-wide design change, run the builder's regenerate CSS tool, or pages can keep old generated styles.
Optimisation plugins
Caching and performance plugins can minify and combine CSS, inline critical CSS and generate trimmed per-page stylesheets. They are effective, and they are also the most common reason a WordPress CSS change "does not show", because the old optimised copy is still being served. Use one plugin for CSS optimisation, clear its cache after design changes, and test logged-in and logged-out views separately, since many of these features are disabled for logged-in users. For a deeper look at trimming, see Fixing unused CSS.
When a CSS change will not show up
Work through these in order; it is almost always one of them:
- Browser cache. Check in a private window. If you use a
filemtimeversion on your child stylesheet, this stops being a problem. - Optimisation plugin cache. Combined and minified files are rebuilt only when the cache is cleared.
- Server or host cache. Many managed hosts cache whole pages; clear it from the hosting panel.
- CDN. Purge the stylesheet or the whole zone.
- Load order. Your file loads before the rule it is meant to override. Add the right dependency handle to your enqueue call.
- Specificity. The theme or builder rule has a stronger selector or an inline style. Inspect the element; see Fixing CSS specificity conflicts.
- A syntax error above your rule. A missing brace in Additional CSS can disable everything after it. Paste the block into a validator.
1. Where should I put custom CSS in WordPress?
For a few lines, the Additional CSS box in the Customizer or Site Editor is fine. For anything larger or long-lived, use a child theme stylesheet, enqueued after the parent theme, because it survives theme updates, can be cached by browsers and can be kept in version control. Never edit the parent theme or plugin files directly, as updates replace them. In block themes, put colours, fonts and spacing in a child theme.json before writing extra CSS.
2. Why is my WordPress CSS not updating?
Usually a cache is still serving the old version. Check in a private browser window, then clear your optimisation plugin's cache, any server cache from your host and your CDN. If the change still does not appear, inspect the element: your rule may load before the rule it should override, or a theme or builder selector may be stronger. A syntax error such as a missing brace above your rule can also stop it being applied at all.
3. Do I need a child theme if I only use Additional CSS?
Not strictly. Additional CSS is stored in the database and is not overwritten by theme updates, so small tweaks there are safe. The drawbacks appear as it grows: it is printed inline on every page, it is tied to the active theme so switching themes leaves it behind, and it cannot be version-controlled easily. Once you have more than a screenful of rules, or you need PHP changes as well, a child theme is the better home.
4. How do I stop a plugin loading CSS on every page?
First look for a setting in the plugin to load its styles only where its block or shortcode is used, or to turn them off. If there is none, find its stylesheet handle from the id attribute in the page source, then call wp_dequeue_style with that handle from your child theme's functions.php on the wp_enqueue_scripts hook, inside a condition for the pages that do not need it. Test the pages where it is still needed afterwards.
5. Is it safe to remove wp-block-library CSS?
Only if nothing on the front end uses blocks. Removing it on a site built entirely with a page builder or classic templates can save a request, but widget areas, reusable content, plugin output and even some theme parts may rely on block styles. A safer first step for classic themes is to enable separate block asset loading, so WordPress includes styles only for the blocks each page actually uses. Test key templates carefully before removing it altogether.
6. Why does my site look broken after enabling CSS optimisation?
Optimisation plugins change how stylesheets load: combining them changes their order, deferring them can change what the first paint looks like, and removing unused CSS can drop styles for menus, forms and elements added by scripts. Turn features on one at a time and test after each. Most plugins let you exclude specific stylesheets or classes. If two plugins both optimise CSS, disable those features in one of them, as overlapping rewrites often break layouts.
7. Does Elementor or another page builder slow down my CSS?
Page builders add their own framework styles, generated CSS for each page, and sometimes icon fonts and animation libraries. On a simple site that can be more CSS than the design needs. Check the builder's performance settings: output generated CSS as external files, load widget styles only when used, and switch off icon libraries or animations you do not use. Regenerate the CSS after design changes. Whether it is worth replacing the builder depends on how much of the site depends on it.
The CSS Checker measures each stylesheet, flags render-blocking and unused CSS, reports W3C validation errors and scans for specificity issues and prefix gaps, so you can tell which theme and plugin files to deal with first.
Open CSS Checker Fixes โ