Problem/Motivation

When there are many items in the toolbar of CKEditor5, the buttons are relegated into a drop-down menu. However, depending on how many items there are, this can get clipped in Drupal's off-canvas:

CKeditor5 overflow menu clipped by off-canvas

Steps to reproduce

  1. Enable the Layout Builder, Node and Block Content modules.
  2. Create a block type that has a formatted text field.
  3. Create a CKEditor5 editor configuration with many buttons.
  4. Create a node type and enable the layout builder.
  5. Edit the layout.
  6. Hit the Add block button to an existing section to bring out the off-canvas dialog.
  7. Hit Create a custom block.
  8. (If there are multiple block types on the site) Choose the block type that has a formatted text field.
  9. Open the overflow menu drop-down, see that is is clipped and partially unusable.

Proposed resolution

Change the value of --ck-toolbar-dropdown-max-width variable to be relative to the width of the editor instance.

This can be achieved with CSS container queries as follows.

.ck.ck-editor {
  container-type: inline-size;
  container-name: ck-editor;
}


@container ck-editor (width > 0) {
  .ck-dropdown__panel {
    --ck-toolbar-dropdown-max-width: 90cqw;
  }
}

Remaining tasks

  • Fix.
  • Review.
  • Commit.

User interface changes

The dropdown width will always be less than the editor width, ensuring that it never gets clipped if the editor is in a div with overflow: hidden; like off-canvas.

Before:

Before - wysiwyg
Before - source

After:

After - wysiwyg
After - source

API changes

None.

Data model changes

None.

Release notes snippet

None.

Issue fork drupal-3328095

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Wongjn created an issue. See original summary.

wim leers’s picture

Title: CKEditor5 menu overflow can become unusable in Off canvas » CKEditor 5 toolbar overflow can become unusable in Off canvas
Status: Active » Postponed (maintainer needs more info)

Thanks for the clear issue! 👍😊🙏

How does this behave with CKEditor 4?

(Asking to determine if this is a regression or not.)

wongjn’s picture

Status: Postponed (maintainer needs more info) » Active
StatusFileSize
new11.1 KB

As far as I am aware, CKEditor 4 had no such overflow drop-down menu – the toolbar buttons would wrap to new lines (screenshot taken from their documentation site):

CKEditor 4 narrow size toolbar

wongjn’s picture

StatusFileSize
new7.47 KB

And indeed, CKEditor 4 in the off-canvas in Drupal 9 does wrap instead of exhibit an overflow menu drop-down:

CKEditor 4 in Drupal 9's off-canvas

wim leers’s picture

Status: Active » Postponed (maintainer needs more info)
StatusFileSize
new694 bytes

So CKEditor 4 was clearly not rendering in a nice way either. Because it was never designed for narrow viewports.

CKEditor 5 was designed to work well on narrow viewports. 😊 We just need to figure out if the problem is:

  • the way that Drupal is configuring CKEditor 5, or
  • CKEditor 5 not supporting very narrow viewports

I'd suspect it's the first, so let's try to rule that out (see https://ckeditor.com/docs/ckeditor5/latest/features/toolbar/toolbar.html...), so could you please try the attached patch and report back? 🙏

wongjn’s picture

Status: Postponed (maintainer needs more info) » Active

Made no difference unfortunately.

CKEditor 5 was designed to work well on narrow viewports.

I believe the discrepancy here could be that actually the viewport is quite wide (these screenshots were taken on a maximised browser window of a 1920×1080 screen) but the area that the editor is in is quite narrow.

In case this helps at all, here is temporary JavaScript code I concocted to adjust the overflow menu size:

{
  const ONCE_ID = 'ckeditor5-off-canvas';
  const SELECTOR = '[data-editor-active-text-format]';

  /** @type {ResizeObserver|undefined} */
  let observer;

  /** @type {ResizeObserverCallback} */
  const onResize = (entries) =>
    entries.forEach(({ target, contentRect }) => {
      target.style.setProperty(
        '--ck-toolbar-dropdown-max-width',
        `calc(${contentRect.width}px - var(--ck-spacing-small)`,
      );
    });

  /**
   * Whether a form element is for a CKEditor5 editor.
   *
   * @param {{ [k: string]: { editor: string } }} formats
   *   The text formats available.
   *
   * @return {(field: HTMLElement) => boolean}
   *   The filter function.
   */
  const isCkeditor5 =
    (formats) =>
    ({ dataset }) =>
      formats[dataset.editorActiveTextFormat].editor === 'ckeditor5';

  Drupal.behaviors.ckeditor5OffCanvas = {
    attach(context, { editor = {} }) {
      if (editor.formats) {
        once(ONCE_ID, `#drupal-off-canvas ${SELECTOR}`, context)
          .filter(isCkeditor5(editor.formats))
          .forEach(({ parentElement }) => {
            observer = observer || new ResizeObserver(onResize);
            (observer || new ResizeObserver(onResize)).observe(parentElement);
          });
      }
    },
    detach(context, _, trigger) {
      if (trigger === 'unload' && observer) {
        once.filter(ONCE_ID, SELECTOR, context).forEach(({ parentElement }) => {
          observer.unobserve(parentElement);
        });
      }
    },
  };
}
wim leers’s picture

#6: that sounds very plausible! https://caniuse.com/css-container-queries only started shipping a few months ago…

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ravi kant’s picture

StatusFileSize
new166.02 KB
new142.14 KB
new79.65 KB

The solution of remove dropdown of extra tools in CKEditor is providing by CKEditor and it is "Button divider". It will break the CKEditor toolbar in next line.

How to use?

  1. Edit preferred "Text Format". Mostly using Full-HTML.
  2. Navigate to "Toolbar configuration"
  3. Find the "button divider" at the right-top of the active-toolbar. There are two types of button dividers. 1. Divider 2. Wrapper
  4. Drage the wrapper divider and place it on the active toolbar where the next line will be starting.
ravi kant’s picture

Status: Active » Needs review
smustgrave’s picture

Status: Needs review » Active

Moving to active as there is nothing to review

#9 seems to describe building a text editor to be narrow and only have a few buttons each line vs responsive, which I believe was the discussion before.

Correct me if I'm wrong.

smustgrave’s picture

tried #6 but didn't seem to work for me.

smustgrave’s picture

Status: Active » Needs work

Found the css causing the issue. It's from ckeditor5. It's applying width: max-content.

I'm overriding that and seems to work but sure it's not ideal. Thoughts?

jwilson3’s picture

I had experienced something like this on a site with Layout Builder + CKEditor 4 and my workaround was to just widen the LB sidebar flyout. The edge of the flyout is drag-enabled in some contexts, (but I did notice unfortunately not all contexts, though I cannot now remember where it was set to a fixed width). IMHO, the offCanvas for LB should be wider on larger screens. Maybe a follow-up?

Also, I don't see a huge drawback in overriding width: max-content on the wrapper as long as it is in the correct context and solves the problem.

bkosborne’s picture

I think this is a legit bug, but the workaround to get this behaving as it did in CKE4 is mentioned in #9. Just add the "wrapping" button divider anywhere in the toolbar (even as the last item). That will prevent CKE5 from trying to render everything on one completely.

randalv’s picture

StatusFileSize
new27.04 KB

Thanks to #9 and #16, I can confirm that adding the "wrap"-item even as the last item on the bar is a solid workaround until a permanent fix can be provided.
It wraps the excessive items neatly on a second row (as was the behaviour in CKEditor4 if I'm not mistaken).

Ckeditor 5 new line wrapping

Redwan Jamous made their first commit to this issue’s fork.

redwan jamous’s picture

Status: Needs work » Needs review
StatusFileSize
new9.98 KB
new11.15 KB
new731 bytes

Created a MR that fixes the issue using CSS container queries.
The --ck-toolbar-dropdown-max-width variable will be set to 90% of the editor's width instead of 60% of the viewport's width.

Before fix:
Before fix

After fix:
After fix

Adding a patch file to use with composer...

Redwan Jamous changed the visibility of the branch 3328095-ckeditor-5-toolbar to hidden.

Redwan Jamous changed the visibility of the branch 11.x to hidden.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update, +Needs screenshots

If a new solution is being proposed issue summary should match.

Also before/after screenshots need to be added to the issue summary.

redwan jamous’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs issue summary update, -Needs screenshots
Related issues: +#3291797: Refactor Drupal 10 settings tray / off-canvas to use modern CSS
StatusFileSize
new7.33 KB
new129.55 KB
new127.58 KB
new128.94 KB
new128.12 KB
new2.64 KB
new2.54 KB

Thank you, @smustgrave! I'm updating the issue summary...

Unfortunately, the previous fix doesn't work well while source editing mode in CKEditor is active.

After fix with source editing mode

To overcome the issue, the container can be the parent element (.ck.ck-editor) instead of .ck.ck-editor__top.

However, changing the css from:

.ck.ck-editor__top {
  container-type: inline-size;
  container-name: ck-editor;
}

@container ck-editor (width > 0) {
  .ck-dropdown__panel {
    --ck-toolbar-dropdown-max-width: 90cqw;
  }
}

To:

.ck.ck-editor {
  container-type: inline-size;
  container-name: ck-editor;
}

@container ck-editor (width > 0) {
  .ck-dropdown__panel {
    --ck-toolbar-dropdown-max-width: 90cqw;
  }
}

isn't enough because off-canvas reset (core/misc/dialog/off-canvas/css/reset.pcss.css) is applying all: revert; with higher specificity which will overwrite our container-type and container-name.

Adding .ck-editor to the list of elements excluded from the off-canvas reset rules would fix the issue, but I'm not sure about this change.

We currently have the following selector in off-canvas reset:

#drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle))

We're excluding all children elements of .ck-reset but not .ck-reset itself (unlike svg).

The new proposed selector:
#drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle))

Also, CSS linting checks are failing because of the cqw unit, so I will be creating a separate issue to add container query units to the allowed units since they're now supported in all major browsers.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

Thanks for updating. Appears to have some failures in MR.

specky_rum’s picture

Patch in #24 fixes this for me. Had the same problem but caused by the editor being setup within vertical tabs on the Claro theme which prevents overflow.

redwan jamous’s picture

Tests are passing locally. Not sure what the problem is.

vasantha deepika made their first commit to this issue’s fork.

vasantha deepika’s picture

Assigned: Unassigned » vasantha deepika

Let me check the pipeline issue and try to fix it.

This MR only includes CSS changes, but the failure seems to be caused by a JS functional test (JSWebAssertTest), which appears to be unrelated to this update.

I will investigate further and re-run the pipeline if needed. Will share findings shortly.

Additionally, I have increased the dropdown visibility by adjusting the --ck-toolbar-dropdown-max-width value from 90 to 95 to ensure the CKEditor 5 toolbar dropdown displays correctly.

vasantha deepika’s picture

Assigned: vasantha deepika » Unassigned
Status: Needs work » Needs review
StatusFileSize
new773 bytes

The MR !8096 seems fine, but the pipeline is failing due to test-related files.

I'm attaching a patch generated from the MR [3328095-mr8096.patch] in case anyone needs it to proceed without being blocked, until the MR is merged.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new664 bytes

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.