Add WordPress Block Editor Styles and Custom Block Style Variants with PHP

The WordPress block editor loads a separate stylesheet for the editing canvas, and matching that editor appearance to the front-end theme is one of the most frequent pain points for theme developers. Without editor styles, post content looks completely different in the editor compared to the published page, forcing writers to preview constantly and eroding trust in the WYSIWYG promise of the block editor. WordPress provides the add_editor_style() function to enqueue stylesheets inside the editor iframe, where they apply only to the block content area and do not affect admin UI styles. Using the enqueue_block_editor_assets hook is the modern approach for adding both styles and scripts to the block editor context without requiring classic editor compatibility code. The body.block-editor-page selector is the right scope for styles that should apply only inside the block editor canvas, preventing leakage into the surrounding admin interface. Custom block styles registered with register_block_style() add named CSS class variants to any core or third-party block, appearing as style options in the block inspector sidebar without JavaScript. Block-specific styles added via wp_enqueue_block_style() — available since WordPress 5.9 — are loaded only when the corresponding block is present on the page, eliminating unused CSS without a build step. The theme.json styles section applies design tokens to block elements directly, and those tokens are respected in both the editor and the front end without any additional CSS. The CSS grid post shows how the same grid utility classes applied in the front-end stylesheet can be referenced in an editor stylesheet for a consistent layout experience. The CSS custom properties guide explains how to declare :root variables once and reference them in both the front-end and editor stylesheets to avoid duplicating values. After changing editor styles, reload the block editor with a hard refresh (Cmd+Shift+R on macOS) because browser caching of the editor bundle can cause stale styles to persist after updates.

Problem: WordPress block editor content looks different from the published page because the theme stylesheet is not loaded inside the editor canvas, forcing editors to preview every post to see accurate typography and spacing.

Solution: Enqueue a dedicated editor stylesheet via add_editor_style() and register custom block style variants with register_block_style() so the editing experience matches the front-end visually.

// functions.php — enqueue editor styles
add_action('after_setup_theme', function() {
    add_theme_support('editor-styles');
    add_editor_style('css/editor-style.css');
});

// css/editor-style.css — mirror front-end typography in the editor
.editor-styles-wrapper {
    font-family: var(--wp--preset--font-family--primary, Georgia, serif);
    font-size: 1.125rem;
    line-height: 1.75;
    color: #1a1a1a;
    max-width: 780px;
    margin: 0 auto;
}
.editor-styles-wrapper h2 { font-size: 1.75rem; margin-top: 2rem; }
.editor-styles-wrapper h3 { font-size: 1.375rem; margin-top: 1.5rem; }
.editor-styles-wrapper p  { margin-bottom: 1.25rem; }
.editor-styles-wrapper pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; }

// functions.php — register a custom block style variant
add_action('init', function() {
    register_block_style('core/image', [
        'name'  => 'rounded',
        'label' => 'Rounded',
    ]);
    register_block_style('core/button', [
        'name'  => 'outline',
        'label' => 'Outline',
    ]);
});

// Enqueue per-block CSS only when the block is present (WP 5.9+)
add_action('init', function() {
    wp_enqueue_block_style('core/image', [
        'handle' => 'theme-image-block',
        'src'    => get_template_directory_uri() . '/css/blocks/image.css',
        'ver'    => wp_get_theme()->get('Version'),
    ]);
});

NOTE: The is-style-rounded and is-style-outline CSS classes are added automatically by the block editor when an editor selects the named style — add the corresponding CSS rules to the editor stylesheet and the front-end stylesheet so the style variant appears correctly in both contexts.