Mastering the TinyMCE Styles Dropdown in the WordPress Visual Editor

TinyMCE Styles dropdown menuI’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. 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).

TinyMCE editor screenshot

The power of the TinyMCE Styles dropdown menu.

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]
  • selector limits the style to a specific HTML tag, and will apply the style to an existing tag instead of creating one
  • block creates a new block-level element with the style applied, and will replace the existing block element around the cursor
  • inline creates a new inline element with the style applied, and will wrap whatever is selected in the editor, not replacing any tags
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_action( 'admin_init', 'add_my_editor_style' );

function add_my_editor_style() {
	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.

Download the Custom Editor Styles plugin (updated July 30, 2012)

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.