Opens in a new tab
  1. Home
  2. Guides
  3. Backend
Backend guide

WordPress block editor CSS, explained

Understand how CSS works in the modern WordPress Block Editor, including the editor iframe, content versus UI styles, enqueue hooks, editor styles and theme.json.

  • Updated August 19, 2026
  • 14 min read
  • WordPress guide

WordPress block editor CSS can mean several different things, and understanding the difference is essential before adding a stylesheet or choosing an enqueue hook. You may want to style the content being edited, change the Block Editor interface itself, make the editor resemble the frontend or add CSS that belongs to one specific block.

Those are not the same task.

This distinction has become even more important in modern WordPress because the Post Editor now runs inside an iframe. Starting with WordPress 7.1, the Post Editor is always iframed, which means the content canvas has its own document, separate from the surrounding WordPress administration interface.

If you are still deciding whether the Block Editor is appropriate for a particular project, see Block Editor vs. Classic Editor: Which Fits Your Site?. If you already use the Block Editor and simply need to understand why your CSS behaves differently inside it, this guide focuses specifically on that styling architecture.

We will cover the difference between editor content and editor UI styles, how enqueue_block_assets and enqueue_block_editor_assets differ, when to use add_editor_style(), where theme.json fits, how block-specific styles work and why CSS that once affected editor content may suddenly appear to do nothing.

What does “Block Editor CSS” actually mean?

When someone says they want to add CSS to the WordPress Block Editor, they may actually be describing several different goals.

For example, they may want to:

  • style blocks on the frontend;
  • make block content inside the editor resemble the frontend;
  • style only the editing interface;
  • add CSS for a custom block;
  • load the same stylesheet on the frontend and inside the editor;
  • change typography, colors or spacing available to editors;
  • add custom block style variations;
  • remove unnecessary WordPress block styles from the frontend.

Each of those tasks can involve a different WordPress API.

The first question therefore should not be “How do I add CSS to Gutenberg?” but:

Which part of the Block Editor am I trying to style?

If the problem is more general CSS sizing rather than WordPress itself, our px vs. em vs. rem: CSS Units Explained guide covers how relative and absolute CSS units behave in responsive interfaces.

The WordPress editor contains two different documents

The easiest way to understand modern Block Editor styling is to think of the editor as having two visual layers.

The first is the outer editor interface. This includes elements such as:

  • the top toolbar;
  • the block inserter;
  • the settings sidebar;
  • editor panels;
  • buttons and controls;
  • plugin interfaces.

The second is the content canvas, where the actual post or page content is rendered.

Starting with WordPress 7.1, the Post Editor content canvas is always rendered inside an iframe. WordPress documents this change in the official Iframed Editor Changes in WordPress 7.1 developer note.

An iframe creates a separate HTML document. That detail matters because CSS follows document boundaries.

A stylesheet loaded into the outer WordPress administration document does not automatically style elements inside the content iframe.

Likewise, a stylesheet loaded into the iframe does not normally affect the surrounding editor interface.

Why WordPress uses an iframe for the editor canvas

Separating editor content from the surrounding administration interface provides stronger style isolation.

Without that separation, wp-admin styles, plugin CSS and theme styles can interfere with one another much more easily.

An iframe also gives WordPress a more predictable environment for rendering block content and allows viewport-dependent CSS to respond to the dimensions of the editing canvas rather than always using the full browser window.

The transition happened progressively across WordPress editing environments. The Site Editor already relied heavily on an iframe-based canvas, while WordPress 7.1 completes the transition for the Post Editor.

If you are also working with Site Editing, see WordPress Full Site Editing and Block Widgets, Explained for the broader relationship between blocks, templates and modern WordPress editing.

Frontend CSS and editor CSS are different concerns

Suppose your theme contains frontend styles such as:

.article-title {
    font-size: 4rem;
    line-height: 1.1;
}

.article-content p {
    max-width: 70ch;
}

If that stylesheet is loaded only on the frontend, visitors will see those rules but editors may not.

If you want the editing canvas to resemble the published page, the relevant styles must also be made available to the editor content document.

There are several ways to do this depending on whether you are working with a theme, plugin or individual block.

Use enqueue_block_assets for block content styles

The WordPress enqueue_block_assets hook is intended for assets associated with block content.

A basic example looks like this:

add_action( 'enqueue_block_assets', function () {
    wp_enqueue_style(
        'my-block-styles',
        get_stylesheet_directory_uri() . '/assets/css/blocks.css',
        [],
        '1.0.0'
    );
} );

Assets enqueued through enqueue_block_assets can be loaded for block content on both the frontend and in the editor.

The official Enqueueing assets in the Editor documentation covers how WordPress handles editor and block assets.

If you need a broader explanation of WordPress frontend asset loading before diving into Block Editor-specific hooks, see wp_enqueue_scripts explained.

Example: styling a custom callout block

Imagine a custom block that renders:

<div class="my-callout">
    Important content
</div>

You might style it with:

.my-callout {
    padding: 1.5rem;
    border: 1px solid #ddd;
    border-radius: 8px;
}

If those rules describe the block itself, they usually belong with the content rather than with the surrounding editor interface.

The block should ideally remain recognizable both while editing and after publication.

What is enqueue_block_editor_assets for?

The similarly named enqueue_block_editor_assets hook has a different purpose.

It is intended for assets associated specifically with the Block Editor interface.

For example:

add_action( 'enqueue_block_editor_assets', function () {
    wp_enqueue_style(
        'my-editor-ui',
        plugin_dir_url( __FILE__ ) . 'editor-ui.css',
        [],
        '1.0.0'
    );
} );

This can be appropriate when a plugin needs to style:

  • its own sidebar panel;
  • toolbar controls;
  • custom inspector controls;
  • editor notices;
  • other interface elements outside the content canvas.

The important point is that enqueue_block_editor_assets is not simply an “editor version” of enqueue_block_assets.

enqueue_block_assets vs. enqueue_block_editor_assets

The names are similar enough to produce a completely predictable amount of developer confusion.

The practical distinction is:

  • enqueue_block_assets is for assets associated with block content and can affect both editor content and frontend rendering;
  • enqueue_block_editor_assets is for assets associated specifically with the editing interface.

If your CSS controls how a card, heading, button, gallery or custom block appears as content, think about block content assets.

If your CSS controls a plugin sidebar, toolbar or editor control, think about editor-interface assets.

The official WordPress Including Assets documentation explains the broader asset-loading model for themes.

Why enqueue_block_editor_assets may not style your content

This is one of the easiest mistakes to make with the iframed editor.

You might write:

add_action( 'enqueue_block_editor_assets', function () {
    wp_enqueue_style(
        'editor-custom',
        get_theme_file_uri( '/editor.css' )
    );
} );

and then:

.wp-block-heading {
    color: red;
}

Yet headings inside the content canvas remain unchanged.

The problem may not be the selector.

Your stylesheet can exist in the outer editor document while the heading exists inside the content iframe.

CSS does not cross that document boundary.

Use add_editor_style() for theme editor styles

Themes have an established mechanism for providing editor content styles through add_editor_style().

A typical configuration looks like:

add_action( 'after_setup_theme', function () {
    add_theme_support( 'editor-styles' );
    add_editor_style( 'editor-style.css' );
} );

The stylesheet might contain:

body {
    font-family: system-ui, sans-serif;
}

.wp-block-heading {
    font-weight: 800;
}

.wp-block-quote {
    border-left: 4px solid currentColor;
    padding-left: 1.5rem;
}

The WordPress Editor Styles documentation explains how themes can provide styles for editable content.

What is the purpose of editor styles?

The main goal is visual consistency between editing and publishing.

If the frontend uses:

  • a specific font family;
  • custom heading sizes;
  • particular content widths;
  • custom block spacing;
  • special list styles;
  • distinct blockquote styling;

showing similar characteristics inside the editor helps users understand what their content will look like when published.

If typography is the part you are trying to customize more broadly in wp-admin, see How to Change the WordPress Admin Font. That is a different styling context from content inside the editor iframe, which is precisely why distinguishing the two matters.

Do not blindly load the entire frontend stylesheet into the editor

Loading the complete frontend stylesheet inside the editor may seem like the easiest way to achieve visual parity.

Sometimes it works.

Sometimes it imports assumptions about headers, navigation, footers, modals, layout wrappers and JavaScript components that do not exist inside the editor.

For example:

body {
    overflow-x: hidden;
}

main {
    display: grid;
}

.site-header + main {
    padding-top: 120px;
}

Those rules may make perfect sense on the frontend but serve no useful purpose inside the content canvas.

A dedicated editor stylesheet or a shared content stylesheet is usually easier to reason about.

Share content CSS instead of duplicating everything

A useful architecture is to separate application-level layout styles from reusable content styles.

For example:

assets/css/
├── global.css
├── content.css
├── header.css
├── footer.css
└── editor.css

content.css might contain rules for actual post content:

.wp-block-heading { ... }
.wp-block-quote { ... }
.wp-block-table { ... }
.wp-block-button { ... }

Those styles can then be shared where appropriate, while layout-specific CSS remains frontend-only.

This also helps keep asset loading intentional. If you are deciding whether assets should live locally or behind a content delivery network, see CDN vs. Self-hosted Assets in WordPress.

Where does theme.json fit into Block Editor styling?

Modern WordPress themes can define much of their design system through theme.json.

The file can control or define settings related to:

  • color palettes;
  • font sizes;
  • typography;
  • spacing;
  • layout widths;
  • block-specific styles;
  • borders;
  • editor controls available to users.

The official Global Settings and Styles documentation explains the relationship between theme.json, editor settings and generated styles.

A simplified example might look like:

{
    "$schema": "https://schemas.wp.org/trunk/theme.json",
    "version": 3,
    "settings": {
        "color": {
            "palette": [
                {
                    "slug": "brand",
                    "color": "#2563eb",
                    "name": "Brand"
                }
            ]
        },
        "typography": {
            "fontSizes": [
                {
                    "slug": "large",
                    "size": "2rem",
                    "name": "Large"
                }
            ]
        }
    }
}

If your goal is specifically to change colors exposed by the editor rather than write arbitrary CSS selectors, see Customizing the WordPress Block Editor Theme Color.

theme.json and CSS are not mutually exclusive

Using theme.json does not mean that ordinary CSS becomes obsolete.

The systems overlap, but they are not identical.

theme.json is particularly useful for design tokens, defaults, global styles and editor capabilities.

CSS remains useful for:

  • complex selectors;
  • interactive states;
  • pseudo-elements;
  • advanced layouts;
  • custom components;
  • visual behavior that cannot be expressed conveniently through theme configuration.

A modern theme may therefore use all of the following together:

theme.json
style.css
editor-style.css
block-specific stylesheets

Block-specific CSS can be better than one enormous stylesheet

For themes or plugins containing many blocks, loading one large stylesheet everywhere can become inefficient and difficult to maintain.

WordPress allows assets to be associated directly with individual blocks.

For custom blocks registered through block.json, metadata properties can define frontend and editor styles.

For example:

{
    "apiVersion": 3,
    "name": "example/card",
    "title": "Card",
    "style": "file:./style-index.css",
    "editorStyle": "file:./index.css"
}

The official block.json metadata documentation describes the available metadata fields.

The WordPress Use styles and stylesheets guide provides additional examples of block-specific CSS.

style and editorStyle solve different problems

For a block registered with metadata, the general distinction is:

  • style contains styles associated with the rendered block;
  • editorStyle contains additional styling intended specifically for editing.

The editor-only stylesheet can be useful when the editing experience needs visual helpers that visitors should never see.

What should go into editor-only CSS?

Editor-only CSS should usually solve editor-specific usability problems.

Examples include:

  • making an otherwise invisible editing region easier to select;
  • adding an outline around a custom layout while editing;
  • styling block placeholders;
  • adjusting editor-only controls;
  • showing visual cues that should not appear on the frontend.

For example:

.editor-styles-wrapper .my-empty-layout {
    min-height: 120px;
    outline: 1px dashed #999;
}

The outline can help an editor understand the block structure without becoming part of the public design.

Block Styles are another separate concept

WordPress also has a Block Styles system that lets users choose alternative visual variations for a block.

A block might offer styles such as:

  • Default;
  • Outline;
  • Rounded;
  • Compact.

Selecting one generally adds a class to the block wrapper, which CSS can then target.

The official Block Styles documentation explains how these variations work.

Block Styles should not be confused with generic editor CSS. They are an explicit user-selectable variation system.

Be careful with editor selectors

Older tutorials often target internal editor markup directly.

You may encounter selectors containing several nested WordPress component classes copied directly from browser developer tools.

Those selectors can be fragile because the Block Editor interface continues to evolve.

When possible, prefer:

  • documented APIs;
  • your own component classes;
  • block wrapper classes;
  • stable WordPress classes intended for styling.

What about .editor-styles-wrapper?

You may encounter CSS such as:

.editor-styles-wrapper h2 {
    font-size: 2.5rem;
}

.editor-styles-wrapper has traditionally been useful for scoping editor content styles so that they do not affect unrelated administration elements.

However, selector scope and stylesheet location are different concerns.

Adding .editor-styles-wrapper to a selector does not magically move the stylesheet into the content iframe.

If the CSS file exists in the wrong document, the selector still cannot reach the element.

Why CSS that worked before WordPress 7.1 may stop working

A plugin or theme may previously have relied on CSS loaded into the administration document affecting editor content under certain editor configurations.

Older WordPress versions did not always iframe the Post Editor in every situation.

WordPress 7.1 removes that ambiguity by always rendering the Post Editor content canvas inside an iframe.

The official WordPress 7.1 Field Guide identifies the enforced iframe-based Post Editor as an important developer-facing change.

This means theme and plugin code should no longer assume that editor content shares the same document as the surrounding wp-admin interface.

JavaScript has the same document-boundary problem

The iframe distinction is not limited to CSS.

Code such as:

document.querySelector( '.wp-block-post-title' );

runs against whichever document the JavaScript currently belongs to.

If the target element lives inside another iframe document, an ordinary selector against the outer document will not find it.

The official Working with JavaScript for the Block Editor documentation covers editor scripts and the Block Editor JavaScript environment.

How to check where your CSS was loaded

If a stylesheet appears to load successfully but does not affect the target element, browser developer tools can reveal the problem quickly.

Inspect the element and determine whether it exists:

  • in the top-level WordPress administration document; or
  • inside the editor iframe.

Then inspect which stylesheets are loaded in that same document.

If your stylesheet exists only in the outer page while the element lives inside the iframe, changing the selector will not solve the problem.

Do not use !important to solve an iframe problem

Suppose this rule does nothing:

.wp-block-heading {
    color: red;
}

Changing it to:

html body .editor-styles-wrapper .wp-block-heading {
    color: red !important;
}

still cannot style an element in another document if the stylesheet was never loaded there.

Before increasing specificity, check:

  1. which document contains the target element;
  2. which document contains your stylesheet;
  3. whether the selector actually matches;
  4. whether another rule overrides it.

Should plugins style editor content?

Yes, when the plugin introduces visual content that needs styling while editing.

A plugin that registers a custom block should normally ensure that the block remains understandable and usable in the editor.

However, plugins should avoid imposing broad global rules on unrelated content.

For example:

.editor-styles-wrapper * {
    font-family: Arial !important;
}

would be unnecessarily invasive for most plugins.

A plugin should normally scope its styles to the blocks and interfaces that it owns.

Should themes style the Block Editor?

Themes have a stronger reason to provide editor content styles because they determine the frontend appearance of the site.

A theme may want the editing canvas to reflect:

  • its typography;
  • content width;
  • color palette;
  • spacing system;
  • block appearance;
  • design tokens.

This can be achieved with a combination of theme.json, editor styles and block-specific CSS.

The exact combination depends on whether the project is a classic theme, block theme or hybrid theme.

Editor colors should usually come from a design system

If editors repeatedly need access to the same brand colors, hardcoding those values into random stylesheets is rarely the best long-term strategy.

Where appropriate, define the palette through theme.json so WordPress can expose those values consistently within supported editor controls.

Our Customizing the WordPress Block Editor Theme Color guide explores this particular part of editor customization in more detail.

Responsive CSS behaves differently inside the iframe

The iframe is also relevant to responsive design.

Because the content canvas has its own viewport context, CSS that responds to viewport dimensions can behave according to the editing canvas rather than simply using the full browser window.

If you are working with responsive values and breakpoints more broadly, px vs. em vs. rem: CSS Units Explained covers the implications of different CSS units.

What about styling the Site Editor?

The Site Editor and Post Editor share many Block Editor concepts, but their interfaces should not be treated as if they always have identical markup or context.

The Site Editor has used an iframe-based canvas for longer than the Post Editor.

This is another reason to prefer documented WordPress APIs over selectors that depend on the exact administration DOM present in one particular release.

For a broader introduction to this editing model, see WordPress Full Site Editing and Block Widgets, Explained.

What about frontend WordPress block CSS?

WordPress itself loads styles used by core blocks and the Global Styles system on the frontend.

Depending on the site, theme and blocks in use, some projects may decide that particular frontend block assets are unnecessary.

Removing them can reduce CSS delivered to visitors, but it should only be done after confirming that the site does not rely on those styles.

TheOneWP Remove Block Assets provides individual controls for disabling selected WordPress block CSS and related frontend assets instead of treating all block assets as one all-or-nothing setting.

Do you need Block Editor CSS if you disable Gutenberg?

Not necessarily.

Some WordPress installations deliberately use the Classic Editor globally or only for selected post types.

TheOneWP Disable Gutenberg can disable the Block Editor globally or for selected post types.

If you are considering that approach rather than styling the Block Editor, see How to Bring Back the Classic WordPress Editor.

You may also want to compare the workflows in Block Editor vs. Classic Editor: Which Fits Your Site?.

Does changing editors affect existing content?

The editor used to modify content and the format in which that content is stored are related but separate concerns.

Switching editors on an existing WordPress site should therefore be planned carefully, particularly when existing posts contain blocks or editor-specific markup.

For that specific issue, see Does Switching WordPress Editors Affect Your Content?.

A practical decision tree for Block Editor CSS

When deciding where a stylesheet belongs, start by identifying exactly what it needs to affect.

If the CSS styles content on both the frontend and in the editor

Consider block content asset mechanisms such as:

enqueue_block_assets

or block-specific styles registered with the block itself.

If the CSS styles theme content inside the editor

Consider:

add_editor_style()

alongside the theme’s theme.json configuration.

If the CSS styles Block Editor controls or plugin UI

Consider:

enqueue_block_editor_assets

and keep selectors scoped to the interface owned by your plugin.

If the CSS represents design-system settings

Consider whether those settings belong in:

theme.json

especially for colors, typography, spacing and editor customization options.

If the CSS belongs to one custom block

Keep the stylesheet associated with that block when possible instead of adding every rule to one global file.

Common Block Editor CSS mistakes

Most Block Editor CSS problems fall into a relatively small number of categories.

Loading the stylesheet into the wrong document

This is particularly important with WordPress 7.1 because the Post Editor is now always iframed.

Determine whether the target belongs to the editor interface or the content canvas before debugging selectors.

Using enqueue_block_editor_assets for content styles

The hook name sounds as though it should style anything inside the editor, but editor-interface assets and content assets are different things.

Assuming frontend CSS automatically appears in the editor

It does not necessarily do so unless you deliberately load or register those styles through an appropriate mechanism.

Loading the entire frontend application into the editor

The editor usually needs content presentation styles, not every header, footer, modal, navigation and application-layout rule on the site.

Targeting unstable editor internals

Selectors based on temporary component markup are more fragile than selectors based on documented APIs or classes that your own code controls.

Using excessive !important declarations

Specificity cannot solve a stylesheet loaded into the wrong document.

Confusing theme.json with a replacement for CSS

theme.json can control a substantial part of the editor design system, but ordinary CSS remains necessary for many kinds of presentation logic.

Example: theme with shared frontend and editor content styles

A theme might organize its files like this:

my-theme/
├── functions.php
├── style.css
├── theme.json
└── assets/
    └── css/
        ├── content.css
        └── editor.css

content.css contains reusable post-content styling.

editor.css contains additional adjustments needed only while editing.

The theme could register editor styles in functions.php:

add_action( 'after_setup_theme', function () {
    add_theme_support( 'editor-styles' );
    add_editor_style( 'assets/css/editor.css' );
} );

and enqueue shared content styles through:

add_action( 'enqueue_block_assets', function () {
    wp_enqueue_style(
        'theme-content',
        get_theme_file_uri( '/assets/css/content.css' ),
        [],
        wp_get_theme()->get( 'Version' )
    );
} );

If wp_enqueue_style(), dependencies and WordPress enqueue hooks are unfamiliar territory, start with wp_enqueue_scripts explained before building a more complex asset architecture.

Example: plugin with editor UI CSS

Imagine a plugin that adds a custom settings panel to the Block Editor sidebar.

The interface stylesheet could be loaded with:

add_action( 'enqueue_block_editor_assets', function () {
    wp_enqueue_style(
        'my-plugin-editor',
        plugin_dir_url( __FILE__ ) . 'assets/editor.css',
        [],
        '1.0.0'
    );
} );

The CSS can then target classes controlled by the plugin itself:

.my-plugin-panel {
    padding: 16px;
}

.my-plugin-panel__status {
    font-weight: 600;
}

This keeps plugin interface CSS separate from the styling of actual post content.

Example: plugin with content styles

If the same plugin instead introduces a visual block:

<div class="my-plugin-notice">
    Notice content
</div>

the block’s presentation might be:

.my-plugin-notice {
    padding: 1rem 1.25rem;
    border-radius: 6px;
}

Those styles belong with the content rather than being treated purely as editor-interface CSS.

Block Editor CSS and performance

Editor-only CSS generally matters more for maintainability and editing consistency than public page performance because visitors do not normally download editor-only assets.

Frontend block CSS is different.

If a site loads styles for components it never uses, those files become part of the public page payload.

Before removing anything, identify:

  • which stylesheets are actually loaded;
  • which blocks depend on them;
  • whether the active theme replaces their styling;
  • whether removing them changes frontend rendering.

Remove Block Assets exists for this more granular optimization workflow.

For broader asset-delivery decisions, CDN vs. Self-hosted Assets in WordPress explains another layer of WordPress CSS and JavaScript delivery.

Block Editor CSS debugging checklist

When a style does not work inside the Block Editor, check the problem in this order:

  1. Determine whether the target is editor UI or editor content.
  2. Check whether the target exists inside an iframe.
  3. Confirm that your stylesheet is loaded into the same document.
  4. Confirm that the stylesheet URL loads successfully.
  5. Check whether the selector actually matches the target.
  6. Inspect computed styles for competing declarations.
  7. Check whether WordPress or theme.json generates a competing rule.
  8. Only then consider increasing selector specificity.

Which Block Editor CSS method should you use?

There is no single correct “WordPress Block Editor CSS hook” because the phrase covers several different styling contexts.

A useful modern WordPress mental model is:

  • Block content: use block asset APIs such as enqueue_block_assets or block-specific styles.
  • Theme editor content: use editor styles and theme.json where appropriate.
  • Editor interface: use enqueue_block_editor_assets.
  • Design system: use theme.json for supported settings and global styles.
  • Custom block variations: use the Block Styles system when users need selectable visual alternatives.
  • Frontend optimization: remove block assets only after confirming they are unnecessary.

Related WordPress Block Editor guides

If you are working more deeply with the WordPress editing experience, the following guides cover related areas:

Final thoughts

WordPress Block Editor CSS becomes much easier to understand once you stop treating the editor as one page.

Modern WordPress separates the outer editing interface from the content canvas. With WordPress 7.1, that content canvas is always inside an iframe, making the document boundary something theme and plugin developers can no longer safely ignore.

enqueue_block_assets, enqueue_block_editor_assets, add_editor_style(), block-specific stylesheets, Block Styles and theme.json all have legitimate roles, but they solve different problems.

The most useful question is therefore not which hook is newest or which snippet appears most frequently in search results. It is where the CSS needs to run and what it is supposed to style.

Once that distinction is clear, most Block Editor CSS problems become ordinary CSS problems again.

If you are optimizing the public side of a block-based site, see Remove Block Assets. If the project should not use Gutenberg at all, see Disable Gutenberg. You can also browse the complete TheOneWP WordPress Guides for more WordPress development, administration, performance and publishing topics.

Simplify your WordPress stack

A modular WordPress toolkit. 104 focused tools.

Ultimately, you can build cleaner workflows, maintain fewer plugins and enable only the features each website actually needs.