How to Add Custom CSS Classes to <table> or <img> in CKEditor
Adam C. |

CKEditor 5 is great! But if you are a fan of CKEditor 4, then you may not agree with me, because you cannot edit the source code to add whatever HTML code to the content you are editing in CKEditor 5. I like the way how CKEditor 5 works, and I agree that the Text Editor is for the end-user to compose a story, not to write HTML code.  The code generated by the Editor needs to be as clean as possible. 

Photo by Kelly Sikkema on Unsplash

Problem

But sometimes, we do want to have a bit more control over the content generated by CKEditor. For example, the Deni Apps website is using the Semantic-UI theme, which comes with a styled table. If I use CKEditor to generate the table. The source code is like this:

<figure class="table">
	<table>
		<tbody>
			<tr>
				<td>1</td>
				<td>2</td>
			</tr>
		</tbody>
	</table>
</figure>

But the CSS style of the table in the Semantic-UI is like this:

.ui.table {
    width: 100%;
    background: #fff;
    margin: 1em 0;
    border: 1px solid rgba(34,36,38,.15);
    -webkit-box-shadow: none;
    box-shadow: none;
    border-radius: .28571429rem;
    text-align: left;
    color: rgba(0,0,0,.87);
    border-collapse: separate;
    border-spacing: 0
}

So to make it works, we need to have CSS classes (i.e., .ui .table) applied to the <table> element, not to <figure>.  

But we cannot edit the HTML source code, how to do it? The good thing is that CKEditor allows us to add converters to upcast and downcast dispatchers. The sounds hard. Yes, it's.  So I created a plugin to make this work a lot easier for people who need this feature.  And the plugin is integrated into the ckeditor5-build-classic-dna - a CKEditor build for the developer's blog.

Solution

Install  ckeditor5-build-classic-dna

npm install ckeditor5-build-classic-dn

Pass custom CSS class names as Array  to CKEditor

import CKEditor from "@ckeditor/ckeditor5-react";
import ClassicEditor from "ckeditor5-build-classic-dna";

class CKEditor5 extends Component {
  render() {
    return (
      <CKEditor
        editor={ClassicEditor}
        data={this.props.value}
        config={{
          table: {
            customClass: ["ui", "table", "celled"], // Important!!! need to be array
          },
          image: {
          	customClass: ["ui", "fluid", "image"], // Use whatever class names defined in your theme
          }
          //... other configs
        }}
       />
      );
   }
}  

As you see, the plugin works for both <table> and <img>, what you need to do is passing the class names. Again, it has to be an Array even you have only one class name.

After that,  the CKEditor will generate the HTML code like this:

<figure class="table">
	<table class="ui table celled">
		<tbody>
			<tr>
				<td>1</td>
				<td>2</td>
			</tr>
		</tbody>
	</table>
</figure>

That's it. Check out the CKEditor demo page for more usage.