Document outline
The document outline feature displays the list of sections (headings) of the document next to the editor. The outline updates automatically as the user works on the document. It offers quick navigation to a specific section upon clicking.
Unlock this feature with a CKEditor Paid Plan. Sign up for a free trial, or select the Plan that provides access to all the premium features you need.
# Demo
When the feature is enabled and configured, the outline can be displayed next to the document as presented below. The placement of the outline is configurable and depends on the HTML structure of the integration. The demo below showcases one of the recommended integrations but more are possible. See the demo code to learn more.
This demo presents a limited set of features. Visit the feature-rich editor example to see more in action.
# Demo code
For the best user experience the document outline feature requires some effort from integrators. Because it renders independently from the rest of the editor user interface (toolbar, edited content), its placement, dimensions, and behavior (like toggling) depend on the layout and functionality of the web page.
The presented demo is a custom UI built on top of the DecoupledEditor
(similar to the document editor). The editor in this demo loads:
- A set of common editor plugins (
Essentials
,Bold
,Heading
, etc.). - The
DocumentOutline
plugin. - A custom
DocumentOutlineToggler
plugin created for this particular demo to allow toggling the visibility of the outline (learn more in the step-by-step tutorial).
You can find the entire integration code below.
View the editor configuration script
import {
DecoupledEditor,
Alignment,
Autoformat,
Bold,
Code,
Italic,
Strikethrough,
Subscript,
Superscript,
Underline,
BlockQuote,
CloudServices,
CodeBlock,
EasyImage,
Essentials,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
Heading,
HorizontalLine,
Image,
ImageCaption,
ImageResize,
ImageStyle,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Link,
List,
MediaEmbed,
PageBreak,
Paragraph,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersEssentials,
Table,
TableCellProperties,
TableProperties,
TableToolbar,
ButtonView
} from 'ckeditor5';
import { DocumentOutline } from 'ckeditor5-premium-features';
const DOCUMENT_OUTLINE_ICON = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M5 9.5a.5.5 0 0 0 .5-.5v-.5A.5.5 0 0 0 5 8H3.5a.5.5 0 0 0-.5.5V9a.5.5 0 0 0 .5.5H5Z"/><path d="M5.5 12a.5.5 0 0 1-.5.5H3.5A.5.5 0 0 1 3 12v-.5a.5.5 0 0 1 .5-.5H5a.5.5 0 0 1 .5.5v.5Z"/><path d="M5 6.5a.5.5 0 0 0 .5-.5v-.5A.5.5 0 0 0 5 5H3.5a.5.5 0 0 0-.5.5V6a.5.5 0 0 0 .5.5H5Z"/><path clip-rule="evenodd" d="M2 19a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2Zm6-1.5h10a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5H8v15Zm-1.5-15H2a.5.5 0 0 0-.5.5v14a.5.5 0 0 0 .5.5h4.5v-15Z"/></svg>';
const COLLAPSE_OUTLINE_ICON = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M11.463 5.187a.888.888 0 1 1 1.254 1.255L9.16 10l3.557 3.557a.888.888 0 1 1-1.254 1.255L7.26 10.61a.888.888 0 0 1 .16-1.382l4.043-4.042z"/></svg>';
// A custom simplified plugin to allow toggling the visibility of the outline.
function DocumentOutlineToggler( editor ) {
const button = new ButtonView( editor.locale );
const documentOutlineContainer = editor.config.get( 'documentOutline.container' );
const demoContainer = documentOutlineContainer.closest( '.demo-container' );
button.set( {
label: 'Toggle document outline',
class: 'ck-document-outline-toggle',
tooltip: 'Hide document outline',
tooltipPosition: 'se',
icon: COLLAPSE_OUTLINE_ICON
} );
button.on( 'execute', () => {
// Toggle a CSS class on the demo container to manage the visibility of the outline.
demoContainer.classList.toggle( 'collapsed' );
// Change the look of the button to reflect the state of the outline.
if ( demoContainer.classList.contains( 'collapsed' ) ) {
button.icon = DOCUMENT_OUTLINE_ICON;
button.tooltip = 'Show document outline';
} else {
button.icon = COLLAPSE_OUTLINE_ICON;
button.tooltip = 'Hide document outline';
}
// Keep the focus in the editor whenever the button is clicked.
editor.editing.view.focus();
} );
button.render();
// Append the button next to the outline in its container.
documentOutlineContainer.appendChild( button.element );
}
// Start the editor.
DecoupledEditor
.create( document.querySelector( '.editor-content' ), {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [
Alignment,
Autoformat,
BlockQuote,
Bold,
CloudServices,
Code,
CodeBlock,
DocumentOutline,
DocumentOutlineToggler,
EasyImage,
Essentials,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
Heading,
HorizontalLine,
Image,
ImageCaption,
ImageResize,
ImageStyle,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
List,
ListProperties,
MediaEmbed,
PageBreak,
Paragraph,
RemoveFormat,
SelectAll,
SpecialCharacters,
SpecialCharactersEssentials,
Strikethrough,
Subscript,
Superscript,
Table,
TableCellProperties,
TableProperties,
TableToolbar,
Underline
],
toolbar: [
'undo',
'redo',
'|',
'heading',
'|',
'fontFamily',
'fontSize',
'fontColor',
'fontBackgroundColor',
'|',
'bold',
'italic',
'underline',
'removeFormat',
'-',
'link',
'uploadImage',
'insertTable',
'blockquote',
'codeBlock',
'mediaEmbed',
'|',
'alignment',
'|',
'numberedList',
'bulletedList',
'indent',
'outdent'
],
shouldNotGroupWhenFull: true,
image: {
toolbar: [ 'imageStyle:inline', 'imageStyle:wrapText', 'imageStyle:breakText', '|', 'imageTextAlternative' ]
},
table: {
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ],
tableToolbar: [ 'bold', 'italic' ]
},
documentOutline: {
container: document.querySelector( '.document-outline-container' )
},
cloudServices: {
// This demo includes the Easy Image feature. Provide correct configuration values to use it.
tokenUrl: 'https://example.com/cs-token-endpoint',
uploadUrl: 'https://your-organization-id.cke-cs.com/easyimage/upload/'
// For other image upload methods see the guide - https://ckeditor.com/docs/ckeditor5/latest/features/images/image-upload/image-upload.html.
}
} ).then( editor => {
document.querySelector( '.toolbar-container' ).appendChild( editor.ui.view.toolbar.element );
window.editor = editor;
} ).catch( err => {
console.error( err.stack );
} );
View the page layout and styles
<div class="demo-container">
<div class="toolbar-container"></div>
<div class="document-outline-container"></div>
<div class="editor-content-wrapper">
<div class="editor-content">
<p>Initial content of the editor</p>
</div>
</div>
</div>
<style>
/* ----------------------- Demo layout styles ------------------------------ */
.demo-container {
display: grid;
grid-template-columns: minmax(250px,.5fr) 1.5fr;
grid-template-rows: auto 1fr;
gap: 0px 0px;
grid-template-areas:
"Toolbar Toolbar"
"Sidebar Content";
background: var(--ck-color-base-foreground);
border: 1px solid var(--ck-color-base-border);
margin: 1.5em 0;
/* The max height of the editor content wrapper before it becomes scrollable. */
--demo-content-height: 800px;
}
.demo-container .toolbar-container {
grid-area: Toolbar;
box-shadow: 0 2px 3px hsla(0, 0%, 0%, 0.078);
/* Makes the shadow display over the editor content. */
position: relative;
}
/* Adjust borders of the toolbar to fit well into the layout. Avoid duplicated borders. */
.demo-container .toolbar-container > .ck.ck-toolbar {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
border-top: 0;
border-left: 0;
border-right: 0;
}
.demo-container .editor-content-wrapper {
grid-area: Content;
max-height: var(--demo-content-height);
overflow-y: auto;
/* Center the editor content in this grid area. */
display: flex;
justify-content: center;
align-items: flex-start;
}
.demo-container .document-outline-container {
grid-area: Sidebar;
max-height: var(--demo-content-height);
overflow-y: auto;
display: flex;
flex-direction: column;
padding: var(--ck-spacing-large) 0 0;
/* Customize the default font size of the outline */
--ck-document-outline-base-font-size: 1em;
}
/* ------------ DocumentOutlineToggler plugin styles ------------------- */
/* Styles of the topmost demo container when the outline gets collapsed. */
.demo-container.collapsed {
grid-template-columns: 50px 1fr;
}
/* Styles of the outline when it gets collapsed. */
.demo-container.collapsed .document-outline-container .ck-document-outline {
width: 0px;
margin: 0;
padding: 0;
overflow: hidden;
height: 0;
}
/* Styles of the outline collapse button. */
.demo-container .document-outline-container .ck-document-outline-toggle {
align-self: flex-start;
opacity: .5;
margin-left: var(--ck-spacing-large);
border-radius: 100%;
}
.demo-container .document-outline-container .ck-document-outline-toggle:hover {
opacity: 1;
}
/* ----------------------- Content styles ------------------------------ */
/* Styles of the editor content container to make it look like a sheet of paper. */
.ck.ck-content {
max-width: calc( 210mm + 2px );
min-height: calc( 210mm + 2px );
height: auto;
padding: 20mm 12mm;
box-sizing: border-box;
background: hsl( 0, 0%, 100% );
box-shadow: 0 2px 8px hsla( 0, 0%, 0%, .08 );
margin: calc( 2 * var(--ck-spacing-large) );
overflow: hidden;
flex: 1 1 auto;
}
.ck.ck-content,
.ck.ck-content.ck-focused {
border: 1px solid hsl( 0, 0%, 88% );
box-shadow: 0 2px 8px hsla( 0, 0%, 0%, .08 );
}
/* Vertical rhythm of the blocks in the editor content below. */
.ck.ck-content h2 {
font-size: 2.06em;
line-height: 1.58em;
padding-top: 0.455em;
margin-bottom: 0.333em;
}
.ck.ck-content h3 {
font-size: 1.75em;
line-height: 1.86em;
padding-top: 0.571em;
margin-bottom: 0.357em;
}
.ck.ck-content h4 {
font-size: 1.44em;
line-height: 1.13em;
padding-top: 0.217em;
margin-bottom: 0.913em;
}
.ck.ck-content h5 {
font-size: 1.19em;
line-height: 1.37em;
padding-top: 0.368em;
margin-bottom: 1.00em;
}
.ck.ck-content p {
font-size: 1.00em;
line-height: 1.63em;
padding-top: 0.500em;
margin-bottom: 1.13em;
}
</style>
# Installation
⚠️ New import paths
Starting with version 42.0.0, we changed the format of import paths. This guide uses the new, shorter format. Refer to the Packages in the legacy setup guide if you use an older version of CKEditor 5.
After installing the editor, add the feature to your plugin list and toolbar configuration:
import { DecoupledEditor } from 'ckeditor5';
import { DocumentOutline } from 'ckeditor5-premium-features';
DecoupledEditor
.create( document.querySelector( '#editor' ), {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [ DocumentOutline, /* ... */ ],
documentOutline: {
container: document.querySelector( '.document-outline-container' ),
}
} )
.then( /* ... */ )
.catch( /* ... */ );
# Activating the feature
To use this premium feature, you need to activate it with proper credentials. Refer to the License key and activation guide for details.
# Configuration
For more technical details, check the plugin configuration reference.
# Configuring the container
The container element is essential for the document outline to render. You should pass the reference to the container element in the config.documentOutline.container
configuration option.
documentOutline: {
// Make sure the .document-outline-container element exists when the editor is being created.
container: document.querySelector( '.document-outline-container' )
}
# Customizing the look
The look of the document outline can be customized using CSS classes and custom properties. In the demo below, the following customizations were applied:
- The indentation of outline items was reduced (custom properties:
--ck-document-outline-indent-level-[2-3]
). - The active item color was changed (
--ck-document-outline-item-active-color
custom property). - The font size and line height were reduced for a more compact look (
.ck-document-outline__item
CSS class). - Different bullets were added for each level for better readability (
.ck-document-outline__item_level-[2-3]
CSS classes).
View the document outline customization code
.customization-demo {
--ck-document-outline-indent-level-2: 1.1em;
--ck-document-outline-indent-level-3: 2.2em;
--ck-document-outline-item-active-color: hsl(340deg 82% 52%);
}
.customization-demo .ck-document-outline__item {
line-height: 1.1em;
}
.customization-demo .ck-document-outline__item::before {
margin: 0 .2em 0 0;
}
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-2::before,
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-5::before {
content: "•";
}
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-3 {
font-size: .9em;
}
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-3::before,
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-6::before {
content: "‣";
}
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-4,
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-5,
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-6 {
font-size: .8em;
}
.customization-demo .ck-document-outline__item.ck-document-outline__item_level-4::before {
content: "⁃";
}
# Related features
Here are some more CKEditor 5 features that can help you navigate the content of the editor:
- Table of contents – Insert a table of contents widget into the document.
- Content minimap – Navigate the document using a miniature overview map placed next to the editor.
- Pagination – See the live preview of the document’s page breaks and quickly navigate between pages.
Every day, we work hard to keep our documentation complete. Have you spotted outdated information? Is something missing? Please report it via our issue tracker.
With the release of version 42.0.0, we have rewritten much of our documentation to reflect the new import paths and features. We appreciate your feedback to help us ensure its accuracy and completeness.