Export with inline styles
The export with inline styles feature applies the styles defined by CSS style sheets directly on HTML elements. For example, a global <p class="red">
style defining the font color to be red, will be turned into <p style="color: red">
. This is especially useful for email creation but may be helpful in other use cases.
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
Use the Source editing command
to see changes. Check the output below to see the exported content with inline styles applied.Switch the tabs below to see three different outputs: the HTML tags with classes, CSS styles, and the HTML with those styles inlined. The last output shows how the exported content would look like.
The preview below shows the rendered content with inlined styles.
This demo presents a limited set of features. Visit the feature-rich editor example to see more in action.
# 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 { ClassicEditor } from 'ckeditor5';
import { ExportInlineStyles } from 'ckeditor5-premium-features';
ClassicEditor
.create( document.querySelector( '#editor' ), {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [ ExportInlineStyles, /* ... */ ],
exportInlineStyles: {
// Configuration.
}
} )
.then( editor => {
editor.execute( 'exportInlineStyles' )
.then( html => {
console.log( 'Email-ready content with proper HTML attributes:', html );
} );
// ...
} )
.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
The export with inline styles feature can be configured using the exportInlineStyles
configuration object:
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
stylesheets: [ './path/to/custom-styles.css' ],
inlineCss: `
.ck-content {
.warning { color: red; }
.note { background: yellow; }
}
`,
stripCssClasses: true
// ...
}
} )
# Stylesheets
An array with paths to CSS files to process. The order matters as later files can override styles from earlier ones. The distinct 'EDITOR_STYLES'
token includes default editor content styles. The option defaults to [ 'EDITOR_STYLES' ]
.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
stylesheets: [
'./path/to/base-styles.css', // Processed first.
'./path/to/theme-styles.css', // Can override base styles.
'./path/to/custom-styles.css' // Has highest priority.
]
// ...
}
} )
The 'EDITOR_STYLES'
token is supported only in legacy custom builds with webpack or DLLs. In other setups, you need to provide style sheet paths explicitly.
⚠️ CSS selectors must include the .ck-content
prefix
Styles without this prefix will be ignored during the inline styles transformation. You can use CSS nesting with .ck-content
as the parent:
For example:
/* ❌ This style will be ignored */
.warning { color: red; }
/* ✅ This style will be processed - flat approach */
.ck-content .warning { color: red; }
/* ✅ This style will be processed - nested approach */
.ck-content {
.warning { color: red; }
}
⚠️ Direct styles on .ck-content
are inherited by first-level children
Any styles set directly on the .ck-content
element will be copied to all its direct children during export. This is because the .ck-content
element itself is synthetic and not part of the exported content.
For example, if you define styles like color: red
and font-family: Arial
on .ck-content
, all first-level elements such as paragraphs and lists will have these styles directly applied to them in the exported content. This inheritance only applies to first-level children, not to deeper descendants.
# Inline CSS
A string containing CSS rules to apply after processing the external style sheets. Useful for adding supplemental styles without external files. The option defaults to an empty string.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
inlineCss: `
.ck-content {
/* Styles directly applied to .ck-content */
color: blue;
font-family: Arial;
/* Nested styles for children */
.warning {
color: red;
font-weight: bold;
}
.highlight {
background: yellow;
}
}
`
// ...
}
} )
# Strip CSS classes
When set to true
, the feature will remove the CSS classes from elements after inline styles are applied. This ensures the exported content preserves styling without depending on external style sheets. The option defaults to false
.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
stripCssClasses: true
// ...
}
} )
# Transformations
An array of functions that allow you to modify the elements and their styles before applying inline styles. Each function receives the element and a stylesMap
object, which contains the computed styles for that element. You can use this to add, remove, or modify styles based on your needs.
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
transformations: [
( element, stylesMap ) => {
// Example transformation: Add a custom attribute to all paragraphs.
if ( element.tagName === 'P' ) {
element.setAttribute( 'data-paragraph', 'true' );
}
}
]
// ...
}
} )
We also provide a handy transformation helper for email creation use cases. These transformations improve compatibility with email clients by converting modern CSS properties to better-supported HTML attributes.
import { ClassicEditor } from 'ckeditor5';
import { ExportInlineStyles, getEmailInlineStylesTransformations } from 'ckeditor5-premium-features';
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ... Other configuration options ...
exportInlineStyles: {
// Add email-specific transformations to the editor configuration.
transformations: getEmailInlineStylesTransformations()
// ...
}
} )
.then( editor => {
// When exporting content, the email transformations will be applied automatically.
editor.execute( 'exportInlineStyles' )
.then( html => {
console.log( 'Email-ready content with proper HTML attributes:', html );
} );
} )
.catch( error => {
console.error( error );
} );
# Usage
To export the editor content with inline styles, use the ExportInlineStyles
command:
editor.execute( 'exportInlineStyles' )
.then( ( html ) => {
console.log( html );
} )
.catch( ( error ) => {
console.error( error );
} );
You can also pass configuration options directly to the command. These options will override any editor configuration settings:
editor.execute( 'exportInlineStyles', {
stylesheets: [ './path/to/custom-styles.css' ],
inlineCss: '.ck-content .warning { color: red; }',
stripCssClasses: true,
transformations: [ /* custom transformations */ ]
} )
.then( ( html ) => {
console.log( html );
} )
.catch( ( error ) => {
console.error( error );
} );
The command outputs the exported content as an HTML string with inline styles applied. You can then use the content in email templates, CMS systems, or other environments where external CSS is not supported.
⚠️ One-way transformation
The exported content should not be loaded back to the editor. The content with inlined styles will render depending on the editor’s configuration and the UI of some features may not work correctly.
If you want to save the content with inlined styles, make sure to save the getData
output as well as exportInlineStyles
. Always load the editor with the getData
output.
If you need to load content with inlined styles consider using the General HTML Support (“GHS”) feature. However, it may lose some of the original styling and document structure.
# Style transformations
The export with inline styles feature allows you to apply custom transformations to elements before inline styles are applied. Transformations enable you to modify elements and their styles programmatically during the export process.
# When transformations are invoked
Transformations are called for each element in the DOM tree during the export process:
- Child elements are processed first, before their parent elements.
- For each element, the transformation is executed immediately before inline styles are assigned to the element.
This execution order gives you powerful control over the exported content:
- You can modify the element’s attributes and styles just before they are finalized.
- You can add or remove styles from the
stylesMap
to customize the final appearance. - You can manipulate the element’s children (add, remove, or modify) since they are already processed when the parent’s transformation is called.
- You can even remove elements completely from the output if needed.
# Example transformation
transformations: [
( element, stylesMap ) => {
// Add a new style.
if ( element.tagName === 'P' ) {
stylesMap.set( 'line-height', '1.5' );
}
// Remove a style.
if ( element.classList.contains( 'no-margin' ) ) {
stylesMap.delete( 'margin' );
}
// Modify child structure.
if ( element.classList.contains( 'box' ) ) {
// Remove unwanted child elements.
const unwantedElements = Array.from( element.querySelectorAll( '.remove-me' ) );
unwantedElements.forEach( el => el.remove() );
// Add new child element.
const disclaimer = document.createElement( 'div' );
disclaimer.textContent = 'Important notice';
element.appendChild( disclaimer );
}
}
]
This processing approach provides flexibility for implementing complex export logic while ensuring all styles are properly applied to the modified DOM structure.
# Real-world example
Here is a simple example showing how to use this feature to export content for an email message:
// Button that exports the editor content for email use.
document.querySelector( '#export-for-email' ).addEventListener( 'click', () => {
// Get content with inline styles with configuration options.
editor.execute( 'exportInlineStyles', {
// Specify which root to use (useful in multi-root editors).
rootName: 'main',
// Override editor configuration with email-specific settings.
stylesheets: [ './email-styles.css' ],
inlineCss: `
.ck-content {
font-family: Arial, sans-serif;
.quote { font-style: italic; }
}
`,
stripCssClasses: true,
// Apply email-specific transformations.
transformations: [
( element, stylesMap ) => {
// Make all links color blue and underlined for better email client compatibility.
if ( element.tagName === 'A' ) {
stylesMap.set( 'color', '#0066cc' );
stylesMap.set( 'text-decoration', 'underline' );
}
// Ensure all images have explicit width/height (helps with email rendering).
if ( element.tagName === 'IMG' && !element.getAttribute( 'width' ) ) {
element.setAttribute( 'width', '300px' );
element.setAttribute( 'height', '100px' );
}
// Ensure paragraphs have margin for email spacing.
if ( element.tagName === 'P' ) {
stylesMap.set( 'margin-bottom', '16px' );
}
}
],
// Remove all classes to prevent dependency on external CSS.
stripCssClasses: true
} )
.then( htmlWithInlineStyles => {
// Use the exported content in your email sending logic.
sendEmail( {
subject: 'Newsletter',
content: htmlWithInlineStyles,
recipients: [ 'user@example.com' ]
} );
} )
.catch( error => {
console.error( 'Failed to export content:', error );
} );
} );
// Example email sending function (would be replaced with your actual email API).
function sendEmail( emailData ) {
console.log( 'Sending email with inline-styled content:', emailData );
// Your email API call would go here:
// emailAPI.send( emailData );
}
# Compatibility
# Supported features
- Basic CSS properties (
color
,background-color
,font-family
, etc.) - Compound properties (
background
,margin
,padding
, etc.) - CSS variables (resolved during export)
- Simple CSS selectors (
class
,id
,element
)
Supported pseudo-classes:
- Structural pseudo-classes:
:first-child
:last-child
:nth-child()
:only-child
:empty
:nth-of-type()
:first-of-type
:last-of-type
- Logical pseudo-classes:
:matches()
:not()
:is()
- Root pseudo-class:
:root
# Limited or unsupported features
media
queries@import
and@font-face
rules@keyframes
andanimation
propertiestransition
properties:before
and:after
pseudo-elements- Interactive state pseudo-classes:
:focus
:visited
:link
:hover
:active
- Shadow DOM and
::part()
selectors
# Related features
Here are some other CKEditor 5 features that work well with the export with inline styles feature:
- Email configuration helper – Ensure email-compatible content structure and validate against email client restrictions.
- General HTML support – Add support for additional HTML elements and attributes in your content.
- Style – Apply predefined styles to content elements that can be exported as inline styles.
- Layout tables – Layout tables are used to structure a web page content spatially rather than for presenting tabular data.
# Common API
The ExportInlineStyles
plugin registers the ExportInlineStyles
command.
It accepts the optional rootName
configuration parameter, which determines the editor root to use for content origin.
We recommend using the official CKEditor 5 inspector for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.
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.