Mastering the TinyMCE Styles Dropdown in the WordPress Visual Editor
I’ll just come out and say it: I write my blog posts in the visual editor. Yes, it may be blasphemy for a developer to do that, but I just don’t care. I like seeing the post I’m writing come to life as I’m writing it. Since I’m such a fan of the visual editor, I’m always looking for new ways to stretch its capabilities without adding a truckload of extra markup to my post. There’s a slightly more detailed story that leads to how I got to writing this particular post,* but that’s not why you’re reading this. You’re reading this because you want to learn about the styles dropdown in the visual editor. Here we go!
Most people know about the “Kitchen Sink” button in the WordPress visual editor—the one that toggles the second row of buttons. On that second row, there’s the familiar Format dropdown menu. Well, there’s another dropdown menu available that isn’t on the toolbar by default: the Styles dropdown. This makes it easy to add custom classes to the visual editor in WordPress (which is particularly great for client websites, when clients need a foolproof way to add HTML to the post).
Method 1: Comma-separated string of styles
I learned about the Styles dropdown a couple of years ago, and through a few Google searches I found out how to make it show up and list my custom classes. This is what I learned then, and it’s still prevalent in Google search results:
add_filter( 'tiny_mce_before_init', 'my_custom_tinymce' );
function my_custom_tinymce( $init ) {
$init['theme_advanced_buttons2_add_before'] = 'styleselect';
$init['theme_advanced_styles'] = 'Button=button,Callout Box=callout';
return $init;
}
(That code would go in your theme’s functions.php file.)
This is pretty straightforward. We’re adding the Styles dropdown ('styleselect') to the second row of buttons (theme_advanced_buttons2_add) at the beginning of the row (_before). Then we’re adding our own styles to the list.
In the list of styles, the title comes before the equals sign and the CSS class comes afterward. Separate multiple styles with a comma. Violà!
So what’s wrong with that?
This method is 100% okay to use. It’s short and sweet, requires very little code, and gets the job done. However, it’s a little restricting. This will take whatever text is highlighted in the editor and wrap a <span> element around it, applying the CSS class to the span. Here’s what it won’t do:
- Apply a class to an existing block element
- Limit a style to a specific HTML tag
- Wrap multiple block elements in another block element with a custom class
- Apply inline styles to an element
I definitely want to be able to do all of those things. Don’t you? (Well, maybe not inline styles, but the point is that you can.)
Method 2: Arrays using TinyMCE parameters
Step 1: Add the Styles dropdown to the toolbar
Add this code to functions.php:
add_filter( 'mce_buttons_2', 'my_mce_buttons_2' );
function my_mce_buttons_2( $buttons ) {
array_unshift( $buttons, 'styleselect' );
return $buttons;
}
A slightly different way of adding the dropdown. This filter applies only to the buttons, so it feels a little more right.
Step 2: Add KICK-ASS custom styles
After that, add this code:
add_filter( 'tiny_mce_before_init', 'my_mce_before_init' );
function my_mce_before_init( $settings ) {
$style_formats = array(
array(
'title' => 'Button',
'selector' => 'a',
'classes' => 'button'
),
array(
'title' => 'Callout Box',
'block' => 'div',
'classes' => 'callout',
'wrapper' => true
),
array(
'title' => 'Bold Red Text',
'inline' => 'span',
'styles' => array(
'color' => '#f00',
'fontWeight' => 'bold'
)
)
);
$settings['style_formats'] = json_encode( $style_formats );
return $settings;
}
This is also fairly simple once you know the syntax. All we’re doing is defining the formats, then encoding them as JSON so they’re TinyMCE-friendly, then assigning them to the TinyMCE settings.
Let’s break apart the array and look at the different options.
| title [required] | label for this dropdown item |
| selector | block | inline [required] |
|
| classes [optional] | space-separated list of classes to apply to the element |
| styles [optional] | array of inline styles to apply to the element (two-word attributes, like font-weight, are written in Javascript-friendly camel case: fontWeight) |
| attributes [optional] | assigns attributes to the element (same syntax as styles) |
| wrapper [optional, default = false] | if set to true, creates a new block-level element around any selected block-level elements |
| exact [optional, default = false] | disables the “merge similar styles” feature, needed for some CSS inheritance issues |
Note that while classes and styles are both optional, one of the two should be present in each array. (Otherwise, why are you adding this to the dropdown anyway?)
Step 3: Add your stylesheet to the visual editor
WordPress made this one easy in version 3.1. Just add this to functions.php:
add_editor_style();
Then put a file in your theme folder named editor-style.css. Any styles in there are applied to the visual editor.
Update 6/11/11: I’ve made a plugin version of this so your customizations will be preserved when updating your theme (especially important if you’re using a regularly updated theme like Twenty Ten). Download it below.
Download the Custom Styles Dropdown plugin
To use it, just unzip the download and put the PHP file in your wp-content/plugins folder, then activate it!
That’s it! For more TinyMCE parameter examples, check out this post at WordPress Answers and this documentation for TinyMCE.
* Here’s the story I mentioned earlier: I am just days away from launching Themejack, where my husband and I will be creating and selling premium WordPress themes based on my Bolts framework. I had a bunch of fancy custom shortcodes defined for things like callout boxes, download links, and buttons, when I happened upon this post by Justin Tadlock. Basically he’s saying that shortcodes are often overused, and replaced only with basic HTML. This has certain disadvantages for the user (read his post for more details on that). I really admire Justin Tadlock’s work—he definitely knows his stuff, and he’s one of the developers that inspires my work in WordPress—so I tend to listen to what he says when he expresses opinions as strongly as he did in that post.
So I did plenty of Google searching and somehow landed on the TinyMCE Styles dropdown. It makes much more sense than shortcodes when you think about it. Changes can be visible immediately in the visual editor (if you’re using a custom editor stylesheet) and if the user switches themes, there aren’t a bunch of useless shortcodes left in the content. I was running into that lack of flexibility, though, and didn’t find these advanced TinyMCE parameters right away. When I did track them down, they were scattered across a few different sites, some of which were on pages 3 & 4 in the search results. Hopefully putting them all in one place will make someone else’s search less exhausting than my own!
