Inline CSS plugin
This plugin is only available for paid TinyMCE subscriptions. |
This feature is only available for TinyMCE 6.3 and later. |
As is normal and long-time best practice, TinyMCE documents keep CSS and HTML separate. This practice is not, however, email-friendly.
The Inline CSS plugin takes a TinyMCE document, and processes it such that the previously separate CSS is applied inline to each HTML element. This single output file is much closer to the common requirements for sending as an HTML-formatted email.
Interactive example
-
TinyMCE
-
HTML
-
JS
-
Edit on CodePen
Click the button to export content with CSS inlined
Raw HTML output
Rendered output
<textarea id="inline-css" class="classic">
<h1>TinyMCE documents and Inline CSS documents</h1>
<h2>TinyMCE documents</h2>
<p><em>TinyMCE</em> documents consist of</p>
<ul>
<li>material marked up as HTML;</li>
<li>stylesheets defined by the <code>content_css</code> and <code>font_css</code> options; and</li>
<li>CSS defined by the <code>style_css</code> option.</li>
</ul>
<h2>Inline CSS</h2>
By contrast, <em>Inline CSS</em> documents consist of
<ul>
<li>a single file with all CSS styling applied inline to each HTML element.</li>
</ul>
<h2>The TinyMCE Inline CSS plugin</h2>
<p>The TinyMCE Inline CSS plugin takes a TinyMCE document, with its multiple components.</p>
<p>And returns a single file, with all CSS styling applied inline to each HTML element.</p>
<p>As an example, below is a small text section with various styles applied. Press the <strong>Inline CSS</strong> button to view the content where all CSS are inlined</p>
<br>
<p class="red">Red text</p>
<p class="red blue-background">Red text - blue background</p>
<p class="blue">Blue text</p>
<p class="blue red-background">Blue text - red background</p>
</textarea>
<div id="inlinecss-api-runner">
<h1> Click the button to export content with CSS inlined</h1>
<button id="inline-css-btn" style="margin: 10px">Inline CSS</button>
<br/>
<br/>
<h2>Raw HTML output</h2>
<textarea style="display: block; min-height: 250px; width: 100%;" id='output-text-area'></textarea>
<br/>
<br/>
<h2>Rendered output </h2>
<div style="height: 400px; display: flex; flex-direction: column; overflow: hidden;">
<iframe style="flex: 1; height: 100%; width: 100%" id="outputIframe"></iframe>
</div>
</div>
const settings = {
plugins: [
'advlist', 'anchor', 'autolink', 'charmap', 'code', 'fullscreen',
'help', 'image', 'insertdatetime', 'link', 'lists', 'media',
'preview', 'searchreplace', 'table', 'visualblocks', 'inlinecss'
],
toolbar: 'undo redo | styles | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
content_style: `
.red {
color: red;
}
.blue {
color: blue;
}
.blue-background {
background-color: blue;
}
.red-background {
background-color: red;
}
`
};
tinymce.init({
selector: 'textarea.classic',
...settings
});
const button = document.getElementById('inline-css-btn');
const outputTextArea = document.getElementById('output-text-area');
button.addEventListener('click', () => {
const pluginAPI = tinymce.get(0).plugins.inlinecss;
const outputIframe = document.getElementById('outputIframe');
const rawDoc = outputIframe.contentWindow.document;
pluginAPI.getContent().then((content) => {
outputTextArea.value = content.html;
if (rawDoc) {
rawDoc.open();
rawDoc.write(content.html);
rawDoc.close();
}
});
});
Basic setup
To add the Inline CSS plugin to the editor, add inlinecss
to the plugins
option in the editor configuration.
For example:
tinymce.init({
selector: 'textarea', // change this value according to your HTML
plugins: 'inlinecss',
});
Usage notes
The Inline CSS plugin does not support
-
Pseudo-classes (for example
button:hover { color: blue; }
). -
Pseudo-elements (for example
p::first-line { color: blue; }
) -
@ rules (for example
@media (screen)
) -
The
!important
property.
Iframe mode is fully supported with some notable limitations
Since iframe is a sandbox, specifying CSS is reasonably constrained at this stage.
CSS styling information can be specified in several places for iframe mode:
-
A CSS stylesheet that is specified in the
<head>
of the iframe document i.e.<link rel="stylesheet" href="styles.css">
-
The supported way to add a stylesheet in TinyMCE is using the
content_css
option which automatically creates the<link>
tag and puts it in the<head>
of the document. -
The user can also manually insert a stylesheet link in the <head> of the
iframe
.
-
-
A
<style>
tag in the<head>
of theiframe
document i.e.<style>p { color: red; }</style>
-
The supported way to add a style tag in TinyMCE, is using the
content_style
option which automatically creates the<style>
tag and puts in the head of the document -
The user can manually insert a style tag in the <head> of the
iframe
.
-
-
A
style
attribute on an element within the content i.e. inline CSS
It is worth noting that by default, TinyMCE does not support having a <style>
tags as part of the body HTML content.
Inline mode is supported with some notable limitations
As inline
mode for TinyMCE editor is not sandboxed and as a result, any CSS specified on the main page can have an effect on how the editor content looks.
CSS styling information can be specified in several places for inline mode:
-
A CSS stylesheet that is specified in the
<head>
of the page i.e.<link rel="stylesheet" href="styles.css">
-
Adding a stylesheet in TinyMCE, can be done by using the
content_css
option which automatically creates the<link>
tag in the <head> of the page.-
It is recommended to not use the
content_css
option though and just manually include the stylesheets. -
The user can also manually insert a stylesheet link in the <head> of the page.
-
-
-
A CSS stylesheet that is specified in the
<body>
of the page i.e.<link rel="stylesheet" href="styles.css">
-
This is not recommended by MDN, but some browsers do allow it
-
-
A
<style>
in the<head>
of the page i.e.<style>p { color: red; }</style>
-
To add a
<style>
in TinyMCE is by using thecontent_style
option which automatically creates the<style>
tag in the <head> of the document -
The user can also manually put a
<style>
tag in the <head> of the page.
-
-
A
<style>
in the<body>
of the page-
As noted in the
Classic iframe
section, this should not be done, but some browsers will still allow it.
-
-
A
style
attribute on an TinyMCE element within the content i.e. inline CSS
Shadow DOM is supported but not officially, with some notable limitations
Shadow DOM is not officially supported by TinyMCE, but the feature will work when an editor running in inline
or iframe
is contained within a shadow root.
When an iframe
mode editor is contained with a shadow root, the editor content can be styled the same way, where the expected behavior for the feature
is that it should not have to consider if the editor is in a shadow root. When an inline
editor is contained within a shadow root, the stylesheet (<link>
tags) and <style>
tags are added directly as children of the shadow root and do not need to be contained within a <head>
tag.
When in inline mode
, the feature checks if the editor is inside a shadow root to ensure it does not try to get <styles>
that are outside the shadow root.
When an editor is in a shadow root, the feature should still support getting the stylesheets specified via the content_css
option as well as the CSS styles specified via the`content_style` option.
Options
The following configuration options affect the behavior of the Inline CSS plugin.
inline_selector_filter
Determines whether it is valid for a given CSS selector to have its CSS properties inlined into the HTML content
Default: All selectors are considered valid to have their CSS inlined
Type: String
RegExp
or Function
inlinecss_selector_filter: (selector: string): boolean => {
return selector.indexOf('myprefix') !== -1;
}
inline_file_filter
Determines whether it is valid for a given CSS stylesheet to have its CSS inspected and inlined into the HTML content
Default: All CSS stylesheet are considered valid to have their CSS inspected and inlined
Type: String
RegExp
or Function
inlinecss_file_filter: (href: string): boolean => {
return selector.indexOf('mystyles') !== -1;
}
Events
The Inline CSS plugin provides the following events.
The following events are provided by the Inline CSS plugin.
Name | Data | Description |
---|---|---|
InlineCSS |
N/A |
Fired when inlining the CSS begins. |
APIs
The Inline CSS plugin provides the following APIs.
A new API, editor.plugins.inlinecss.getContent();
has been added to support the new InlineCSS
plugin
The API’s function is to take a TinyMCE document, and processes it such that the previously separate CSS is applied inline to each HTML element.
The editor.plugins.inlinecss.getContent();
API does not require configuration from the user
The API will do the following
-
Fire the 'InlineCSS' event
-
Get the editor’s content by calling the
editor.plugins.inlinecss.getContent();
-
Collect all of the stylesheets defined by the
content_css
option -
Collect all styles specified in the
content_style
option -
Combine
content_css
andcontent_style
styles while making surecontent_style
has a higher precedent -
Iterate over the content within the TinyMCE editor viewport, by inlining any
InlineCSS
styles where it finds a selector match -
Return an object that contains the content with
InlineCSS
as astring