Checkboxes
Checkboxes let the user select one or more options from a list.
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">What devices do you own?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="mobile-phone" class="ons-checkbox__input ons-js-checkbox " value="mobile-phone">
<label class=" ons-checkbox__label " for="mobile-phone" id="mobile-phone-label">Mobile phone</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="tablet" class="ons-checkbox__input ons-js-checkbox " value="tablet">
<label class=" ons-checkbox__label " for="tablet" id="tablet-label">Tablet</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="laptop" class="ons-checkbox__input ons-js-checkbox " value="laptop">
<label class=" ons-checkbox__label " for="laptop" id="laptop-label">Laptop</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="desktop" class="ons-checkbox__input ons-js-checkbox " value="desktop">
<label class=" ons-checkbox__label " for="desktop" id="desktop-label">Desktop computer</label>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% call onsQuestion({
"title": "What devices do you own?",
"legendIsQuestionTitle": true,
"classes": "ons-u-mt-no"
}) %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"dontWrap": true,
"name": "devices",
"checkboxes": [
{
"id": "mobile-phone",
"label": {
"text": "Mobile phone"
},
"value": "mobile-phone"
},
{
"id": "tablet",
"label": {
"text": "Tablet"
},
"value": "tablet"
},
{
"id": "laptop",
"label": {
"text": "Laptop"
},
"value": "laptop"
},
{
"id": "desktop",
"label": {
"text": "Desktop computer"
},
"value": "desktop"
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
When to use this component
Use the checkboxes component when you need to help users select multiple options from a list.
When not to use this component
Do not use the checkboxes component if users can only choose one option from a list. In this case, use the radios component.
How to use this component
Checkboxes are grouped within a fieldset which starts with a <legend>
which lets the user know what they need to do.
Variants
Descriptions
This variant allows you to add more context to the checkbox answers. The description is added by providing a description
parameter within the checkbox’s label
parameter.
Answer descriptions are a good way to provide examples to help a user answer a question without disrupting their journey through the survey.
Answer descriptions should:
- be short – try to have no more than 100 characters
- be clearly written
- be relevant to that answer only, not any of the other answers
- start with a capital letter
- not have a full stop on the end
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">What type of central heating does your accommodation have?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label"></p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="none" class="ons-checkbox__input ons-js-checkbox " value="" name="none">
<label class=" ons-checkbox__label " for="none" id="none-label">No central heating</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="mains-gas" class="ons-checkbox__input ons-js-checkbox " value="" name="mains-gas">
<label class=" ons-checkbox__label ons-label--with-description" for="mains-gas" id="mains-gas-label">Gas
<span id="mains-gas-label-description-hint" class="ons-label__description ons-checkbox__label--with-description">Including tank or bottled gas</span></label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="electric" class="ons-checkbox__input ons-js-checkbox " value="" name="electric">
<label class=" ons-checkbox__label ons-label--with-description" for="electric" id="electric-label">Electric
<span id="electric-label-description-hint" class="ons-label__description ons-checkbox__label--with-description">Including storage headers</span></label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="oil" class="ons-checkbox__input ons-js-checkbox " value="" name="oil">
<label class=" ons-checkbox__label " for="oil" id="oil-label">Oil</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="wood" class="ons-checkbox__input ons-js-checkbox " value="" name="wood">
<label class=" ons-checkbox__label ons-label--with-description" for="wood" id="wood-label">Wood
<span id="wood-label-description-hint" class="ons-label__description ons-checkbox__label--with-description">For example, logs, waste wood or pellets</span></label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="solid-fuel" class="ons-checkbox__input ons-js-checkbox " value="" name="solid-fuel">
<label class=" ons-checkbox__label ons-label--with-description" for="solid-fuel" id="solid-fuel-label">Solid fuel
<span id="solid-fuel-label-description-hint" class="ons-label__description ons-checkbox__label--with-description">For example, coal</span></label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="renewable" class="ons-checkbox__input ons-js-checkbox " value="" name="renewable">
<label class=" ons-checkbox__label ons-label--with-description" for="renewable" id="renewable-label">Renewable energy
<span id="renewable-label-description-hint" class="ons-label__description ons-checkbox__label--with-description">For example, solar thermal or heat pumps</span></label>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% from "components/question/_macro.njk" import onsQuestion %}
{% call onsQuestion({
"title": "What type of central heating does your accommodation have?",
"classes": "ons-u-mt-no",
"legendIsQuestionTitle": true
}) %}
{{
onsCheckboxes({
"dontWrap": true,
"name": "central-heating",
"checkboxes": [
{
"id": "none",
"label": {
"text": "No central heating"
},
"name": "none"
},
{
"id": "mains-gas",
"label": {
"text": "Gas",
"description": "Including tank or bottled gas"
},
"name": "mains-gas"
},
{
"id": "electric",
"label": {
"text": "Electric",
"description": "Including storage headers"
},
"name": "electric"
},
{
"id": "oil",
"label": {
"text": "Oil"
},
"name": "oil"
},
{
"id": "wood",
"label": {
"text": "Wood",
"description": "For example, logs, waste wood or pellets"
},
"name": "wood"
},
{
"id": "solid-fuel",
"label": {
"text": "Solid fuel",
"description": "For example, coal"
},
"name": "solid-fuel"
},
{
"id": "renewable",
"label": {
"text": "Renewable energy",
"description": "For example, solar thermal or heat pumps"
},
"name": "renewable"
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Select and unselect all checkboxes
This variant lets the user select and unselect all checkboxes using a button.
Use the parameter autoSelect
with the required child parameters selectAllText
, unSelectAllText
and context
. The context
parameter is used for visually hidden text to help screen reader users understand the purpose of the button, for example, “Select all following options”.
The “select/unselect all” button cannot be used when one of the checkboxes uses the other
parameter to reveal nested inputs. It can however, be inside the other
parameter to select and unselect all nested checkboxes or radios.
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">What devices do you own?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<button type="submit" class="ons-btn ons-u-mb-s ons-js-auto-selector ons-btn--small ons-btn--secondary" data-unselect-all="Unselect all" data-select-all="Select all">
<span class="ons-btn__inner"><span class="ons-js-button-text">Select all</span><span class="ons-u-vh"> following checkboxes</span></span>
</button>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="mobile-phone" class="ons-checkbox__input ons-js-checkbox " value="mobile-phone">
<label class=" ons-checkbox__label " for="mobile-phone" id="mobile-phone-label">Mobile phone</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="tablet" class="ons-checkbox__input ons-js-checkbox " value="tablet">
<label class=" ons-checkbox__label " for="tablet" id="tablet-label">Tablet</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="laptop" class="ons-checkbox__input ons-js-checkbox " value="laptop">
<label class=" ons-checkbox__label " for="laptop" id="laptop-label">Laptop</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="desktop" class="ons-checkbox__input ons-js-checkbox " value="desktop">
<label class=" ons-checkbox__label " for="desktop" id="desktop-label">Desktop computer</label>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% call onsQuestion({
"title": "What devices do you own?",
"legendIsQuestionTitle": true,
"classes": "ons-u-mt-no"
}) %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"dontWrap": true,
"name": "devices",
"autoSelect": {
"selectAllText": "Select all",
"unselectAllText": "Unselect all",
"context": "following checkboxes"
},
"checkboxes": [
{
"id": "mobile-phone",
"label": {
"text": "Mobile phone"
},
"value": "mobile-phone"
},
{
"id": "tablet",
"label": {
"text": "Tablet"
},
"value": "tablet"
},
{
"id": "laptop",
"label": {
"text": "Laptop"
},
"value": "laptop"
},
{
"id": "desktop",
"label": {
"text": "Desktop computer"
},
"value": "desktop"
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkbox with revealed text input
This variant lets the user provide an answer other to the options in the list, or to provide additional information required to describe their answer.
Provide the other
parameter containing the relevant input parameters. The field is hidden until the checkbox is selected.
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">Do you have any dietary requirements?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="gluten-free" class="ons-checkbox__input ons-js-checkbox " value="gluten-free">
<label class=" ons-checkbox__label " for="gluten-free" id="gluten-free-label">Gluten free</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="lactose-intolerant" class="ons-checkbox__input ons-js-checkbox " value="lactose-intolerant">
<label class=" ons-checkbox__label " for="lactose-intolerant" id="lactose-intolerant-label">Lactose intolerant</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegan" class="ons-checkbox__input ons-js-checkbox " value="vegan">
<label class=" ons-checkbox__label " for="vegan" id="vegan-label">Vegan</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegetarian" class="ons-checkbox__input ons-js-checkbox " value="vegetarian">
<label class=" ons-checkbox__label " for="vegetarian" id="vegetarian-label">Vegetarian</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="other-checkbox" class="ons-checkbox__input ons-js-checkbox ons-js-other" value="other" aria-controls="other-checkbox-other-wrap" aria-haspopup="true">
<label class=" ons-checkbox__label " for="other-checkbox" id="other-checkbox-label">Other</label>
<span class="ons-checkbox__other" id="other-checkbox-other-wrap">
<label class="ons-label ons-u-fw-n" for="other-textbox" id="other-textbox-label">Enter dietary requirements</label>
<input type="text" id="other-textbox" class="ons-input ons-input--text ons-input-type__input ons-input--w-auto" name="other-answer" />
</span>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% call onsQuestion({
"title": "Do you have any dietary requirements?",
"legendIsQuestionTitle": true,
"classes": "ons-u-mt-no"
}) %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"dontWrap": true,
"name": "dietary",
"checkboxes": [
{
"id": "gluten-free",
"label": {
"text": "Gluten free"
},
"value": "gluten-free"
},
{
"id": "lactose-intolerant",
"label": {
"text": "Lactose intolerant"
},
"value": "lactose-intolerant"
},
{
"id": "vegan",
"label": {
"text": "Vegan"
},
"value": "vegan"
},
{
"id": "vegetarian",
"label": {
"text": "Vegetarian"
},
"value": "vegetarian"
},
{
"id": "other-checkbox",
"label": {
"text": "Other"
},
"value": "other",
"other": {
"id": "other-textbox",
"name": "other-answer",
"label": {
"text": "Enter dietary requirements"
}
}
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkbox with revealed drop-down
This variant reveals a nested select component when a checkbox is selected.
To use this variant provide "otherType": "select"
inside the other
parameter.
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">How would you like us to contact you?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="post" class="ons-checkbox__input ons-js-checkbox " value="post">
<label class=" ons-checkbox__label " for="post" id="post-label">By post</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="email" class="ons-checkbox__input ons-js-checkbox " value="email">
<label class=" ons-checkbox__label " for="email" id="email-label">By email</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="phone" class="ons-checkbox__input ons-js-checkbox ons-js-other" value="phone" aria-controls="phone-other-wrap" aria-haspopup="true">
<label class=" ons-checkbox__label " for="phone" id="phone-label">By phone</label>
<span class="ons-checkbox__other" id="phone-other-wrap">
<label class="ons-label ons-u-fw-n" for="phone-time">Choose preferred time of day</label>
<select id="phone-time" name="phone-time" class="ons-input ons-input--select">
<option value="" selected disabled>Select an option</option>
<option value="anytime">Anytime of day</option>
<option value="morning">Morning</option>
<option value="afternoon">Afternoon</option>
<option value="evening">Evening</option>
</select>
</span>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% call onsQuestion({
"title": "How would you like us to contact you?",
"legendIsQuestionTitle": true,
"classes": "ons-u-mt-no"
}) %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"dontWrap": true,
"name": "contact",
"checkboxes": [
{
"id": "post",
"label": {
"text": "By post"
},
"value": "post"
},
{
"id": "email",
"label": {
"text": "By email"
},
"value": "email"
},
{
"id": "phone",
"label": {
"text": "By phone"
},
"value": "phone",
"other": {
"otherType": "select",
"id": "phone-time",
"name": "phone-time",
"label": {
"text": "Choose preferred time of day"
},
"options": [
{
"value": "",
"text": "Select an option",
"disabled": true,
"selected": true
},
{
"value": "anytime",
"text": "Anytime of day"
},
{
"value": "morning",
"text": "Morning"
},
{
"value": "afternoon",
"text": "Afternoon"
},
{
"value": "evening",
"text": "Evening"
}
]
}
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkbox with visible text input
This variant always shows the nested inputs.
To use this variant provide "open": true
inside the other
parameter.
<div class="ons-question ons-u-mb-l ons-u-mt-no">
<div class="ons-question__answer ons-u-mb-m">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title ons-u-mb-m">Do you have any dietary requirements?</h1>
</legend>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="gluten-free" class="ons-checkbox__input ons-js-checkbox " value="gluten-free">
<label class=" ons-checkbox__label " for="gluten-free" id="gluten-free-label">Gluten free</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="lactose-intolerant" class="ons-checkbox__input ons-js-checkbox " value="lactose-intolerant">
<label class=" ons-checkbox__label " for="lactose-intolerant" id="lactose-intolerant-label">Lactose intolerant</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegan" class="ons-checkbox__input ons-js-checkbox " value="vegan">
<label class=" ons-checkbox__label " for="vegan" id="vegan-label">Vegan</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegetarian" class="ons-checkbox__input ons-js-checkbox " value="vegetarian">
<label class=" ons-checkbox__label " for="vegetarian" id="vegetarian-label">Vegetarian</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="other-checkbox" class="ons-checkbox__input ons-js-checkbox ons-js-other" value="other">
<label class=" ons-checkbox__label " for="other-checkbox" id="other-checkbox-label">Other</label>
<span class="ons-checkbox__other ons-checkbox__other--open" id="other-checkbox-other-wrap">
<label class="ons-label ons-u-fw-n" for="other-textbox" id="other-textbox-label">Enter dietary requirements</label>
<input type="text" id="other-textbox" class="ons-input ons-input--text ons-input-type__input ons-input--w-auto" name="other-answer" />
</span>
</span>
</span>
</div>
</div>
</fieldset>
</div>
</div>
{% from "components/question/_macro.njk" import onsQuestion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{% call onsQuestion({
"title": "Do you have any dietary requirements?",
"legendIsQuestionTitle": true,
"classes": "ons-u-mt-no"
}) %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"dontWrap": true,
"name": "dietary",
"checkboxes": [
{
"id": "gluten-free",
"label": {
"text": "Gluten free"
},
"value": "gluten-free"
},
{
"id": "lactose-intolerant",
"label": {
"text": "Lactose intolerant"
},
"value": "lactose-intolerant"
},
{
"id": "vegan",
"label": {
"text": "Vegan"
},
"value": "vegan"
},
{
"id": "vegetarian",
"label": {
"text": "Vegetarian"
},
"value": "vegetarian"
},
{
"id": "other-checkbox",
"label": {
"text": "Other"
},
"value": "other",
"other": {
"open": true,
"id": "other-textbox",
"name": "other-answer",
"label": {
"text": "Enter dietary requirements"
}
}
}
]
})
}}
{% endcall %}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkboxes without a border
This variant removes the border around the checkbox and label.
Do not use this variant on question pages with checkboxes. It is better to have a border. It makes the checkboxes more visible for users and gives them a larger target area to select (the label and the boundary).
Only remove the checkbox border for pages that are not following the practice of “one thing per page”, where the checkboxes are not the primary call to action. For example, the checkboxes could be one part of a multipurpose page, like the checkboxes used for the filters on the download resources pattern.
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend">Select type</legend>
<p class="ons-checkboxes__label">All types</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="booklet" class="ons-checkbox__input ons-js-checkbox " value="booklet">
<label class=" ons-checkbox__label " for="booklet" id="booklet-label">Booklet</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="logo" class="ons-checkbox__input ons-js-checkbox " value="logo">
<label class=" ons-checkbox__label " for="logo" id="logo-label">Logo</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="poster" class="ons-checkbox__input ons-js-checkbox " value="poster">
<label class=" ons-checkbox__label " for="poster" id="poster-label">Poster</label>
</span>
</span>
</div>
</fieldset>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{{
onsCheckboxes({
"checkboxesLabel": "All types",
"legend": "Select type",
"name": "types",
"borderless": true,
"checkboxes": [
{
"id": "booklet",
"label": {
"text": "Booklet"
},
"value": "booklet"
},
{
"id": "logo",
"label": {
"text": "Logo"
},
"value": "logo"
},
{
"id": "poster",
"label": {
"text": "Poster"
},
"value": "poster"
}
]
})
}}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkbox with revealed checkboxes
This variant reveals nested checkboxes when a checkbox is selected. We recommend using this variant together with the parent checkboxes using the borderless variant.
To use this variant provide "otherType": "checkboxes"
inside the other
parameter. The example below includes the optional parameter selectAllChildren: true
which automatically checks all revealed checkboxes.
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend">Content type</legend>
<p class="ons-checkboxes__label">Show only:</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="data" class="ons-checkbox__input ons-js-checkbox " value="data">
<label class=" ons-checkbox__label " for="data" id="data-label">Data (309)</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="publications" class="ons-checkbox__input ons-js-checkbox ons-js-other ons-js-select-all-children" value="publications" aria-controls="publications-other-wrap" aria-haspopup="true">
<label class=" ons-checkbox__label " for="publications" id="publications-label">Publications (137)</label>
<span class="ons-checkbox__other" id="publications-other-wrap">
<fieldset class="ons-fieldset ons-js-other-fieldset">
<legend class="ons-fieldset__legend ons-u-vh ons-u-mb-xs">Publication type</legend>
<p class="ons-checkboxes__label"></p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="datasets" class="ons-checkbox__input ons-js-checkbox " value="datasets">
<label class=" ons-checkbox__label " for="datasets" id="datasets-label">Datasets (100)</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="timeseries" class="ons-checkbox__input ons-js-checkbox " value="timeseries">
<label class=" ons-checkbox__label " for="timeseries" id="timeseries-label">Timeseries (20)</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="requested" class="ons-checkbox__input ons-js-checkbox " value="requested">
<label class=" ons-checkbox__label " for="requested" id="requested-label">User requested data (17)</label>
</span>
</span>
</div>
</fieldset>
</span>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="areas" class="ons-checkbox__input ons-js-checkbox ons-js-other ons-js-select-all-children" value="areas">
<label class=" ons-checkbox__label " for="areas" id="areas-label">Areas (0)</label>
</span>
</span>
</div>
</fieldset>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{{
onsCheckboxes({
"legend": "Content type",
"checkboxesLabel": "Show only:",
"borderless": true,
"name": "dietary",
"checkboxes": [
{
"id": "data",
"label": {
"text": "Data (309)"
},
"value": "data"
},
{
"id": "publications",
"label": {
"text": "Publications (137)"
},
"value": "publications",
"other": {
"otherType": "checkboxes",
"selectAllChildren": true,
"legend": "Publication type",
"legendClasses": "ons-u-vh",
"name": "name",
"checkboxes": [
{
"id": "datasets",
"label": {
"text": "Datasets (100)"
},
"value": "datasets"
},
{
"id": "timeseries",
"label": {
"text": "Timeseries (20)"
},
"value": "timeseries"
},
{
"id": "requested",
"label": {
"text": "User requested data (17)"
},
"value": "requested"
}
]
}
},
{
"id": "areas",
"label": {
"text": "Areas (0)"
},
"value": "areas"
}
]
})
}}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Checkbox with revealed radios
This variant reveals nested radios when a checkbox is selected. We recommend using this variant together with the parent checkboxes using the borderless variant.
To use this variant provide "otherType": "radios"
inside the other
parameter.
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend">How would you like us to contact you?</legend>
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="post" class="ons-checkbox__input ons-js-checkbox " value="post">
<label class=" ons-checkbox__label " for="post" id="post-label">By post</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="email" class="ons-checkbox__input ons-js-checkbox " value="email">
<label class=" ons-checkbox__label " for="email" id="email-label">By email</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="phone" class="ons-checkbox__input ons-js-checkbox ons-js-other" value="phone" aria-controls="phone-other-wrap" aria-haspopup="true">
<label class=" ons-checkbox__label " for="phone" id="phone-label">By phone</label>
<span class="ons-checkbox__other" id="phone-other-wrap">
<fieldset id="phone-time" class="ons-fieldset ons-js-other-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-xs">Choose preferred time of day</legend>
<div class="ons-radios__items">
<span class="ons-radios__item ons-radios__item--no-border">
<span class="ons-radio ons-radio--no-border">
<input type="radio" id="anytime" class="ons-radio__input ons-js-radio" value="anytime" name="phone-time">
<label class=" ons-radio__label " for="anytime" id="anytime-label">Any time of day</label>
</span>
</span>
<br>
<span class="ons-radios__item ons-radios__item--no-border">
<span class="ons-radio ons-radio--no-border">
<input type="radio" id="morning" class="ons-radio__input ons-js-radio" value="morning" name="phone-time">
<label class=" ons-radio__label " for="morning" id="morning-label">Morning</label>
</span>
</span>
<br>
<span class="ons-radios__item ons-radios__item--no-border">
<span class="ons-radio ons-radio--no-border">
<input type="radio" id="afternoon" class="ons-radio__input ons-js-radio" value="afternoon" name="phone-time">
<label class=" ons-radio__label " for="afternoon" id="afternoon-label">Afternoon</label>
</span>
</span>
<br>
<span class="ons-radios__item ons-radios__item--no-border">
<span class="ons-radio ons-radio--no-border">
<input type="radio" id="evening" class="ons-radio__input ons-js-radio" value="evening" name="phone-time">
<label class=" ons-radio__label " for="evening" id="evening-label">Evening</label>
</span>
</span>
</div>
</fieldset>
</span>
</span>
</span>
</div>
</fieldset>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"legend": "How would you like us to contact you?",
"name": "contact",
"borderless": true,
"checkboxes": [
{
"id": "post",
"label": {
"text": "By post"
},
"value": "post"
},
{
"id": "email",
"label": {
"text": "By email"
},
"value": "email"
},
{
"id": "phone",
"label": {
"text": "By phone"
},
"value": "phone",
"other": {
"otherType": "radios",
"id": "phone-time",
"name": "phone-time",
"legend": "Choose preferred time of day",
"radios": [
{
"value": "anytime",
"id": "anytime",
"label": {
"text": "Any time of day"
}
},
{
"value": "morning",
"id": "morning",
"label": {
"text": "Morning"
}
},
{
"value": "afternoon",
"id": "afternoon",
"label": {
"text": "Afternoon"
}
},
{
"value": "evening",
"id": "evening",
"label": {
"text": "Evening"
}
}
]
}
}
]
})
}}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
Disabled checkboxes
This variant enables the use of disabled checkboxes. Allowing for a consistent user interface even when some options aren’t available.
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend">Content type</legend>
<p class="ons-checkboxes__label">Show only:</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="data" class="ons-checkbox__input ons-js-checkbox " value="data">
<label class=" ons-checkbox__label " for="data" id="data-label">Data (309)</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="publications" class="ons-checkbox__input ons-js-checkbox " value="publications">
<label class=" ons-checkbox__label " for="publications" id="publications-label">Publications (137)</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item ons-checkboxes__item--no-border">
<span class="ons-checkbox ons-checkbox--no-border">
<input type="checkbox" id="areas" class="ons-checkbox__input ons-js-checkbox " value="areas" disabled aria-disabled="true">
<label class=" ons-checkbox__label " for="areas" id="areas-label">Areas (0)</label>
</span>
</span>
</div>
</fieldset>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{{
onsCheckboxes({
"legend": "Content type",
"checkboxesLabel": "Show only:",
"borderless": true,
"name": "dietary",
"checkboxes": [
{
"id": "data",
"label": {
"text": "Data (309)"
},
"value": "data"
},
{
"id": "publications",
"label": {
"text": "Publications (137)"
},
"value": "publications"
},
{
"id": "areas",
"label": {
"text": "Areas (0)"
},
"value": "areas",
"disabled": true
}
]
})
}}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
How to validate checkboxes
To help users make a selection on the page and provide extra detail if it is required, you should:
- check they have selected at least one checkbox
- check they have entered something or selected a drop-down option if more detail is required for one of the checkboxes
- show an error message if they have not selected any of the checkboxes or given any more detail when required
Error messages
Use the correct errors pattern and show the error details above the checkbox options.
<div class="ons-panel ons-panel--error ons-panel--no-title" id="dietary-error">
<span class="ons-u-vh">Error: </span>
<div class="ons-panel__body">
<p class="ons-panel__error">
<strong>Enter your dietary requirements</strong>
</p>
<div class="ons-input-items">
<p class="ons-checkboxes__label">Select all that apply</p>
<div class="ons-checkboxes__items">
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="gluten-free" class="ons-checkbox__input ons-js-checkbox " value="gluten-free">
<label class=" ons-checkbox__label " for="gluten-free" id="gluten-free-label">Gluten free</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="lactose-intolerant" class="ons-checkbox__input ons-js-checkbox " value="lactose-intolerant">
<label class=" ons-checkbox__label " for="lactose-intolerant" id="lactose-intolerant-label">Lactose intolerant</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegan" class="ons-checkbox__input ons-js-checkbox " value="vegan">
<label class=" ons-checkbox__label " for="vegan" id="vegan-label">Vegan</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="vegetarian" class="ons-checkbox__input ons-js-checkbox " value="vegetarian">
<label class=" ons-checkbox__label " for="vegetarian" id="vegetarian-label">Vegetarian</label>
</span>
</span>
<br>
<span class="ons-checkboxes__item">
<span class="ons-checkbox ">
<input type="checkbox" id="other-checkbox" class="ons-checkbox__input ons-js-checkbox ons-js-other" value="other" checked aria-controls="other-checkbox-other-wrap" aria-haspopup="true">
<label class=" ons-checkbox__label " for="other-checkbox" id="other-checkbox-label">Other</label>
<span class="ons-checkbox__other" id="other-checkbox-other-wrap">
<label class="ons-label ons-u-fw-n" for="other-textbox" id="other-textbox-label">Enter dietary requirements</label>
<input type="text" id="other-textbox" class="ons-input ons-input--text ons-input-type__input ons-input--error ons-input--w-auto" name="other-answer" />
</span>
</span>
</span>
</div>
</div>
</div>
</div>
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
{{
onsCheckboxes({
"checkboxesLabel": "Select all that apply",
"name": "dietary",
"dontWrap": true,
"checkboxes": [
{
"id": "gluten-free",
"label": {
"text": "Gluten free"
},
"value": "gluten-free"
},
{
"id": "lactose-intolerant",
"label": {
"text": "Lactose intolerant"
},
"value": "lactose-intolerant"
},
{
"id": "vegan",
"label": {
"text": "Vegan"
},
"value": "vegan"
},
{
"id": "vegetarian",
"label": {
"text": "Vegetarian"
},
"value": "vegetarian"
},
{
"id": "other-checkbox",
"label": {
"text": "Other"
},
"checked": true,
"value": "other",
"other": {
"id": "other-textbox",
"name": "other-answer",
"label": {
"text": "Enter dietary requirements"
}
}
}
],
"error": {
"classes": "test",
"id": "dietary-error",
"text": "Enter your dietary requirements",
"dsExample": isPatternLib
}
})
}}
{% macro onsCheckboxes(params) %}
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
{% from "components/checkboxes/_checkbox-macro.njk" import onsCheckbox %}
{% from "components/button/_macro.njk" import onsButton %}
{% set fields %}
<p class="ons-checkboxes__label{{ " " + params.checkboxesLabelClasses if params.checkboxesLabelClasses }}">{{ params.checkboxesLabel }}</p>
{% set hasOther = false %}
{% for checkbox in params.checkboxes %}
{% if checkbox.other is defined and checkbox.other %}
{% set hasOther = true %}
{% endif %}
{% endfor %}
{% if hasOther == false and params.autoSelect is defined and params.autoSelect and params.autoSelect.selectAllText is defined %}
{% set btnClasses = ['small', 'secondary'] %}
{% if params.borderlessParent is defined and params.borderlessParent == false %}
{% set btnClasses = ['small', 'secondary', 'ghost-dark'] %}
{% endif %}
{{
onsButton({
"html": '<span class="ons-js-button-text">' + params.autoSelect.selectAllText + '</span>' + '<span class="ons-u-vh"> ' + params.autoSelect.context + '</span>',
"variants": btnClasses,
"classes": 'ons-u-mb-s ons-js-auto-selector',
"attributes": {
"data-unselect-all": params.autoSelect.unselectAllText,
"data-select-all": params.autoSelect.selectAllText
}
})
}}
{% endif %}
<div class="ons-checkboxes__items">
{% for checkbox in params.checkboxes %}
{% set childIsChecked = false %}
{% set labelHTML = checkbox.label.text %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% set exclusiveClass = ' ons-js-exclusive-group-item' %}
{% endif %}
{% if params.borderless is defined and params.borderless %}
{% set borderless = "ons-checkbox--no-border" %}
{% endif %}
{% if checkbox.other is defined and checkbox.other %}
{% set otherClass = " ons-js-other" %}
{% if checkbox.other.selectAllChildren is defined and checkbox.other.selectAllChildren == true %}
{% set otherClass = otherClass + " ons-js-select-all-children" %}
{% endif %}
{% for otherCheckbox in checkbox.other.checkboxes %}
{% if otherCheckbox.checked is defined and otherCheckbox.checked %}
{% set childIsChecked = true %}
{% endif %}
{% endfor %}
{% endif %}
<span class="ons-checkboxes__item{{ " ons-checkboxes__item--no-border" if params.borderless }}">
{% set config = {
"id": checkbox.id,
"name": checkbox.name,
"value": checkbox.value,
"checked": childIsChecked if childIsChecked == true else checkbox.checked,
"disabled": checkbox.disabled,
"borderless": params.borderless,
"classes": checkbox.classes | default('') + borderless | default(''),
"inputClasses": exclusiveClass | default('') + otherClass | default(''),
"label": {
"for": checkbox.id,
"text": labelHTML,
"description": checkbox.label.description,
"classes": checkbox.label.classes | default('')
},
"attributes": checkbox.attributes
} %}
{% if checkbox.other is defined and checkbox.other %}
{% set config = config | setAttributes({
"other": {
"open": checkbox.other.open | default(false),
"id": checkbox.other.id,
"name": checkbox.other.name,
"type": checkbox.other.type,
"otherType": checkbox.other.otherType,
"options": checkbox.other.options,
"width": checkbox.other.width,
"classes": ("ons-input--error" if params.error else "") + checkbox.other.classes | default('') + exclusiveClass | default(''),
"attributes": checkbox.other.attributes,
"label": {
"text": checkbox.other.label.text
},
"legend": checkbox.other.legend,
"legendClasses": checkbox.other.legendClasses | default('') + ' ons-u-mb-xs',
"value": checkbox.other.value,
"autoSelect": checkbox.other.autoSelect,
"selectAllChildren": checkbox.other.selectAllChildren,
"checkboxes": checkbox.other.checkboxes,
"radios": checkbox.other.radios
}
}) %}
{% endif %}
{{ onsCheckbox(config) }}
</span>
{% if not loop.last %}
<br>
{% endif %}
{% endfor %}
</div>
{% endset %}
{% if params.mutuallyExclusive is defined and params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"checkbox": params.mutuallyExclusive.checkbox,
"or": params.mutuallyExclusive.or,
"deselectMessage": params.mutuallyExclusive.deselectMessage,
"deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
"deselectCheckboxAdjective": params.mutuallyExclusive.deselectCheckboxAdjective,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% else %}
{% call onsFieldset({
"id": params.id,
"description": params.description,
"classes": params.classes,
"legend": params.legend,
"legendClasses": params.legendClasses,
"legendIsQuestionTitle": params.legendIsQuestionTitle,
"description": params.description,
"attributes": params.attributes,
"dontWrap": params.dontWrap,
"error": params.error
}) %}
{{ fields | safe }}
{% endcall %}
{% endif %}
{% endmacro %}
$checkbox-input-width: 22px;
$checkbox-padding: 11px;
.ons-checkbox {
display: inline-block;
position: relative;
width: 100%;
z-index: 1;
&__input {
appearance: none;
background: url(#{$static}/img/icons--check.svg) no-repeat center center;
background-color: $color-white;
background-size: 0;
border: 2px solid $color-input;
border-radius: 0.2rem;
box-sizing: border-box;
height: $checkbox-input-width;
left: $checkbox-padding;
position: absolute;
top: $checkbox-padding + 3px;
width: $checkbox-input-width;
z-index: 1;
&:focus,
&:checked {
outline: none;
}
&:checked {
background-size: 14px;
}
&:disabled {
border: 2px solid $color-border-disabled;
cursor: not-allowed;
}
&:disabled + label {
color: $color-grey-35;
cursor: not-allowed;
}
}
&--no-border {
& > .ons-checkbox__label {
padding: 0 0 0 1.85rem;
&::before {
background: none;
border: none;
box-shadow: none;
}
& > .ons-checkbox__label--with-description {
padding: 0;
}
}
& > .ons-checkbox__input {
left: 0.05rem;
top: 0.15rem;
&:checked,
&:focus {
background-color: initial;
& + .ons-checkbox__label::before {
background: none;
border: none;
box-shadow: none;
}
}
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
& .ons-checkbox__other {
margin: 0.5rem 0 0.5rem 0.5rem;
}
}
&__label {
cursor: pointer;
display: block;
padding: $checkbox-padding 1rem $checkbox-padding ($checkbox-padding * 2 + $checkbox-input-width);
width: 100%;
&--with-description {
padding: 0 1rem $checkbox-padding 0;
}
&::before {
background: $color-white;
border: 1px solid $color-input;
border-radius: 3px;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
* {
pointer-events: none;
}
}
&__description {
display: block;
margin-top: 0.25rem;
}
&__other {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 0 1rem 0.5rem 1.1rem;
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2 - 1;
}
&__input:checked + &__label::before {
background: $color-grey-5;
box-shadow: 0 0 0 1px $color-input;
}
.ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
border: 1px solid $color-ruby-red;
outline: 1px solid $color-ruby-red;
outline-offset: -2px;
}
&__input:focus + &__label::before {
@extend %ons-input-focus;
}
&__input:not(:checked) ~ &__other {
display: none;
}
&__input:not(:checked) ~ &__other--open {
display: block;
}
&--toggle & {
&__input {
left: 0;
top: 0.1rem;
&:focus {
box-shadow: 0 0 0 3px $color-focus;
}
}
&__label {
padding: 0 0 0 ($checkbox-input-width + $checkbox-padding);
&::before {
background: none;
border: 0;
}
}
&__input:checked + .ons-checkbox__label::before,
&__input:focus + .ons-checkbox__label::before {
background: transparent;
box-shadow: none;
}
&__input:focus + .ons-checkbox__label::before {
border: 0;
outline: none;
}
}
}
.ons-checkboxes {
&__label {
display: block;
margin: 0 0 0.5rem;
}
&__items {
display: block;
}
&__item {
display: inline-block;
margin: 0 0 0.5rem;
width: 100%;
&:last-child {
margin-bottom: 0;
}
@include mq(s) {
min-width: 20rem;
width: auto;
&--no-border {
min-width: 0;
}
}
}
&--mutually-exclusive__item {
@extend .ons-checkboxes__item;
margin-bottom: 0;
}
}
If no checkbox options have been selected
Use “Select [whatever it is]”.
For example, “Select your dietary requirements”.
If “checkbox with input” is selected but the input field is empty
Use “Enter your [whatever it is]”.
For example, “Enter your sexual orientation”.
If “checkbox with drop-down” is selected but a drop-down option has not been selected
Use “Select [whatever topic the drop-down is asking for]”.
For example, “Select the time of day you would like us to contact you”.
Help improve this component
Let us know how we could improve this component or share your user research findings. Discuss the ‘Checkboxes’ component on GitHub