guideCollaborative document editor

CKEditor 5 is a highly flexible framework that was created with collaboration in mind. It lets you build your custom editor of any type, with any set of features and the toolbar type that you need where multiple authors can easily work on the same rich text documents. This feature-rich editor also brings many edition- and management-enhancing tools to the table, turning it into a full-fledged editing experience comparable with the most popular solutions such as Google Docs or Microsoft Word.

Share the complete URL of this page with your colleagues to collaborate in real time!

By default, CKEditor 5 filters out any content that is unsupported by its plugins and configuration. Check out the General HTML Support (“GHS”) feature that allows you to enable HTML features that are not explicitly supported by any other dedicated CKEditor 5 plugins.

# Editor example configuration

To set up this feature-rich demo locally, you need to follow the Building the editor from source guide. However, you need to use the configuration files provided below:

Packages installation
npm install --save \
    @ckeditor/ckeditor5-alignment \
    @ckeditor/ckeditor5-autoformat \
    @ckeditor/ckeditor5-basic-styles \
    @ckeditor/ckeditor5-block-quote \
    @ckeditor/ckeditor5-ckbox \
    @ckeditor/ckeditor5-cloud-services \
    @ckeditor/ckeditor5-code-block \
    @ckeditor/ckeditor5-dev-utils \
    @ckeditor/ckeditor5-document-outline \
    @ckeditor/ckeditor5-editor-classic \
    @ckeditor/ckeditor5-essentials \
    @ckeditor/ckeditor5-export-pdf \
    @ckeditor/ckeditor5-export-word \
    @ckeditor/ckeditor5-find-and-replace \
    @ckeditor/ckeditor5-font \
    @ckeditor/ckeditor5-format-painter \
    @ckeditor/ckeditor5-heading \
    @ckeditor/ckeditor5-highlight \
    @ckeditor/ckeditor5-horizontal-line \
    @ckeditor/ckeditor5-html-embed \
    @ckeditor/ckeditor5-image \
    @ckeditor/ckeditor5-indent \
    @ckeditor/ckeditor5-language \
    @ckeditor/ckeditor5-link \
    @ckeditor/ckeditor5-list \
    @ckeditor/ckeditor5-media-embed \
    @ckeditor/ckeditor5-mention \
    @ckeditor/ckeditor5-page-break \
    @ckeditor/ckeditor5-paste-from-office \
    @ckeditor/ckeditor5-remove-format \
    @ckeditor/ckeditor5-slash-command \
    @ckeditor/ckeditor5-special-characters \
    @ckeditor/ckeditor5-table \
    @ckeditor/ckeditor5-table-of-contents \
    @ckeditor/ckeditor5-template \
    @ckeditor/ckeditor5-theme-lark \
    @ckeditor/ckeditor5-typing \
    @ckeditor/ckeditor5-word-count \
    @webspellchecker/wproofreader-ckeditor5 \
    @ckeditor/ckeditor5-comments \
    @ckeditor/ckeditor5-track-changes \
    @ckeditor/ckeditor5-revision-history \
    @ckeditor/ckeditor5-real-time-collaboration
Editor configuration script (app.js in the customized installation guide)
import { DecoupledEditor } from '@ckeditor/ckeditor5-editor-decoupled';

import { Alignment } from '@ckeditor/ckeditor5-alignment';
import { Autoformat } from '@ckeditor/ckeditor5-autoformat';
import { BlockQuote } from '@ckeditor/ckeditor5-block-quote';
import {
    Bold,
    Code,
    Italic,
    Strikethrough,
    Subscript,
    Superscript,
    Underline
} from '@ckeditor/ckeditor5-basic-styles';
import { CKBox } from '@ckeditor/ckeditor5-ckbox';
import { CloudServices } from '@ckeditor/ckeditor5-cloud-services';
import { CodeBlock } from '@ckeditor/ckeditor5-code-block';
import { Essentials } from '@ckeditor/ckeditor5-essentials';
import { ExportPdf } from '@ckeditor/ckeditor5-export-pdf';
import { ExportWord } from '@ckeditor/ckeditor5-export-word';
import { FindAndReplace } from '@ckeditor/ckeditor5-find-and-replace';
import { Font } from '@ckeditor/ckeditor5-font';
import { FormatPainter } from '@ckeditor/ckeditor5-format-painter';
import { GeneralHtmlSupport } from '@ckeditor/ckeditor5-html-support';
import { Heading } from '@ckeditor/ckeditor5-heading';
import { Highlight } from '@ckeditor/ckeditor5-highlight';
import { HorizontalLine } from '@ckeditor/ckeditor5-horizontal-line';
import { HtmlEmbed } from '@ckeditor/ckeditor5-html-embed';
import { MediaEmbed } from '@ckeditor/ckeditor5-media-embed';
import {
    Image,
    ImageCaption,
    ImageInsert,
    ImageResize,
    ImageStyle,
    ImageToolbar,
    ImageUpload,
    AutoImage,
    PictureEditing
} from '@ckeditor/ckeditor5-image';
import { ImportWord } from '@ckeditor/ckeditor5-import-word';
import {
    Indent,
    IndentBlock
} from '@ckeditor/ckeditor5-indent';
import {
    Link,
    LinkImage,
    AutoLink
} from '@ckeditor/ckeditor5-link';
import {
    List,
    ListProperties
} from '@ckeditor/ckeditor5-list';
import { Mention } from '@ckeditor/ckeditor5-mention';
import { PageBreak } from '@ckeditor/ckeditor5-page-break';
import { Pagination } from '@ckeditor/ckeditor5-pagination';
import { Paragraph } from '@ckeditor/ckeditor5-paragraph';
import { PasteFromOffice } from '@ckeditor/ckeditor5-paste-from-office';
import { RemoveFormat } from '@ckeditor/ckeditor5-remove-format';
import { SlashCommand } from '@ckeditor/ckeditor5-slash-command';
import {
    SpecialCharacters,
    SpecialCharactersEssentials
} from '@ckeditor/ckeditor5-special-characters';
import { Style } from '@ckeditor/ckeditor5-style';
import {
    Table,
    TableCaption,
    TableCellProperties,
    TableColumnResize,
    TableProperties,
    TableToolbar
} from '@ckeditor/ckeditor5-table';
import {
    TableOfContents,
    DocumentOutline
} from '@ckeditor/ckeditor5-document-outline';
import { Template } from '@ckeditor/ckeditor5-template';
import { TextTransformation } from '@ckeditor/ckeditor5-typing';
import { WordCount } from '@ckeditor/ckeditor5-word-count';
import WProofreader from '@webspellchecker/wproofreader-ckeditor5/src/wproofreader';
import { ButtonView } from '@ckeditor/ckeditor5-ui';
import { Comments } from '@ckeditor/ckeditor5-comments';
import { TrackChanges } from '@ckeditor/ckeditor5-track-changes';
import { RevisionHistory } from '@ckeditor/ckeditor5-revision-history';
import {
    PresenceList,
    RealTimeCollaborativeRevisionHistory,
    RealTimeCollaborativeTrackChanges,
    RealTimeCollaborativeEditing,
    RealTimeCollaborativeComments
} from '@ckeditor/ckeditor5-real-time-collaboration';
import { handleDocIdInUrl } from './_utils/document-id-in-url.js';
import buildUserTokenUrl from './_utils/buildusertokenurl.js';
import generateComments from './_utils/generatecomments.js';
import generateSuggestions from './_utils/generatesuggestions.js';
import { randomUserFromAPI } from './_utils/randomuser.js';

const channelId = handleDocIdInUrl();
const csConfig = {
    // PROVIDE CORRECT VALUES HERE:
    tokenUrl: 'https://example.com/cs-token-endpoint'
    uploadUrl: 'https://example.com/upload/',
    webSocketUrl: 'https://example.com/ws'
};

const initialCommentsData = {
    // example initial comment data
    user: {
        id: '1',
        name: 'John Doe',
        email: 'john.doe@example.com',
        avatar: 'https://randomuser.me/api/portraits/thumb/men/99.jpg'
    },
    comments: {
        thread1: [
            '<p>We need to insert a table with late fees.</p>'
        ],
        thread2: [
            '<p>Here\'s a place for the description of services.</p>'
        ]
    }
};

const initialSuggestionsData = {
    // example initial user
    user: {
        id: '2',
        name: 'Jane Doe',
        email: 'jane.doe@example.com',
        avatar: 'https://randomuser.me/api/portraits/thumb/women/97.jpg'
    },
    suggestions: [
        {
            id: 's1',
            type: 'insertion',
            data: null
        }
    ]
};

const initialData = `
    initial editor content
`;

// templates icons
import articleImageRightIcon from '../../assets/img/article-image-right.svg';
import financialReportIcon from '../../assets/img/financial-report.svg';
import formalLetterIcon from '../../assets/img/formal-letter.svg';
import resumeIcon from '../../assets/img/resume.svg';
import richTableIcon from '../../assets/img/rich-table.svg';
import todoIcon from '../../assets/img/todo.svg';

// eslint-disable-next-line max-len
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>';
// eslint-disable-next-line max-len
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 ) {
    if ( document.querySelector( '.ck-document-outline-toggle' ) ) {
        return;
    }

    const button = new ButtonView( editor.locale );
    const documentOutlineContainer = editor.config.get( 'documentOutline.container' );
    const demoContainer = documentOutlineContainer.closest( '.demo-container' );
    demoContainer.classList.add( 'collapsed' );

    button.set( {
        label: 'Toggle document outline',
        class: 'ck-document-outline-toggle',
        tooltip: 'Show document outline',
        tooltipPosition: 'se',
        icon: DOCUMENT_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 );
}

generateComments( csConfig, channelId, initialCommentsData )
    .catch( error => console.error( error ) )
    .then( generateSuggestions( csConfig, channelId, initialSuggestionsData ) )
    .catch( error => console.error( error ) )
    .then( () => randomUserFromAPI() )
    .then( randomUser => {
        csConfig.tokenUrl = buildUserTokenUrl( csConfig.tokenUrl, randomUser );

        DecoupledEditor
            .create( document.querySelector( '.editor-content' ), {
                initialData,
                ui: {
                    viewportOffset: {
                        top: window.getViewportTopOffsetConfig()
                    }
                },
                plugins: [
                    Autoformat, BlockQuote, Bold, Heading, Image, ImageCaption, FormatPainter,
                    ImageStyle, ImageToolbar, Indent, Italic, Link, List, MediaEmbed,
                    Paragraph, Table, TableToolbar, Alignment, AutoImage, AutoLink,
                    CKBox, CloudServices, Code, CodeBlock, Essentials, ExportPdf,
                    ExportWord, ImportWord, FindAndReplace, Font, Highlight, HorizontalLine,
                    HtmlEmbed, ImageInsert, ImageResize, ImageUpload, IndentBlock, GeneralHtmlSupport,
                    LinkImage, ListProperties, Mention, PageBreak, Pagination, PasteFromOffice,
                    PictureEditing, RemoveFormat, SlashCommand, SpecialCharacters,
                    SpecialCharactersEssentials, Style, Strikethrough, Subscript, Superscript,
                    TableCaption, TableCellProperties, TableColumnResize,
                    TableProperties, TableOfContents, Template, TextTransformation,
                    Underline, WordCount, WProofreader, DocumentOutline, DocumentOutlineToggler,
                    PresenceList, Comments, TrackChanges, RevisionHistory, RealTimeCollaborativeComments,
                    RealTimeCollaborativeEditing, RealTimeCollaborativeTrackChanges, RealTimeCollaborativeRevisionHistory
                ],
                toolbar: {
                    items: [
                        'undo', 'redo',
                        '|',
                        'previousPage',
                        'nextPage',
                        'pageNavigation',
                        '|',
                        'comment', 'commentsArchive', 'trackChanges', 'revisionHistory',
                        '|',
                        'exportPdf', 'exportWord', 'importWord',
                        '|',
                        'formatPainter', 'findAndReplace', 'selectAll', 'wproofreader',
                        '|',
                        'heading',
                        '|',
                        'style',
                        '|',
                        'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
                        '|',
                        'bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript', 'code',
                        '|',
                        'removeFormat',
                        '|',
                        'specialCharacters', 'horizontalLine', 'pageBreak',
                        '|',
                        'link', 'insertImage', 'ckbox', 'insertTable', 'tableOfContents', 'insertTemplate',
                        'highlight', 'blockQuote', 'mediaEmbed', 'codeBlock', 'htmlEmbed',
                        '|',
                        'alignment',
                        '|',
                        'bulletedList',	'numberedList',	'outdent', 'indent'
                    ],
                    shouldNotGroupWhenFull: true
                },
                pagination: {
                    pageWidth: '21cm',
                    pageHeight: '29.7cm',
                    pageMargins: {
                        top: '20mm',
                        bottom: '20mm',
                        right: '12mm',
                        left: '12mm'
                    }
                },
                exportPdf: {
                    // This callback makes the exported PDF include tracked changes.
                    dataCallback: editor => editor.getData( {
                        showSuggestionHighlights: true
                    } ),
                    stylesheets: [
                        '../../assets/pagination-fonts.css',
                        'EDITOR_STYLES',
                        '../../snippets/features/pagination/snippet.css',
                        '../../assets/pagination.css'
                    ],
                    fileName: 'export-pdf-demo.pdf',
                    appID: 'cke5-docs',
                    converterOptions: {
                        format: 'Tabloid',
                        margin_top: '20mm',
                        margin_bottom: '20mm',
                        margin_right: '24mm',
                        margin_left: '24mm',
                        page_orientation: 'portrait'
                    },
                    // PROVIDE CORRECT VALUES HERE:
                    tokenUrl: 'https://example.com/cs-token-endpoint'
                },
                exportWord: {
                    stylesheets: [ 'EDITOR_STYLES' ],
                    fileName: 'export-word-demo.docx',
                    appID: 'cke5-docs',
                    converterOptions: {
                        format: 'B4',
                        margin_top: '20mm',
                        margin_bottom: '20mm',
                        margin_right: '12mm',
                        margin_left: '12mm',
                        page_orientation: 'portrait'
                    },
                    // PROVIDE CORRECT VALUES HERE:
                    tokenUrl: 'https://example.com/cs-token-endpoint'
                },
                fontFamily: {
                    supportAllValues: true
                },
                fontSize: {
                    options: [ 10, 12, 14, 'default', 18, 20, 22 ],
                    supportAllValues: true
                },
                htmlEmbed: {
                    showPreviews: true
                },
                image: {
                    styles: [
                        'alignCenter',
                        'alignLeft',
                        'alignRight'
                    ],
                    resizeOptions: [
                        {
                            name: 'resizeImage:original',
                            label: 'Original',
                            value: null
                        },
                        {
                            name: 'resizeImage:50',
                            label: '50%',
                            value: '50'
                        },
                        {
                            name: 'resizeImage:75',
                            label: '75%',
                            value: '75'
                        }
                    ],
                    toolbar: [
                        'imageTextAlternative',
                        'toggleImageCaption',
                        '|',
                        'imageStyle:inline',
                        'imageStyle:wrapText',
                        'imageStyle:breakText',
                        '|',
                        'resizeImage'
                    ]
                },
                list: {
                    properties: {
                        styles: true,
                        startIndex: true,
                        reversed: true
                    }
                },
                link: {
                    decorators: {
                        addTargetToExternalLinks: true,
                        defaultProtocol: 'https://',
                        toggleDownloadable: {
                            mode: 'manual',
                            label: 'Downloadable',
                            attributes: {
                                download: 'file'
                            }
                        }
                    }
                },
                mention: {
                    feeds: [
                        {
                            marker: '@',
                            feed: [
                                '@apple', '@bears', '@brownie', '@cake', '@cake', '@candy',
                                '@canes', '@chocolate', '@cookie', '@cotton', '@cream',
                                '@cupcake', '@danish', '@donut', '@dragée', '@fruitcake',
                                '@gingerbread', '@gummi', '@ice', '@jelly-o', '@liquorice',
                                '@macaroon', '@marzipan', '@oat', '@pie', '@plum', '@pudding',
                                '@sesame', '@snaps', '@soufflé', '@sugar', '@sweet', '@topping', '@wafer'
                            ],
                            minimumCharacters: 0
                        }
                    ]
                },
                importWord: {
                // PROVIDE CORRECT VALUES HERE:
                    tokenUrl: 'https://example.com/cs-token-endpoint'
                },
                placeholder: 'Type or paste your content here!',
                table: {
                    contentToolbar: [
                        'tableColumn',
                        'tableRow',
                        'mergeTableCells',
                        'tableProperties',
                        'tableCellProperties',
                        'toggleTableCaption'
                    ]
                },
                        template: {
                            definitions: [
                                {
                                    title: 'The title of the template',
                                    description: 'A longer description of the template',
                                    data: '<p>Data inserted into the content</p>'
                                },
                                {
                                    // ...
                                },
                                // More template definitions.
                                // ...
                            ]
                },
                style: {
                    definitions: [
                        {
                            name: 'Article category',
                            element: 'h3',
                            classes: [ 'category' ]
                        },
                        {
                            name: 'Title',
                            element: 'h2',
                            classes: [ 'document-title' ]
                        },
                        {
                            name: 'Subtitle',
                            element: 'h3',
                            classes: [ 'document-subtitle' ]
                        },
                        {
                            name: 'Info box',
                            element: 'p',
                            classes: [ 'info-box' ]
                        },
                        {
                            name: 'Side quote',
                            element: 'blockquote',
                            classes: [ 'side-quote' ]
                        },
                        {
                            name: 'Marker',
                            element: 'span',
                            classes: [ 'marker' ]
                        },
                        {
                            name: 'Spoiler',
                            element: 'span',
                            classes: [ 'spoiler' ]
                        },
                        {
                            name: 'Code (dark)',
                            element: 'pre',
                            classes: [ 'fancy-code', 'fancy-code-dark' ]
                        },
                        {
                            name: 'Code (bright)',
                            element: 'pre',
                            classes: [ 'fancy-code', 'fancy-code-bright' ]
                        }
                    ]
                },
                documentOutline: {
                    container: document.querySelector( '.document-outline-container' )
                },
                wproofreader: {
                     // PROVIDE CORRECT VALUE HERE:
                    serviceId: 'service ID',
                    lang: 'auto',
                    srcUrl: 'https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js'
                },
                ckbox: {
                    // This editor configuration includes the CKBox feature.
                    // Provide correct configuration values to use it.
                    tokenUrl: 'https://example.com/cs-token-endpoint'
                    // Read more about CKBox - https://ckeditor.com/docs/ckeditor5/latest/features/images/image-upload/ckbox.html.
                    // For other image upload methods see the guide - https://ckeditor.com/docs/ckeditor5/latest/features/images/image-upload/image-upload.html.
                },
                collaboration: {
                    channelId
                },
                cloudServices: csConfig,
                sidebar: {
                    container: document.querySelector( '#sidebar-container' )
                },
                comments: {
                    editorConfig: {
                        extraPlugins: [ Bold, Italic, Autoformat ]
                    }
                },
                revisionHistory: {
                    editorContainer: document.querySelector( '.demo-container' ),
                    viewerContainer: document.querySelector( '#revision-viewer-container' ),
                    viewerEditorElement: document.querySelector( '#revision-viewer-editor' ),
                    viewerSidebarContainer: document.querySelector( '#revision-viewer-sidebar' )
                },
                presenceList: {
                    container: document.querySelector( '.presence' )
                },
                // PROVIDE CORRECT VALUES HERE:
                tokenUrl: 'https://example.com/cs-token-endpoint'
            } )
            .then( editor => {
                document.querySelector( '.toolbar-container' ).appendChild( editor.ui.view.toolbar.element );

                window.editor = editor;

                // Prevent showing a warning notification when user is pasting a content from MS Word or Google Docs.
                window.preventPasteFromOfficeNotification = true;

                document.querySelector( '.ck.ck-word-count-wrapper' ).appendChild( editor.plugins.get( 'WordCount' ).wordCountContainer );

                return editor;
            } )
            .then( () => {
                document.querySelector( '.live-snippet__loader' ).classList.add( 'fadeout' );
                document.querySelector( '.live-snippet__container' ).classList.add( 'loaded' );
            } )
            .catch( err => {
                console.error( err );
            } );
    } );

Editor content listing (index.html in the customized installation guide)
<!-- include CKBox from CDN -->
<script src="https://cdn.ckbox.io/ckbox/latest/ckbox.js"></script>

<div class="live-snippet__loader">
    <svg class="spinner" viewBox="25 25 50 50">
        <circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle>
    </svg>
</div>

<div class="live-snippet__container revision-integration">
    <div class="presence"></div>

    <div class="row">
        <div class="demo-container">
            <div class="toolbar-container"></div>
            <div class="document-outline-container"></div>

            <div class="editor-content-wrapper">
                <div class="editor-content">
                    Editor content is inserted here.
                </div>
                <div class="sidebar" id="sidebar-container"></div>
            </div>
        </div>

        <div id="revision-viewer-container">
            <div class="revision-editor-container">
                <div id="revision-viewer-editor"></div>
                <div class="sidebar" id="revision-viewer-sidebar"></div>
            </div>
        </div>
    </div>

    <div class="ck ck-word-count-wrapper"></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"
            "Content Content";
        background: var(--ck-color-base-foreground);
        border: 1px solid var(--ck-color-base-border);

        /* 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 .editing-area-scroll-wrapper{
        grid-area: Content;
        overflow: scroll;
        display: flex;
    }

    .demo-container .editing-area-wrapper {
        display: flex;
        flex: 1;
        width: fit-content;
    }

    .demo-container .editor-content-wrapper {
        max-height: var(--demo-content-height);

        /* Center the editor content in this grid area. */
        display: flex;
        flex:1;
        justify-content: center;
        align-items: flex-start;

        transform: translateZ(0); /* It is a hack for safari not repainting headings in document when unfolding document outline */
    }

    .demo-container .document-outline-container {
        max-height: var(--demo-content-height);
        padding: var(--ck-spacing-large) 0 0;
        display: flex;
        overflow-y: auto;
        /* Customize the default font size of the outline */
        --ck-document-outline-base-font-size: 1em;
    }

    .demo-container .document-outline-container .ck-document-outline{
        max-width: 350px;
        text-overflow: ellipsis;
    }

    .sidebar {
        min-width: 320px;
        padding-right: var(--ck-spacing-large);
    }

    #revision-viewer-container {
        display: none;
    }

    .revision-editor-container {
        display: flex;
    }

    .revision-editor-container .ck-editor {
        margin: 0;
    }

    .revision-editor-container .sidebar {
        border: 1px solid var(--ck-color-base-border);
    }

    #demo-container .ck.ck-editor {
        width: 860px;
    }
    #demo-container .sidebar {
        margin-left: 20px;
    }
    #demo-container .sidebar.narrow {
        width: 30px;
    }

    /* ------------ 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;
    }

    .demo-container .document-outline-container .ck-document-outline:empty::before {
        width: max-content;
    }

    /* 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;
    }

    .ck.ck-word-count {
        display: flex;
        justify-content: flex-end;

        background: var(--ck-color-toolbar-background);
        padding: var(--ck-spacing-small) var(--ck-spacing-standard);
        margin-bottom: 15px;
        border: 1px solid var(--ck-color-toolbar-border);
        border-top-width: 0;
        border-radius: 0 0 var(--ck-border-radius);
        box-shadow: 2px 2px 2px hsla(0,0%,0%,0.1);
    }

    .ck.ck-word-count .ck-word-count__words {
        margin-right: var(--ck-spacing-standard);
    }

    .live-snippet {
        min-height: 200px;
    }

    .live-snippet__container {
        overflow: visible;
        margin: 1.5em 0;
        opacity: 0;
        display: none;
    }

    .live-snippet__container.loaded {
        display: block;
        opacity: 1;
        animation: 300ms _fadein ease-in-out;
    }

    .live-snippet__loader {
        position: absolute;
        display: flex;
        justify-content: center;
        align-items: center;
        opacity: 1;
        width: 100%;
        text-align: center;
        margin: 50px auto;
    }

    .live-snippet__loader.fadeout {
        display: none;
        animation: 300ms _fadeout ease-in-out;
    }

    .live-snippet__loader .spinner {
        display: block;
        height: 75px;
        width: 75px;
    }

    .live-snippet__loader .spinner .path {
        stroke-dasharray: 1, 200;
        stroke-dashoffset: 0;
        animation: _spinner-color 6s ease-in-out infinite, _spinner-dash 1.5s ease-in-out infinite;
        stroke-linecap: round;
    }


    @keyframes _fadein {
        from {
            opacity: 0;
        }
        to {
            opacity: 1;
        }
    }

    @keyframes _fadeout {
        from {
            opacity: 1;
        }
        to {
            opacity: 0;
        }
    }

    @keyframes _spinner-color {
        100%,
        0% {
            stroke: #f75b4b;
        }

        40% {
            stroke: #0387d0;
        }

        66% {
            stroke: #1ebd60;
        }

        80%,
        90% {
            stroke: #8d44ad;
        }
    }

    @keyframes _spinner-dash {
        0% {
            stroke-dasharray: 1, 200;
            stroke-dashoffset: 0;
        }

        50% {
            stroke-dasharray: 89, 200;
            stroke-dashoffset: -35px;
        }

        100% {
            stroke-dasharray: 89, 200;
            stroke-dashoffset: -124px;
        }
    }

    /* ----------------------- Content styles ------------------------------ */

    /* Styles of the editor content container to make it look like a sheet of paper. */
    .editor-content.ck.ck-content {
        /* Min and max used to force width in flexbox. */
        min-width: 210mm;
        max-width: 210mm;
        min-height: 297mm;
        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;
        word-break: break-word;
    }

    .editor-content.ck.ck-content,
    .editor-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. */
    .editor-content.ck.ck-content h2 {
        font-size: 2.06em;
        line-height: 1.58em;
        padding-top: 0.455em;
        margin-bottom: 0.333em;
    }

    .editor-content.ck.ck-content h3 {
        font-size: 1.75em;
        line-height: 1.86em;
        padding-top: 0.571em;
        margin-bottom: 0.357em;
    }

    .editor-content.ck.ck-content h4 {
        font-size: 1.44em;
        line-height: 1.13em;
        padding-top: 0.217em;
        margin-bottom: 0.913em;
    }

    .editor-content.ck.ck-content h5 {
        font-size: 1.19em;
        line-height: 1.37em;
        padding-top: 0.368em;
        margin-bottom: 1.00em;
    }

    .editor-content.ck.ck-content p {
        font-size: 1.00em;
        line-height: 1.63em;
        padding-top: 0.500em;
        margin-bottom: 1.13em;
    }

    /* Styles dropdown styles */

    @import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=PT+Serif:ital,wght@0,400;0,700;1,400&display=swap');

    .ck.ck-content {
    /*	font-family: 'PT Serif', serif; */
        font-size: 16px;
        line-height: 1.6;
        padding: 2em;
    }

    .ck-content .ck-horizontal-line {
        margin-bottom: 1em;
    }

    .ck.ck-content h3.category {
        font-family: 'Bebas Neue';
        font-size: 20px;
        font-weight: bold;
        color: #555;
        letter-spacing: 10px;
        margin: 0;
        padding: 0;
    }

    .ck.ck-content h2.document-title {
        font-family: 'Bebas Neue';
        font-size: 50px;
        font-weight: bold;
        margin: 0;
        padding: 0;
        border: 0;
    }

    .ck.ck-content h3.document-subtitle {
        font-family: 'Bebas Neue';
        font-size: 20px;
        color: #555;
        margin: 0 0 1em;
        font-weight: normal;
        padding: 0;
    }

    .ck.ck-content p.info-box {
        --background-size: 30px;
        --background-color: #e91e63;
        padding: 1.2em 2em;
        border: 1px solid var(--background-color);
        background: linear-gradient(135deg, var(--background-color) 0%, var(--background-color) var(--background-size), transparent var(--background-size)), linear-gradient(135deg, transparent calc(100% - var(--background-size)), var(--background-color) calc(100% - var(--background-size)), var(--background-color));
        border-radius: 10px;
        margin: 1.5em 2em;
        box-shadow: 5px 5px 0 #ffe6ef;
    }

    .ck.ck-content blockquote.side-quote {
        font-family: 'Bebas Neue';
        font-style: normal;
        float: right;
        width: 35%;
        position: relative;
        border: 0;
        overflow: visible;
        z-index: 1;
        margin-left: 1em;
    }

    .ck.ck-content blockquote.side-quote::before {
        content: "“";
        position: absolute;
        top: -37px;
        left: -10px;
        display: block;
        font-size: 200px;
        color: #e7e7e7;
        z-index: -1;
        line-height: 1;
    }

    .ck.ck-content blockquote.side-quote p {
        font-size: 2em;
        line-height: 1;
    }

    .ck.ck-content blockquote.side-quote p:last-child:not(:first-child) {
        font-size: 1.3em;
        text-align: right;
        color: #555;
    }

    .ck.ck-content span.marker {
        background: yellow;
    }

    .ck.ck-content span.spoiler {
        background: #000;
        color: #000;
    }

    .ck.ck-content span.spoiler:hover {
        background: #000;
        color: #fff;
    }

    .ck.ck-content pre.fancy-code {
        border: 0;
        margin-left: 2em;
        margin-right: 2em;
        border-radius: 10px;
    }

    .ck.ck-content pre.fancy-code::before {
        content: "";
        display: block;
        height: 13px;
        background: url(data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1NCAxMyI+CiAgPGNpcmNsZSBjeD0iNi41IiBjeT0iNi41IiByPSI2LjUiIGZpbGw9IiNGMzZCNUMiLz4KICA8Y2lyY2xlIGN4PSIyNi41IiBjeT0iNi41IiByPSI2LjUiIGZpbGw9IiNGOUJFNEQiLz4KICA8Y2lyY2xlIGN4PSI0Ny41IiBjeT0iNi41IiByPSI2LjUiIGZpbGw9IiM1NkM0NTMiLz4KPC9zdmc+Cg==);
        margin-bottom: 8px;
        background-repeat: no-repeat;
    }

    .ck.ck-content pre.fancy-code-dark {
        background: #272822;
        color: #fff;
        box-shadow: 5px 5px 0 #0000001f;
    }

    .ck.ck-content pre.fancy-code-bright {
        background: #dddfe0;
        color: #000;
        box-shadow: 5px 5px 0 #b3b3b3;
    }

</style>