CKEditor automatically strips classes from div

Solution 1:

Disabling content filtering

The easiest solution is going to the config.js and setting:

config.allowedContent = true;

(Remember to clear browser's cache). Then CKEditor stops filtering the inputted content at all. However, this will totally disable content filtering which is one of the most important CKEditor features.

Configuring content filtering

You can also configure CKEditor's content filter more precisely to allow only these element, classes, styles and attributes which you need. This solution is much better, because CKEditor will still remove a lot of crappy HTML which browsers produce when copying and pasting content, but it will not strip the content you want.

For example, you can extend the default CKEditor's configuration to accept all div classes:

config.extraAllowedContent = 'div(*)';

Or some Bootstrap stuff:

config.extraAllowedContent = 'div(col-md-*,container-fluid,row)';

Or you can allow description lists with optional dir attributes for dt and dd elements:

config.extraAllowedContent = 'dl; dt dd[dir]';

These were just very basic examples. You can write all kind of rules - requiring attributes, classes or styles, matching only special elements, matching all elements. You can also disallow stuff and totally redefine CKEditor's rules. Read more about:

  • Content filtering in CKEditor – why do you need content filter.
  • Advanced Content Filter – in deep description of the filtering mechanism.
  • Allowed content rules – how to write allowed content rules.

Solution 2:

I found a solution.

This turns off the filtering, it's working, but not a good idea...

config.allowedContent = true;

To play with a content string works fine for id, etc, but not for the class and style attributes, because you have () and {} for class and style filtering.

So my bet is for allowing any class in the editor is:

config.extraAllowedContent = '*(*)';

This allows any class and any inline style.

config.extraAllowedContent = '*(*);*{*}';

To allow only class="asdf1" and class="asdf2" for any tag:

config.extraAllowedContent = '*(asdf1,asdf2)';

(so you have to specify the classnames)

To allow only class="asdf" only for p tag:

config.extraAllowedContent = 'p(asdf)';

To allow id attribute for any tag:

config.extraAllowedContent = '*[id]';

etc etc

To allow style tag (<style type="text/css">...</style>):

config.extraAllowedContent = 'style';

To be a bit more complex:

config.extraAllowedContent = 'span;ul;li;table;td;style;*[id];*(*);*{*}';

Hope it's a better solution...

Solution 3:

Edit: this answer is for those who use ckeditor module in drupal.

I found a solution which doesn't require modifying ckeditor js file.

this answer is copied from here. all credits should goes to original author.

Go to "Admin >> Configuration >> CKEditor"; under Profiles, choose your profile (e.g. Full).

Edit that profile, and on "Advanced Options >> Custom JavaScript configuration" add config.allowedContent = true;.

enter image description here

Don't forget to flush the cache under "Performance tab."

Solution 4:

Since CKEditor v4.1, you can do this in config.js of CKEditor:

CKEDITOR.editorConfig = function( config ) {
  config.extraAllowedContent = '*[id](*)';  // remove '[id]', if you don't want IDs for HTML tags
}

You can refer to the official documentation for the detailed syntax of Allowed Content Rules

Solution 5:

if you're using ckeditor 4.x you can try

config.allowedContent = true;

if you're using ckeditor 3.x you may be having this issue.

try putting the following line in config.js

config.ignoreEmptyParagraph = false;