Sign in to follow this  

CKEditor Styles dropdown tips

Recommended Posts

A few usability tweaks and tips for the CKEditor "Styles" dropdown, which is by default not that user-friendly:


As you can see it's small and if you add custom items to it they may look awkward as they may inherit styles from their targets (a 3rem bottom margin in the screenshot above).

These are relatively easy to fix but you have to load your custom CSS files to two places (eg. with AdminOnSteroids): PW admin and CKEditor.

After loading the CSS/Js assets (see code below) the dropdown looks nicer and more usable:


The screencap contains other features that you can achieve with the snippets below.


CSS - CKEditor (contains demo styles too)


/* Styles to load in CKEditor */

.cke_panel_grouptitle {
  position: sticky;
  top: 0;
  z-index: 99;

html.cke_panel_container {
  scroll-behavior: auto;

html.cke_panel_container .cke_panel_listItem > a * {
    margin: 0 !important;
    font-size: 0.97rem !important;
} {
  margin-bottom: 0 !important;

p.small-space-after {
  margin-bottom: 0.5rem !important;

p.large-space-after {
  margin-bottom: 3rem !important;

[data-list-style] li {
  margin-bottom: 0.5rem;

[data-list-style="decimal-leading-zero"] {
  list-style-type: decimal-leading-zero;

[data-list-style="upper-roman"] {
  list-style-type: upper-roman;

[data-list-style="checkmark"] {
  color: inherit;
  list-style: none;
  padding-left: 1.25rem;

[data-list-style="checkmark"] li {
  position: relative;

[data-list-style="checkmark"] li::before {
  content: '\2714';
  position: absolute;
  left: -1.1rem;


CSS - admin


/* /site/templates/styles/admin.css */

.cke_combopanel {
    width: auto !important;
    max-width: 600px !important;
    height: 400px !important;

.cke_combo__styles > a > .cke_combo_text {
    width: auto !important;
    max-width: 240px !important;


JavaScript - CKEditor custom styles


// /site/templates/scripts/cke.js

var myStyles = [

    {name: 'Heading 1', element: 'h1'},
    {name: 'Heading 2', element: 'h2'},
    {name: 'Heading 3', element: 'h3'},
    {name: '2 column', element: 'div', attributes: {'class': 'col2'}},

    {name: 'Button', element: 'a', attributes: {'class': 'button'}},
    {name: 'Button-outline', element: 'a', attributes: {'class': 'button-outline'}},

    // empty class prevents highlighting other "p" elements
    {name: 'Paragraph', element: 'p', attributes: {'class': ''}},
    {name: 'Paragraph: no space after', element: 'p', attributes: {'class': 'no-space-after'}},
    {name: 'Paragraph: small space after', element: 'p', attributes: {'class': 'small-space-after'}},
    {name: 'Paragraph: large space after', element: 'p', attributes: {'class': 'large-space-after'}},

    // OBJECT STYLES - visible only if the cursor is inside the corresponding element type in the editor
    {name: 'List: upper-roman', element: 'ol', attributes: {'data-list-style': 'upper-roman'}},
    {name: 'List: decimal leading zero', element: 'ol', attributes: {'data-list-style': 'decimal-leading-zero'}},
    {name: 'List: checkmark', element: 'ul', attributes: {'data-list-style': 'checkmark'}}

// add inline font-size from 12px to 48px
for(var i = 12; i <= 48; i++) {
    myStyles.push({name: 'text ' + i, element: 'span', attributes: {'style': 'font-size: ' + i + 'px;'}});

CKEDITOR.stylesSet.add('mystyles', myStyles);


P.s. in case you wonder whether the half-margin, no-margin stuff and font-sizes from 12px to 48px were real-life examples - yes, client request 🙂 

  • Like 7
  • Thanks 1

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Robin S
      A pet hate of mine is when an editor uses a paragraph of bold text for what ought to be a heading. When I need to tidy up poorly formatted content like this I will quickly change such lines of text into the heading of the appropriate level, but that still results in markup like...
      <h2><strong>Some heading text</strong></h2> The <strong> has no business being there, but it's a bit of a hassle to remove it because you have to drag a selection around the exact text as opposed to just placing your cursor within the line. That gets tedious if you have a lot content to process.
      I figured there has to be an easier way so started looking into the ACF (Advanced Content Filter) features of CKEditor. What I wanted is a rule that says "strong tags are disallowed specifically when they are within a heading tag". (I guess there could occasionally be a use case where it would be reasonable to have a strong tag within a heading tag, but it's so rare that I'm not bothered about it).
      With the typical string format for allowedContent and disallowedContent there is no ability to disallow a specific tag only when it is within another specific tag - a tag is allowed everywhere or not at all. But I found there is an alternative object format for these rules that supports a callback function in the "match" property. So I was able to achieve my goal with the following in /site/modules/InputfieldCKEditor/config.js:
      CKEDITOR.editorConfig = function(config) { config.disallowedContent = { // Rule for the <strong> element strong: { // Use "match" callback to determine if the element should be disallowed or not match: function(element) { // Heading tag names var headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; // The parent of the element (if any) var parent = element.parent; if(typeof parent !== 'undefined') { // If there is a parent, return true if its name is in the heading names array return headings.indexOf( !== -1; } else { // There is no parent so the element is allowed return false; } } } } };  
      Another tip: if you want to debug your allowedContent or disallowedContent rules to make sure they are being parsed and applied successfully you can log the filter rules to the console. For convenience I used /site/modules/InputfieldCKEditor/config.js again.
      // Get the CKEditor instance you want to debug var editor = CKEDITOR.instances.Inputfield_body; editor.on('instanceReady', function() { // Log the disallowed content rules console.log(editor.filter.disallowedContent); });  
    • By Mustafa-Online
      CKEditor 5 v10.0.0 – the future of rich text editing looks stable
    • By Rudy
      Looks very clean. Hopefully we get to test it on PW soon.
    • By manuel1981
      Hey guys,
      I want to disable the crop and align features when placing an image into the CKEditor.
      The image should simply placed in a predefined width without any additional options.
      Can anybody help me with that?
      Thanks, Manuel
    • By MilenKo
      Hello guys. I feel a bit ashamed of this fact but I just needed to add an image with some text wrapped around it using CKEditor and I simply can't achieve that. I have an image field attached to the template (called images) and it is showing promptly the uploaded images. I am able to manipulate the image and I set its alignment to left side. Then I add some text and I can see in CKEditor that the text is properly surrounding the image. However, once I save the page and view it, it shows the text under the image or only a line is staying asside the image and the rest is under the image again. As far as the field used for the text (body) is set to TextMultiLang and I did not added any text formatters and chose the content type to be HTML/Markup.
      In my CSS I've added some of the PW styles for the alignement as per some posts here but that did not help either. Something I am missing again?