CKEditor indent: control whole blocks and keep list nesting distinct

CKEditor 5's Indent plugin supplies the indent and outdent controls. Add IndentBlock for paragraph and heading indentation, and List for list nesting. The controls delegate to the available behavior; loading the button plugin alone does not implement indentation. Block indentation documentation

In a fictional oral-history transcript, an editor wants a speaker's explanatory paragraph inset from the surrounding text. Elsewhere, a follow-up question belongs beneath a numbered interview question. The paragraph needs a visual block inset; the follow-up needs a parent-child list relationship. Adding spaces at the start of both lines would leave those intentions unclear.

Give paragraphs a bounded set of levels

For an existing current npm-based integration, import the needed features from ckeditor5 and merge them into its plugin list:

import { Indent, IndentBlock, List } from 'ckeditor5';

const transcriptIndentOptions = {
  plugins: [Indent, IndentBlock, List],
  toolbar: ['outdent', 'indent'],
  indentBlock: {
    classes: ['transcript-inset-1', 'transcript-inset-2']
  }
};

This is an integration fragment. Preserve other plugins, toolbar controls, styles, and the application's applicable license configuration. Include List when authors also need nesting; the transcript's existing list controls still need their usual configuration.

The classes array makes the second listed class the highest available block-indentation level. Provide the styles in both the editable content and the reader view:

.transcript-inset-1 { margin-inline-start: 1rem; }
.transcript-inset-2 { margin-inline-start: 2rem; }

A saved class without matching reader CSS can look as though the indentation disappeared. Check the saved data before changing the editor. Conversely, changing CSS can alter the appearance of many saved documents without changing their stored class values.

Choose fixed steps when classes are unnecessary

The documented default step is 40px. If the application needs spacing that follows text size, configure an offset and unit instead:

const transcriptRelativeIndent = {
  indentBlock: { offset: 1, unit: 'em' }
};

Use this instead of the classes configuration, not as another independent level system. The CSS text-indent guide covers first-line and hanging indentation. CKEditor's block indentation moves a whole block; it does not configure that first-line effect.

For the transcript, select the explanatory paragraph and increase indentation once. Wrap the text onto several lines in the reader view. Every line should share the inset, rather than only the first line beginning farther from the edge.

Diagnose list behavior from the selection

With Indent, IndentBlock, and List installed, the same toolbar controls can perform list nesting and visual list-container indentation. They are different operations. The current documentation describes visual container indentation when the selection is at the start of the topmost list, including Tab or Shift+Tab. A selection inside a list item can instead involve its list behavior.

Test the transcript with a numbered question and a follow-up item. Use the application's nesting action on the follow-up, then inspect the serialized list structure. The follow-up should belong under its question. A margin on an ol changes where the whole list sits; it does not establish that relationship.

Imported li margin values are also a separate case. CKEditor's documentation says it recognizes those values on load, while the UI can reset them under the documented conditions. Do not promise arbitrary per-item margin editing from the existence of imported styles.

Call the block command when that is the intended action

An application action dedicated to block spacing can use the documented command:

editor.execute('indentBlock');
// Opposite action:
editor.execute('outdentBlock');

Here editor is the initialized instance with IndentBlock installed. Treat these as alternative actions and preserve the intended selection. Generic indent and outdent commands delegate to block or list commands depending on availability.

Save and reopen the transcript. Read the speaker explanation at both a wide and narrow width, then inspect the follow-up question's list relationship. The inset should survive its CSS path, and the follow-up should remain attached to the question that prompted it.

Keep reading