Skip to content

Toggle

Toggle
Thymeleaf source
<sl:toggle name="bookmarked" size="sm" variant="outline">
<sl:icon name="bookmark"/> Bookmark
</sl:toggle>
Rendered HTML
<label class="toggle" data-variant="outline" data-size="sm">
<input class="toggle-input" type="checkbox" name="bookmarked">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z"></path>
</svg>
Bookmark
</label>

A toggle is a checkbox drawn as a button: a <label> with the checkbox inside it, covering it. A click anywhere on the toggle checks or unchecks it, the form submits it as a checkbox, and it works without JavaScript. A screen reader announces it as a checkbox, checked or not.

The content is the toggle’s label. A toggle that holds only an icon needs an aria-label. Every attribute that is not a prop goes to the checkbox (name, value, checked, disabled, aria-label, x-on:change), except class, which goes to the label.

For several toggles that belong together, one of which (or any of which) can be on, use a toggle group.

Outline
Thymeleaf source
<sl:toggle variant="outline" name="italicText" aria-label="Italic"><sl:icon name="italic"/></sl:toggle>
<sl:toggle variant="outline" name="underlineText" aria-label="Underline"><sl:icon name="underline"/></sl:toggle>
Rendered HTML
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" name="italicText" aria-label="Italic">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<line x1="19" x2="10" y1="4" y2="4"></line>
<line x1="14" x2="5" y1="20" y2="20"></line>
<line x1="15" x2="9" y1="4" y2="20"></line>
</svg>
</label>
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" name="underlineText" aria-label="Underline">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M6 4v6a6 6 0 0 0 12 0V4"></path>
<line x1="4" x2="20" y1="20" y2="20"></line>
</svg>
</label>
With text
Thymeleaf source
<sl:toggle name="italicLabel"><sl:icon name="italic"/> Italic</sl:toggle>
Rendered HTML
<label class="toggle">
<input class="toggle-input" type="checkbox" name="italicLabel">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<line x1="19" x2="10" y1="4" y2="4"></line>
<line x1="14" x2="5" y1="20" y2="20"></line>
<line x1="15" x2="9" y1="4" y2="20"></line>
</svg>
Italic
</label>
Sizes
Thymeleaf source
<sl:toggle size="sm" variant="outline" name="sizeSm">Small</sl:toggle>
<sl:toggle variant="outline" name="sizeDefault">Default</sl:toggle>
<sl:toggle size="lg" variant="outline" name="sizeLg">Large</sl:toggle>
Rendered HTML
<label class="toggle" data-variant="outline" data-size="sm">
<input class="toggle-input" type="checkbox" name="sizeSm">
Small
</label>
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" name="sizeDefault">
Default
</label>
<label class="toggle" data-variant="outline" data-size="lg">
<input class="toggle-input" type="checkbox" name="sizeLg">
Large
</label>

th:field on a boolean field checks the toggle when the field is true, as on a checkbox: Spring numbers the id (starred1) and adds a hidden marker input, so unchecking it submits false. In a field, the toggle takes the field’s name as its id and is described by the field’s description and error.

In a formth:field on a boolean checks the toggle from the form object, as on a checkbox.
Thymeleaf source
<sl:toggle th:field="*{starred}" variant="outline"><sl:icon name="star"/> Starred</sl:toggle>
Rendered HTML
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" id="starred1" name="starred" value="true" checked>
<input type="hidden" name="_starred" value="on">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"></path>
</svg>
Starred
</label>
InvalidWith th:field, a field that has errors marks the toggle aria-invalid by itself.
Thymeleaf source
<sl:toggle th:field="*{pinned}" variant="outline"><sl:icon name="bookmark"/> Pin to the top</sl:toggle>
Rendered HTML
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" aria-invalid="true" id="pinned1" name="pinned" value="true">
<input type="hidden" name="_pinned" value="on">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z"></path>
</svg>
Pin to the top
</label>
Disabled
Thymeleaf source
<sl:toggle name="boldLocked" disabled aria-label="Bold"><sl:icon name="bold"/></sl:toggle>
<sl:toggle name="underlineLocked" variant="outline" checked disabled aria-label="Underline"><sl:icon
name="underline"/></sl:toggle>
Rendered HTML
<label class="toggle">
<input class="toggle-input" type="checkbox" name="boldLocked" disabled aria-label="Bold">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"></path>
</svg>
</label>
<label class="toggle" data-variant="outline">
<input class="toggle-input" type="checkbox" name="underlineLocked" checked disabled aria-label="Underline">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M6 4v6a6 6 0 0 0 12 0V4"></path>
<line x1="4" x2="20" y1="20" y2="20"></line>
</svg>
</label>
AttributeValuesDefaultDescription
variantdefault outlinedefaultVisual style of the toggle.
sizesm default lgdefaultSize of the toggle.

Every prop can also be set from an expression: th:variant="${...}". Any other attribute passes through to the rendered element, and class is appended.