Styling images with CSS classes in CKEditor

CKEditor allows you to use different ways to style your content, and there are some tricks about the inner workings of CKEditor that you should be aware of to get the desired results.

This article will focus just on styling images as a companion tutorial to our ImageToolbar plugin, although most of the concepts apply to every installation of CKEditor.

The first step to master the styles of images in CKEditor is to understand how the plugin that you use to manage the images works. There are two official plugins and unless you're running a custom version you might be using one of them: the Image plugin and the Enhanced image plugin.

Image Plugin

This is the classic plugin that comes installed by default. It has lots of options but you can't expect improvements on it as CKSource has stated that the future is the Enhanced Image plugin.

Here everything is very easy, an image is always an image. There are no tricks, no matter if you're editing or if you've published the content, you'll always have an <img> there and nothing more. Whatever CSS classes you define in your stylesheets will apply like in any other element. In your stylesheet you can use any type of selector that you prefer: img.class or just .class; both will work.

Although the plugin doesn't allow to define centered alignment, you can use classes to easily achieve whatever alignment you need. ImageToolbar plugin also has a special property for the definition of alignment classes so it applies/removes the align attribute as required.

This is an example of 3 classes that you can use to align images and leave a proper margin so the text doesn't touch the image without including the unnecessary margin on the other side. You can't do this using only the align and margin properties in the dialog.

img.leftImage {
    float: left;
    margin: 0 1em 5px 0;
}

img.rightImage {
    float: right;
    margin: 0 0 5px 1em;
}

img.centeredImage {
    display: block;
    margin: 0 auto 1em;
}

Then if you add in your configuration for CKEditor the corresponding group (so only one item of the group is active at any moment):

config.imagetoolbar.classes = [
    [
        { name: 'imageleft', 'class':'leftImage', title:'At the left', justifyCommand:'justifyleft' },
        { name: 'imagecenter', 'class':'centeredImage', title:'Centered', justifyCommand:'justifycenter' },
        { name: 'imageright', 'class':'rightImage', title:'At the right', justifyCommand:'justifyright' },
        { name: 'imageinside', 'class':'inline', title:'Inline', justifyCommand:'justifynone' }
    ],

    [
        { name: 'imageborder', 'class':'borde', title:'Con Borde' }
    ],
    [
        { name: 'imageshadow', 'class':'sombra', title:'Con Sombra' }
    ],
    [
        { name: 'nomobile', 'class':'no-mobile', title:'No Mostrar en móvil' }
    ]
];

The ImageToolbar will take care also of adjusting the ACF system with whatever classes you want to use, but even if you add extra items so you can use a single config file with different stylesheets, it will show only the buttons to use the classes available in the current stylesheet.

Enhanced Image Plugin

This is an alternative image manager provided by CKSource. Sometimes it's named as image2 (it's internal code name) or Captioned images (the main usage of this plugin).

Things now aren't as simple because there are in fact 4 different states for an image according to the selected options and whether you're editing the content or viewing the final page.

The first two states depends on if you're using a "normal" image, or a "captioned" image. Looking at the generated output in the first case you get a classic <img> element, but the second one generates a wrapping <figure> element and a sibling <figcaption>:

<figure class="image"><img alt="" height="280" src="/userfiles/test_980x657.jpg" width="657" />
<figcaption>Caption</figcaption>
</figure>

In this situation the classes defined for ImageToolbar are applied on the external <figure> element because that's the only way to preserve them if the user opts to turn off the caption and use again a simple img element.

As you will prefer to apply the side margin to the figure element (instead only to the img element), you will have to be more careful with your stylesheets. Also if you want to use borders, shadows, you have to decide if you want those styles applied to the external figure or to the inner img, so you might end up with a stylesheet like this:

  • Alignment styles using only the class name so they apply both to the figure and img elements
.atLeft {
    float: left;
    margin: 0 30px 5px 0;
}
.atRight {
    float: right;
    margin: 0 0 5px 20px;
}
.centered {
    display:block;
    float:none;
    margin:5px auto;
}
  • Styling only for the image:
img.rounded, .rounded img {
    border-radius:20px;
}
img.ellipse, .ellipse img {
    border-radius:50%;
}

There's also another important detail to remember when you're using the Enhanced image plugin: the structure while editing the content is very different from the final output. It includes wrappers to provide the resizing and dragging handlers, and in this situation, the Enhanced image plugin applies whatever alignment classes you have defined in the config.image2_alignClasses to the external wrapper. We haven't found a proper way to override this behaviour, and you must define in your config those entries because we can't generate them at runtime.

Finally, if you apply the Center class, the DOM structure of the page will be modified by the Enhanced image plugin to create a new wrapping p/div where this image will be centered and will be the only child.