close
Skip to content

dx-enhancement: add custom CSS in block editor iframe and frontend  #48437

@tresorama

Description

@tresorama

Update (2023-02-27 - 27 Feb)

There is a better solution, and simpler, to do what this issue originally describes.

In frontend use wp_enqueue_style and add dependency of css generated from theme.json, so your will have priority if has same css specificity.
In block editor iframe, use add_editor_style.

/* .../wp-content/my-theme/my-custom-css.css */

.text-2xl {
  font-size: 1.5rem !important;
}

@media (max-width: 600px) {
  .mobile\:text-2xl {
    font-size: 1.5rem !important;
  }
}
/**
 * Load custom global CSS into both block editor "iframe" and frontend
 *
 * @return void
 */
function my_theme_enqueue_custom_global_css_in_blocks() {
  
  // Add custom CSS to frontend.
  wp_enqueue_style(
    'my-custom-css',
    get_template_directory_uri() . '/my-custom-css.css'
    array( 'global-styles' ),// say to wordpress to inject this file after the css file generated from "theme.json"
  );

  // Add custom CSS to block editor "iframe".
  add_editor_style( 'my-custom-css.css' );

}
add_action( 'after_setup_theme', 'my_theme_enqueue_custom_global_css_in_blocks' );

Your css stylesheet does not need special treatments, it works in both contexts(block editor/site editor and frontend).

In frontend, you just add your stylesheet after the one generated from theme.json, to be able to overrides without increasing css specificity.

In the block editor (and site editor) "iframe" you use the function add_editor_style, does exactly what this guide does manually, for the iframe part.
The function add_editor_style injects a CSS file in the block editor "iframe" and adds .editor-styles-wrapper scoped selector to every css definition, also in media query definitions.
For example, .text-2xl become .editor-styles-wrapper .text-2xl

Thanks to carolinan that suggested this in this issue.

End of update.





Original Issue Content

This issue is a mix of documentation and awareness of a weird behavior not well documented.

While working in a block theme for first time, i wanted to add custom css to the editor and the frontend. So that when i fill Sidebar > Advanced > Additional CSS classes for a block the preview applies these css classes.

I need that my custom CSS is injected in every editor page.
My custom CSS is global, is not related to any particular block.

How to add CSS to block editor iframe and in frontend

In a block editor page, http://my-site.local/wp-admin/post.php?post=32&action=edit

the page dom contains an <iframe name="editor-canvas"> that is the live preview (orange zone of image )

Schermata 2023-02-25 alle 00 56 56

Because this is an <iframe>, it can ONLY uses assets loaded inside its inner html document.
Assets loaded outside of the <iframe> will be ignored.

What we need is to "enqueue" assets to the iframe.
Currently there is no hook (in php) for that.
But some assets are "passed" to the iframe via html attribute (in the <iframe> node).

There is not an array that we can "add_filter" to, but there is an automatic behavior that takes place.

Speaking about a CSS file, Wordpress scan every "normally" enqueued assets, and create a subset of those and later "pass" this list to the iframe.
Then the iframe trigger network requests for fetching these.

How can be a CSS assets eligible for being passed to iframe?
It needs to contains some arbitrary css selector in its content, .wp-block and .editor-styles-wrapper

So, to load a css you MUST include required css selectors in file content, and then:

// in my-theme/functions.php

function my_theme_enqueue_blocks_assets() {
    
  // NOTE: 
  // Editor <iframe> canvas, the live preview of the editor, REQUIRES that CSS file content contains `.wp-block` and `.editor-styles-wrapper`, otherwise your CSS will not loaded.
  // example:
  // 
  // .editor-styles-wrapper .dummy-enable-css-in-iframe ,
  // .wp-block .dummy-enable-css-in-iframe {
  //   color: 'red';
  // }
  // 
  // rest of your css file ...
  
  // load a CSS file in the block editor page and in the frontend
  wp_enqueue_style(
    'my-custom-css',
    get_template_directory_uri() . '/my-custom-css.css',
  );
}
add_action( 'enqueue_block_assets', 'my_theme_enqueue_blocks_assets' );

Weird behavior

It's very weird that we need to include wp-block and editor-styles-wrapper in css file content.
I figured this only because of a great explanation in this issue in this comment #38673 (comment) , many thanks to @NenadObradovic for discovring that.

Honestly it's not nice, it would be great if in future this requirement will be dropped out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions