How to style custom content in CKEditor 5

Last updated on
2 February 2024

This page has not yet been reviewed by CKEditor 5 module maintainer(s) and added to the menu.

This documentation needs review. See "Help improve this page" in the sidebar.

Introduction

With Drupal planning to ship with CKEditor 5 which has a much improved DX and tooling on the Drupal side, it's helpful to know how to style custom content in CKEditor 5. These styles can range from minor UI improvements on your WYSISYG editor to styles essential to match your default (front-end) theme or the content you are editing.

Because the editor instance will take styling from the admin theme, a common use of this will be for users that want their editor input to better resemble how it will appear when published (aka having the editor have the same styling as the default theme). 

In this example, I have Olivero as my default theme and Seven as my admin theme but you should add custom styling to the info.yml file of whatever your default theme is.

Configure the default theme's info.yml file

Add the following information to your default theme's info.yml file. You can have any number of CSS lines in the ckeditor5-stylesheets list.

name: Olivero
type: theme
base theme: false
description: 'A clean, accessible, and flexible Drupal front-end theme.'
package: Core
ckeditor5-stylesheets:
  - css/font-family.css
  - css/style.css

The example style.css file I will be loading.

# css/style.css
h2 {
  color: green;
}

Rebuild your cache and see your CSS changes in the editor

These CSS files will now be loaded whenever a CKEditor 5 instance is present. (If your theme is already active, be sure to rebuild your cache first for the change to take effect!) In my example, I have CSS that will make h2 tags green.

screenshot with custom green h2 styling

Seeing unwanted changes on your page outside the editor?

What isn't apparent in the above example is that all h2 tags on the page would be green, not just those in the editor. This is obvious if we load a stylesheet that styles tags appearing in the node form which I'll show in the following example.

If you don't have unwanted changes on your page you should be all set, otherwise follow these next steps.

Here, my style.css file makes h1 tags blue.

# css/style.css
h1 {
  color: blue;
}

But because my page title is an h1 tag, it'll also be blue and I don't want that.

screenshot of editor and unwanted page title being blue

So if you have unwanted changes on your page outside of your editor, you should create a copy of the css file and prefix the selector(s) that have unwanted changes outside the editor with .ck-content

# css/cke5-style.css
/* Prefix the h1 with .ck-content to keep the style in the editor, and avoid polluting the page with unwanted h1 styles */
.ck-content h1 {
  color: blue;
}

Update your default theme's info.yml file with a new custom css file that will only apply to the editor

Go into info.yml file and remove the old css file that caused the unwanted changes from the ckeditor5-stylesheets list and replace it with the new custom css file you just created.

name: Olivero
type: theme
base theme: false
description: 'A clean, accessible, and flexible Drupal front-end theme.'
package: Core
ckeditor5-stylesheets:
  - css/font-family.css
  /* This replaces the css/style.css we had before */
  - css/cke5-style.css

Rebuild your cache and now the styles should only be applied inside the editor.

screenshot with styling only applied to editor

CKEditor 5 stylesheets vs. CKEditor 4 stylesheets

Those who have used the ckeditor_stylesheets setting for CKEditor 4 will notice this works quite similarly, but ckeditor5-stylesheets is a distinct setting because CKEditor 5 is not provided by an <iframe> like it is in CKEditor 4.

Stylesheets applied via ckeditor5-stylesheets are loaded like any other CSS file but are applied to the entire page instead of on the <iframe> which is why you may require a new custom css file to avoid unwanted changes. It's worth noting that not using <iframe> makes it a lot easier to work with the editor now. 

For more information on switching from CKEditor 4 to CKEditor 5, see https://www.drupal.org/node/3259165.

Registering CKEditor 5 stylesheets from a module

While Drupal core automatically loads ckeditor5-stylesheets from info.yml files in themes, it does not support this for modules. In cases where a module is providing CKEditor 5 functionality, this can be achieved by adding a hook_library_info_alter() implementation, then registering CKEditor 5 stylesheets in the module's info.yml file in the same way as themes, described above:

/**
 * Implements hook_library_info_alter().
 */
function mymodule_library_info_alter(&$libraries, $extension) {
  $module = 'mymodule';
  if ($extension === 'ckeditor5') {
    // Add paths to stylesheets specified by a modules's ckeditor5-stylesheets
    // config property.
    $module_path = \Drupal::service('extension.list.module')->getPath($module);
    $info = \Drupal::service('extension.list.module')->getExtensionInfo($module);
    if (isset($info['ckeditor5-stylesheets']) && $info['ckeditor5-stylesheets'] !== FALSE) {
      $css = $info['ckeditor5-stylesheets'];
      foreach ($css as $key => $url) {
        // CSS URL is external or relative to Drupal root.
        if (UrlHelper::isExternal($url) || $url[0] === '/') {
          $css[$key] = $url;
        }
        // CSS URL is relative to theme.
        else {
          $css[$key] = '/' . $module_path . '/' . $url;
        }
      }
    }
    $libraries['internal.drupal.ckeditor5.stylesheets'] = [
      'css' => [
        'theme' => array_fill_keys(array_values($css), []),
      ],
    ];
  }
}

Tags

Help improve this page

Page status: Needs review

You can: