WYSIWYG editor
Rich-text editor styling with a wrapping toolbar, native editable canvas, and clear focus and validation states.
Rich-text editing surface
Native contenteditable lets you type and edit text. CSS styles the editor shell and existing formatted content; the toolbar is an inactive integration template.
Draft content
Type below to try native editing. Formatting controls are inactive: connect your editor logic to enable them. Changes are not saved.
A new story starts here
Select this text or start typing. Existing bold and italic content uses semantic HTML.
- A comfortable writing area
- A toolbar that wraps on small screens
Give your ideas room to grow.
View HTML / PlaygroundHTML source
<div class="sl-stack">
<p id="editor-rich-label" class="sl-label">Draft content</p>
<p id="editor-rich-hint" class="sl-help">
Type below to try native editing. Formatting controls are inactive: connect your
editor logic to enable them. Changes are not saved.
</p>
<div class="sl-editor">
<div
class="sl-editor__toolbar"
role="group"
aria-label="Formatting controls (inactive CSS demo)"
>
<div class="sl-editor__group" role="group" aria-label="Text formatting">
<button type="button" class="sl-editor__tool" aria-label="Bold" disabled>
<strong>B</strong></button
><button type="button" class="sl-editor__tool" aria-label="Italic" disabled>
<em>I</em></button
><button type="button" class="sl-editor__tool" aria-label="Underline" disabled>
<u>U</u>
</button>
</div>
<div class="sl-editor__group" role="group" aria-label="Content formatting">
<button type="button" class="sl-editor__tool" disabled>Heading</button
><button type="button" class="sl-editor__tool" disabled>List</button
><button type="button" class="sl-editor__tool" disabled>Insert link</button>
</div>
</div>
<div
class="sl-editor__content"
contenteditable="true"
role="textbox"
aria-multiline="true"
aria-labelledby="editor-rich-label"
aria-describedby="editor-rich-hint"
spellcheck="true"
>
<h3>A new story starts here</h3>
<p>
Select this text or start typing. Existing <strong>bold</strong> and
<em>italic</em> content uses semantic HTML.
</p>
<ul>
<li>A comfortable writing area</li>
<li>A toolbar that wraps on small screens</li>
</ul>
<blockquote>Give your ideas room to grow.</blockquote>
</div>
<div class="sl-editor__footer">
<span>Local editing demo · not saved</span><span>CSS-only presentation</span>
</div>
</div>
</div>Compact comment editor
A smaller canvas for comments and short descriptions, with the same keyboard focus styling.
Draft content
Type below to try native editing. Formatting controls are inactive: connect your editor logic to enable them. Changes are not saved.
Write a thoughtful comment…
View HTML / PlaygroundHTML source
<div class="sl-stack">
<p id="editor-compact-label" class="sl-label">Draft content</p>
<p id="editor-compact-hint" class="sl-help">
Type below to try native editing. Formatting controls are inactive: connect your
editor logic to enable them. Changes are not saved.
</p>
<div class="sl-editor sl-editor--compact">
<div
class="sl-editor__toolbar"
role="group"
aria-label="Formatting controls (inactive CSS demo)"
>
<div class="sl-editor__group" role="group" aria-label="Text formatting">
<button type="button" class="sl-editor__tool" aria-label="Bold" disabled>
<strong>B</strong></button
><button type="button" class="sl-editor__tool" aria-label="Italic" disabled>
<em>I</em></button
><button type="button" class="sl-editor__tool" aria-label="Underline" disabled>
<u>U</u>
</button>
</div>
<div class="sl-editor__group" role="group" aria-label="Content formatting">
<button type="button" class="sl-editor__tool" disabled>Heading</button
><button type="button" class="sl-editor__tool" disabled>List</button
><button type="button" class="sl-editor__tool" disabled>Insert link</button>
</div>
</div>
<div
class="sl-editor__content"
contenteditable="true"
role="textbox"
aria-multiline="true"
aria-labelledby="editor-compact-label"
aria-describedby="editor-compact-hint"
spellcheck="true"
>
<p>Write a thoughtful comment…</p>
</div>
<div class="sl-editor__footer">
<span>Local editing demo · not saved</span><span>CSS-only presentation</span>
</div>
</div>
</div>Validation state
The application controls validation. This static example connects the error text to the editable field.
Project summary
Type below to try native editing. Formatting controls are inactive: connect your editor logic to enable them. Changes are not saved.
Edit this example project summary.
Example validation: add a project summary before publishing. This state is illustrative.
View HTML / PlaygroundHTML source
<div class="sl-stack">
<p id="editor-invalid-label" class="sl-label">Project summary</p>
<p id="editor-invalid-hint" class="sl-help">
Type below to try native editing. Formatting controls are inactive: connect your
editor logic to enable them. Changes are not saved.
</p>
<div class="sl-editor sl-editor--compact sl-editor--invalid">
<div
class="sl-editor__toolbar"
role="group"
aria-label="Formatting controls (inactive CSS demo)"
>
<div class="sl-editor__group" role="group" aria-label="Text formatting">
<button type="button" class="sl-editor__tool" aria-label="Bold" disabled>
<strong>B</strong></button
><button type="button" class="sl-editor__tool" aria-label="Italic" disabled>
<em>I</em></button
><button type="button" class="sl-editor__tool" aria-label="Underline" disabled>
<u>U</u>
</button>
</div>
<div class="sl-editor__group" role="group" aria-label="Content formatting">
<button type="button" class="sl-editor__tool" disabled>Heading</button
><button type="button" class="sl-editor__tool" disabled>List</button
><button type="button" class="sl-editor__tool" disabled>Insert link</button>
</div>
</div>
<div
class="sl-editor__content"
contenteditable="true"
role="textbox"
aria-multiline="true"
aria-labelledby="editor-invalid-label"
aria-describedby="editor-invalid-hint editor-invalid-error"
aria-invalid="true"
spellcheck="true"
>
<p>Edit this example project summary.</p>
</div>
<div class="sl-editor__footer">
<span>Local editing demo · not saved</span><span>CSS-only presentation</span>
</div>
</div>
<p class="sl-error" id="editor-invalid-error">
Example validation: add a project summary before publishing. This state is
illustrative.
</p>
</div>Read-only rich-text preview
A published-content preview without editable behavior or inactive controls.
Published preview
A note from the studio
Rich-text output can use the same typography as the editing canvas.
- Write your draft.
- Review it with your team.
- Publish when it is ready.
Clear words make good interfaces.
View HTML / PlaygroundHTML source
<section class="sl-stack" aria-labelledby="editor-preview-title">
<h3 id="editor-preview-title" class="sl-text-xl">Published preview</h3>
<div class="sl-editor sl-editor--readonly">
<div class="sl-editor__content">
<h4>A note from the studio</h4>
<p>Rich-text output can use the same typography as the editing canvas.</p>
<ol>
<li>Write your draft.</li>
<li>Review it with your team.</li>
<li>Publish when it is ready.</li>
</ol>
<blockquote>Clear words make good interfaces.</blockquote>
</div>
<div class="sl-editor__footer"><span>Read-only example</span></div>
</div>
</section>Classes beginning with sl- come from StyloftCSS. Examples with demo- classes also use our optional demo extension CSS ↓. Load it after the core to reproduce those details.