Creating theme editor styles for Gutenberg

WordPress 5 will come with a new editor called »Gutenberg«, which is completely different from the current TinyMCE. That does not only mean change for the users, but also for theme developers, who want to modify editor styles, so it looks like in the frontend. This post shows you how that works for the new editor.

The previous procedure with TinyMCE: quite pleasant

The post content in the TinyMCE editor lives inside an iFrame, that means theme specific styles can be written similar to the frontend CSS. There is a normal website’s markup in the DOM just for the content, the visible content is inside a body element, and inside the body, there are the content elements directly, like paragraphs, headings, et cetera. That is how the DOM looks like:

DOM of this post’s content in the TinyMCE. (Screenshot: Firefox dev tools)

With that, it is not that difficult to implement the basic styles of the theme into TinyMCE.

The procedure with Gutenberg: not so pleasant

With Gutenberg, it is slightly different. First, the editor does not sit in an iFrame, which in itself is good. Among that, all content elements are so-called blocks, which are wrapped in divs that have spacing around them, et cetera. The DOM of this post looks like that in Gutenberg:

DOM of this post’s content in the Gutenberg editor. (Screenshot: Firefox dev tools)

Very complex compared with the content’s markup in TinyMCE…

So much for the starting point. But before we can start writing the CSS rules, let us begin loading the stylesheet. Helpful for me was the article »How to add WordPress Theme Styles to Gutenberg« by Rich Tabor.

Including a stylesheet for Gutenberg modifications

Including the stylesheet is not that hard:

// Add backend styles for Gutenberg. add_action( 'enqueue_block_editor_assets', 'photographus_add_gutenberg_assets' ); /** * Load Gutenberg stylesheet. */ function photographus_add_gutenberg_assets() { // Load the theme styles within Gutenberg. wp_enqueue_style( 'photographus-gutenberg', get_theme_file_uri( '/assets/css/gutenberg-editor-style.css' ), false ); }
Code language: PHP (php)

We hook a function to the enqueue_block_editor_assets hook and add the stylesheet via wp_enqueue_style. Now to the CSS rules.

Writing styles for Gutenberg

Gutenberg comes with styles we need to overwrite. We can use .edit-post-visual-editor as the wrapper for the content, the blocks itself have the .editor-block-list__block class.

We need to be careful to not modify styles of the inline toolbar or other inline tools from Gutenberg. Useful classes are:

  • .mce-content-body – used for many text block elements, like headings, paragraphs (but not the ones inside of blockquote elements), lists, and so on.
  • .wp-block-quote – a class for block quotes.
  • .editor-block-list__block-edit – wrapper inside of .editor-block-list__block for the content element.

My current state of editor styles for Gutenberg in my Photographus theme looks like the following in SASS (I removed media queries to make it shorter):

@import "abstracts/variables"; @import "abstracts/functions"; @import "abstracts/mixins"; .edit-post-visual-editor .editor-block-list__block { color: $color-tundora; margin: 0 auto; max-width: $content-max-width; } .edit-post-visual-editor p, .edit-post-visual-editor, .blocks-rich-text__tinymce.mce-content-body { line-height: inherit; font-size: inherit; } .edit-post-visual-editor .editor-block-list__block-edit, .edit-post-visual-editor { font-family: "PT Serif", Georgia, serif; font-size: 1em; line-height: $line-height; } .edit-post-visual-editor .editor-block-list__block { h1, h2, h3, h4, h5, h6 { &.mce-content-body { font-weight: 400; } } h1.mce-content-body { font-size: 1.802em; line-height: line-height(1.802, 1.5); } h2.mce-content-body { font-size: 1.602em; line-height: line-height(1.602, 1.5); } h3.mce-content-body { font-size: 1.424em; line-height: line-height(1.424, 1.25); } h4.mce-content-body { font-size: 1.266em; line-height: line-height(1.266, 1.25); } h5.mce-content-body { font-size: 1.125em; line-height: line-height(1.125, 1); } h6.mce-content-body { font-size: 1em; line-height: line-height(1, 1); } figure { line-height: 0; margin: add-unit($space-half, 'em') 0 0; figcaption, img { line-height: $line-height; } } figcaption { clear: both; color: inherit; font-size: $font-size-small; padding-top: add-unit($space-quarter, 'em'); text-align: left; } blockquote.wp-block-quote { border-left: 2px solid; padding-left: add-unit($space-half, 'em'); } blockquote.wp-block-quote cite { display: block; font-style: italic; margin: add-unit($space-quarter, 'em') 0 0; } table { border-spacing: 0; } td, th { border: none; border-bottom: 1px solid; padding: add-unit($space-quarter, 'em'); } th { border-bottom: 2px solid; text-align: left; } table tr:last-of-type td { border-bottom: none; } dt { margin: add-unit($space-quarter, 'em') 0 0; } dd { margin: 0 0 0 add-unit($space, 'em'); } ul, ol { padding-left: 1rem; margin-left: 0; } ul > li { list-style-type: none; position: relative; } ul > li::before { content: "·"; left: -#{add-unit($space-half, 'em')}; top: 0; position: absolute; } li + li { margin: add-unit($space-quarter, 'em') 0 0; } ul ol, ol ul, ul ul, ol ol { margin: add-unit($space-quarter, 'em') 0 0; } } .edit-post-visual-editor .mce-content-body { a { box-shadow: inset 0 -1px 0 currentColor; box-shadow: inset 0 -1px 0 currentColor, 4px 0 0 transparent, -4px 0 0 transparent; box-decoration-break: clone; color: inherit; padding-bottom: .05em; padding-top: .05em; text-decoration: none; -webkit-text-decoration-skip: objects; transition: box-shadow .2s ease 0s, background .2s ease 0s; } a:active, a:hover { box-shadow: inset 0 -1px 0 transparent; outline-width: 0; } a:focus { background: $color-tundora; box-shadow: inset 0 -1px 0 $color-tundora, 4px 0 0 $color-tundora, -4px 0 0 $color-tundora; color: $color-white; outline-width: 0; } }
Code language: SCSS (scss)

First, I reset some styles of Gutenberg and define my base styles, like font and line height. After that, I define styles for the block elements and in the end for the inline elements, that live inside .mce-content-body (currently, that are just links in my stylesheet).

An unresolved problem for me is to define the spacing between elements in Gutenberg. If we want, for example, give the headings space to the top, the inline toolbar would float far away from the actual text.

That is a screenshot from Gutenberg with the current result:

The editor styles for Gutenberg in action. (Screenshot: own installation)

I am quite happy with that for now.

Like you can see, writing editor styles for Gutenberg is a little bit of trying and not made quickly. What you should avoid is: just take the styles for TinyMCE, copy them and think it will work. That could break the styles of the editor.

10 reactions on »Creating theme editor styles for Gutenberg«

  1. I gave the instructions a try and it did not work. Adding your styles as .css produced some errors. Perhaps this is not meant for someone who does not understand how use sass for creating styles, or maybe you could include more complete explanation. I appreciate that you are one of the few trying to alleviate some of the ui issues with Gutenberg.

    1. Hey Jim,

      thanks for your comment. Yes, adding that content simply as a CSS file will not work, you would need the import files and compile it to CSS.

      Since I published the post some things has changed regarding the editor styles, I will need to update the post accordingly. I will set that on my list and try to explain it more detailed then.


  2. Hello, is it possible to add a dynamic style sheet (in php)? Indeed, if the goal is is that the front-end and the editor is almost identical, it is sometimes essential to have dynamic css (wordpress options in particular)

  3. is there a hook for the css dynamic for the editor? Example of a css dynamic for the front-end:
    function capacity_wp_head()
    echo ''. capacity_dynamic_css() .'';
    add_action('wp_head', 'capacity_wp_head');

    1. Hi,

      as described in the post you can use the `enqueue_block_editor_assets` hook to laod styles in the editor. There you should be able to `echo` inline styles that can have dynamic parts that are filled via PHP.


      1. body {
        background: ;
        font-family: ;
        font-weight: ;
        font-size: ;

        $dynamic_css = ob_get_contents();
        return $dynamic_css;

        function capacity_enqueue_block_editor_assets()
        echo ''. capacity_dynamic_css_editor() .'';
        add_action('enqueue_block_editor_assets', 'capacity_enqueue_block_editor_assets');

        It works! thank you very much

          1. Hi Ceylan,

            thanks for posting your solution, great to hear that it works. To the thing with removed code: what was removed exactly? Could you post a link to the code in a GitHub Gist or something like that?


          2. @Florian, I do not use GitHub to store files. I put the code on facebook you can put it back in your tutorials or comments ...

Leave a Reply

Your email address will not be published. Required fields are marked *