Matt Cromwell Avatar
This article explains how to implement inline CSS styles for your TinyMCE editor based on color settings in the WordPress Customizer.

I’ve been working on a highly customized version of the WordPress Twenty Sixteen theme that I call “Beyond 2016”. It has some nice features like supporting Sass and Archive styles, more header layouts, and per page layout options. And you can download and test it now from Github if you like.

Last year, when I was building my Matt2015 child theme, I implemented Editor Formats into a theme for the first time. Since then I’ve been more and more convinced that Editor Formats can do A LOT for the WordPress editor if implemented well.

One wishlist item I’ve had to experiment with that idea is being able to dynamically generate CSS styles for the editor based on my Customizer settings. Only recently did I reach out to our handy-dandy Advanced WordPress Facebook group for help on this issue.

TL;DR (what does that mean?)

You can accomplish this by hooking into the tiny_mce_before_init hook and calling and customizing the $mceInit value. Tutorial below.

Why I Still Value AWP

If you have been a member of our Advanced WordPress Facebook group for a year or more, then you most likely know that the “advanced” value of that group waxes and wanes greatly over time. Very often it’s a great Q&A forum for less than advanced questions. Occasionally it turns into the mecca of #wpdrama. Often it’s just a hub for all thing WordPress. But increasingly rarely is it actually a place to discover truly “advanced” material.

I’ll save that full discussion for another post. For this post, I just want to say that understanding how to hook into the TinyMCE editor effectively for my wishlist was “advanced” for me and the group delivered through two very effective developers who took my challenge by the horns and made it happen:

  1. Kevin Hoffman is a guy I’ve always only known through our FB group and through our Slack channel. Yet the more we interact, the more I really like the guy. When I posted my question about dynamic TinyMCE styles he not only dug into the Core code for his own potential solution (which worked, but neither of us particularly liked it), he also reached out to Developer #2 for assistance.
  2. Samuel Wood, aka Otto, was pinged by Kevin and Otto was convinced that this could be done without having to “write” files to WordPress (which was Kevin’s solution). He circled back the next day on the subject and provided the snippet which Kevin and I both customized to do exactly what is needed. Otto also happens to be one of the lead members of the Plugin Review Team and a very long-time Core committer and .org volunteer.

So, that was most recent experience with leaning on AWP for “advanced” coding and it paid off in dividends for me, and I’ve been a member since we only had roughly 200 members (now we have 21,000+ !!!).

The Problem

So, why is this issue so difficult? First, it is actually very easy to call custom CSS styles into the TinyMCE editor. That can be done with one line of code:

add_editor_style( 'editor_styles.css' );

The problem with that approach is that it’s a static CSS file, you can’t dynamically affect the styles from your Customizer settings.

So, my Googling first came up with using a PHP file and tricking your server into treating it like a CSS file. None other than Chris Coyier of CSS-Tricks provided the code to do that. And it works! You can totally do that. It just feels sooooooo wrong.

Then I thought about how Twenty Sixteen itself generates styles dynamically. It doesn’t trick your server into treating PHP files as CSS files. It creates them on the fly as inline-styles and writes them into the header. There HAD to be a way to do that but in  TinyMCE directly.

add_editor_style() unfortunately doesn't allow for styles generated from the Customizer. Click To Tweet

Otto to the Rescue

Here’s the solution that Otto suggested:

As you can see, he hooks into this:

add_filter( 'tiny_mce_before_init', 'kwh_add_editor_style' );

That allows you to access the array $mceInit, which outputs the default inline styles of all TinyMCE editors in WordPress.

From there, you just have to append your styles to the existing inline styles. That’s why you’ll see the comments about adding spaces before and after your styles — accounting for other styles that might come before or after your own styles.

It’s an elegant and “best practices” focused solution. Highly recommended!

Combining Editor Formats with Dynamic Styles

So here’s why I find it such a great tool. I mean, changing the background color of your editor really isn’t anything to jump up and down about. But in my case, I want to provide some useful Editor Formats which are pure HTML/CSS — no shortcodes — and that look exactly how they will look in the front-end. That’s the big wishlist item, giving users an editor that actually resembles what the post will really look like.

Here’s a preview of what I’ve got going in Beyond 2016 now:

Dynamic TinyMCE styles based on the WordPress Customizer settings.
Dynamic TinyMCE styles based on the WordPress Customizer settings.

So you’ll notice a couple things happening there:

  1. I have a “Block Text” item which is my main Editor Style at the moment. It has stylized fonts, border, colors.
  2. When I switch to one of my custom Beyond 2016 color schemes, the Block Text reflects that change completely.
  3. If you’re paying close attention you’ll see the background color changes, the heading colors change, and the paragraph and link colors change as well.

All together, the Editor visual styles look VERY similar to what is output on the front-end. All of this is done with Core functions, without the need of a Page Builder or Front-End editor at all.

It’s Not a Silver Bullet

Just like I said in my Editor Formats article, this method isn’t going to replace Page Builders and Front-End editors. Those still have a really great place in WordPress in general.

But consider how many WordPressers really just type into the editor and hit publish. That’s a huge amount of people. Don’t they deserve some attention to detail to make their publishing experience nice and smooth?

If you are a Theme Author and have implemented either Editor Formats or Dynamic Editor Stlyes, I’d love to give your theme a spin and see what it’s like. I believe this should be common practice for theme authors but I’m just not seeing it overall.

7 Comments

  1. This is a great step towards a better looking editor. It’s rare that I’ll make a theme with a serif typeface and yet the default post editor has that.

    I tend to make layouts only on Advanced Custom Fields 5 – styling that is the next logical step for my development to make the UX smoother.

    1. I agree, this is the kind of attention to detail which can greatly enhance a users experience with publishing and working with WordPress. Agencies and freelance developers can take this into account for their clients as well.

      I personally am digging into Editor Formats more in order to less the need for ACF in general. I want to use ACF only for highly stylized layouts and not simple alerts or call outs and whatnot. Thanks for stopping by!

  2. This is an awesome and very natural feature to have added to WordPress! A better integration of the Customizer TinyMCE Editor. As one makes visual adjustments in the Customizer having these seen in the TinyMCE Editor is a huge help as it gives a better visual representation of what the post/page looks like.

    Great work Matt, Kevin and Otto! I am looking forward to seeing this develop into a feature project for Core/trac ticket!

  3. Nice work, guys! I enjoyed learning a bit here and think your solution was simplistically beautiful.

    1. Thanks so much Mark! Means a lot coming from you!

    2. Thanks, Mark! I began work on getting this into TwentySeventeen, but it turned out the approach to generated color palettes made things a lot more complicated than in TwentySixteen. Still it was a great learning experience, and who knows, maybe a similar technique can be worked into the block editor of the future :)

  4. Thank you very much! Finally something that works!

Leave a Reply

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