Enhancing the editor's experience: Using DIVs in a WYSIWYG Drupal editor

One of the biggest challenges we face as web developers is creating effective site management environments for our clients—a comprehensive system that balances content editing flexibility and ease of use, while still maintaining some semblance of web standards in the output. I want to show you a simple trick I've employed to enhance the editing tools: Making divs a bit easier to comprehend and use.

In this example, I'm using Drupal and ckeditor.

First, a bit of background.

Formatting the Wrong Way

With modern WYSIWYG editors, it's easy to empower the content manager with tons of layout options at the flip of a switch. Just install a good editor, turn on every button in the toolbar, and remove all filtering. But that's a bad option for many reasons.

First, you're giving your client nearly unlimited power to change the layout and style of the content: font size, colors, indentation, etc. Regardless how much you might trust any individual person with that power, understand that she might turn over the reins to someone else at some point. And nothing can kill a professional design more effectively than numerous, inconsistent styles. For that reason alone, it's best to limit style and layout options.

But that's not the only problem with WYSIWYG formatting. Most of those style and layout tools break all the rules of web standards. Consider indentation. Most indent tools add inline styles (e.g. <p style="margin-left: 10px;">). With that one push of a button, you've committed a few sins:

  1. Mixed content and design;
  2. Applied inline style rules that take precedence over style sheets; and
  3. Assumed that a fixed indent level (10px) will work on all devices (desktop, tablet phone).

I won't go into detail on the reasoning behind each of these errors. If you have questions on them, research web standards and separation of content and design.

A Better, Limited Approach

After developing numerous CMS sites, I've come up with a process that works fairly well when launching a WYSIWYG editor for my clients:

  1. Have the graphic designer provide a few Photoshop files that detail all content formatting and styles (paragraphs, margins, headers, emphasis, inline images, etc.)
  2. Enable the bare minumum of style buttons in the editor: bold, italic, links, unordered and ordered lists, superscript/subscript.
  3. Write CSS that automatically applies default styles for basic elements.
  4. Develop formatting classes that achieve the other necessary styles.
  5. Provide the client with custom documentation. Based on the style and formatting requirements, this documentation will be different for each site.
  6. Train the client, get feedback, and provide more formatting classes where necessary. (Let's face it, it's rare to get it absolutely right the first time.)

Going Beyond the Basics

Regardless of how hard I try to keep all formatting limited to the basic sementic tags within the content area, you might find the need to use divs in a WYSYWIG editor at some point. In my experience, this is usually to alter the layout, like creating multiple columns or (gasp) indentation.

From the clients' standpoint, divs can be difficult to understand. First, they are abstract containers with no default style. If you've created sites from scratch, you've probably come to know divs intimately. But we should assume our clients know no HTML. Second, you cannot see a div. In fact, without looking at the source code, you probably can't tell that you've created one. If you can't see it, thre's a good chance that you'll have trouble inserting more content into it.

I've solved both of those problems with a few lines of code. (Frankly, I can't believe I didn't do this years ago; live and learn.)

Making DIVs Visible While Editing

On the site in question, I decided to use divs for a few different style and layout requirements:

  • Floating images and tables,
  • creating two- and three-column content within a single body field, and
  • indenting entire sections of paragraphs and other content.

Here are some screen captures of the styles template page I created for the client. The floated image and mulitple columns are all achieved via formatted divs. I could have applied the float directly to the img, but I like being able to float other objects, like tables. Using a div container allows me to use this on nearly anything.

Floated images:

Multiple columns:


So my div classes work great. And because they don't use inline styles, I'm able to control exactly what they do on small devices: eliminate floats in some cases, reduce or eliminate indentation in other cases.

But inside the editor, you can't really tell where the divs begin and end. It's very easy to insert multiple nested divs and get really confused about where a particular style is coming from. And depending on which editor you're using, applying a style to a group of elements (e.g. an image, a paragrph, and a header) might force it to insert a bunch of divs (one to wrap each element). In this instance, what you can't see will hurt you.

Those divs need some visual definition!

The Solution: Make them Visible

So my solution was to apply some default CSS to the divs, but only within the editing environment. Here's the code:

/* First, add background to bounding box */
body.cke_editable div.indent,
body.cke_editable div.two_col, body.cke_editable div.three_col,
body.cke_editable div.float_left, body.cke_editable div.float_right,
body.cke_editable div.fixed {
    background: rgba(255, 0, 0, 0.1);
    border: 1px solid rgba(255, 0, 0, 0.5);
    padding: 5px;
/* Add class name before */
body.cke_editable div.indent:before,
body.cke_editable div.two_col:before, body.cke_editable div.three_col:before,
body.cke_editable div.float_left:before, body.cke_editable div.float_right:before,
body.cke_editable div.fixed:before {
    content: attr(class);
    font-size: 0.8em;
    font-style: italic;
    color: rgba(0, 0, 0, 0.5);
    float: right;
    padding-right: 15px;

Using body.cke_editable, I made sure the styles will show up only in the editor. First I added a background color and border to define the edges of the div. Next, I used the :before pseudo-element to embed the class name within the div (line 15 above) Be sure to name your classes in a way the person at the other end can decipher.

The results look like this: