Collapsible
The collapsible component is used to simplify a page by allowing the user to reveal certain content only if they need it.
<div id="collapsible" class="ons-collapsible ons-js-collapsible">
<div class="ons-collapsible__heading ons-js-collapsible-heading">
<div class="ons-collapsible__controls">
<h2 class="ons-collapsible__title">What is a photovoltaic system?</h2>
<span class="ons-collapsible__icon">
<svg class="ons-svg-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
</svg>
</span>
</div>
</div>
<div id="collapsible-content" class="ons-collapsible__content ons-js-collapsible-content">
<p>A typical photovoltaic system employs solar panels, each comprising a number of solar cells, which generate electrical power. PV installations may be ground-mounted, rooftop mounted or wall mounted. The mount may be fixed, or use a solar tracker to follow the sun across the sky.</p>
<button type="button" class="ons-btn ons-js-collapsible-button ons-u-d-no ons-btn--secondary ons-btn--small">
<span class="ons-btn__inner ons-js-collapsible-button-inner"><span class="ons-btn__text">Hide this</span>
</span>
<span class="ons-btn__context ons-u-vh">What is a photovoltaic system? content</span>
</button>
</div>
</div>
{% from "components/collapsible/_macro.njk" import onsCollapsible %}
{{
onsCollapsible({
"id": "collapsible",
"title": "What is a photovoltaic system?",
"content": "<p>A typical photovoltaic system employs solar panels, each comprising a number of solar cells, which generate electrical power. PV installations may be ground-mounted, rooftop mounted or wall mounted. The mount may be fixed, or use a solar tracker to follow the sun across the sky.</p>"
})
}}
{% macro onsCollapsible(params) %}
{% from "components/button/_macro.njk" import onsButton %}
<div
id="{{ params.id }}"
class="ons-collapsible ons-js-collapsible{% if params.isAccordion is defined and params.isAccordion %} ons-collapsible--accordion{% endif %}{% if params.classes is defined and params.classes %} {{ params.classes }}{% endif %}{% if params.variants is defined and params.variants %}{% if params.variants is not string %}{% for variant in params.variants %} ons-collapsible--{{ variant }}{% endfor %}{% else %} ons-collapsible--{{ params.variants }}{% endif %}{% endif %}"
{% if params.button is defined and params.button and params.button.close is defined and params.button.close %} data-btn-close="{{ params.button.close }}"{% endif %}
{% if params.group is defined and params.group %} data-group="{{ params.group }}"{% endif %}
{% if params.attributes is defined and params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
{% if params.saveState is defined and params.saveState %} data-save-state="true"{% endif %}
{% if params.open is defined and params.open %} data-open="true"{% endif %}
>
<div
class="ons-collapsible__heading ons-js-collapsible-heading"
{% if params.headingAttributes is defined and params.headingAttributes %}{% for attribute, value in (params.headingAttributes.items() if params.headingAttributes is mapping and params.headingAttributes.items else params.headingAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{# Required to use display flex on Safari as it's not currently supported: https://bugs.webkit.org/show_bug.cgi?id=167111 #}
<div class="ons-collapsible__controls">
{% set titleTag = params.titleTag | default("h2") %}
<{{ titleTag }} class="ons-collapsible__title">{{ params.title }}</{{ titleTag }}>
<span class="ons-collapsible__icon">
{% from "components/icons/_macro.njk" import onsIcon %}
{{
onsIcon({
"iconType": "chevron"
})
}}</span>
{% if params.button is defined and params.button and params.button.open is defined and params.button.open and params.isAccordion is defined and params.isAccordion %}
{{
onsButton({
"type": "button",
"text": params.button.open,
"classes": "ons-collapsible__btn ons-js-collapsible-button ons-u-d-no ons-u-d-no@xxs@s",
"innerClasses": "ons-js-collapsible-button-inner",
"variants": ["secondary", "small"],
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
<div id="{{ params.id }}-content" class="ons-collapsible__content ons-js-collapsible-content"
{% if params.contentAttributes is defined and params.contentAttributes %}{% for attribute, value in (params.contentAttributes.items() if params.contentAttributes is mapping and params.contentAttributes.items else params.contentAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{% if params.isAccordion is defined and params.isAccordion %}
{{ params.content | safe }}{{ caller() if caller }}
{% else %}
{{ params.content | safe }}{{ caller() if caller }}
{{
onsButton({
"type": "button",
"text": params.button.close | default ('Hide this'),
"buttonContext": (params.button.context | default(params.title)) + " " + params.button.contextSuffix | default("content"),
"classes": "ons-js-collapsible-button ons-u-d-no " + (params.button.classes | default("ons-btn--secondary")),
"innerClasses": "ons-js-collapsible-button-inner",
"variants": "small",
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
{% endmacro %}
$collapsible-caret-width: 1.5rem;
.ons-collapsible {
&--initialised & {
&__heading {
color: $color-text-link;
cursor: pointer;
display: inline-block;
outline: none;
padding: 0 0 0 $collapsible-caret-width;
pointer-events: initial;
position: relative;
&::marker {
display: none;
}
&:focus {
.ons-collapsible__title {
@extend %a-focus;
// extend collapsible focus background behind caret
margin-left: -$collapsible-caret-width;
padding-left: $collapsible-caret-width;
}
.ons-collapsible__icon .ons-svg-icon {
fill: $color-text-link-focus;
}
}
&:hover:not(:focus) {
color: $color-text-link-hover;
.ons-collapsible__icon {
fill: $color-text-link-hover;
}
.ons-collapsible__title {
text-decoration: underline solid $color-text-link-hover 2px;
}
}
}
&__icon {
display: inline-block;
fill: $color-text-link;
height: $collapsible-caret-width;
left: -0.15rem;
position: absolute;
top: -0.25rem;
width: $collapsible-caret-width;
}
&__title {
font-size: 1rem;
font-weight: $font-weight-bold;
margin-bottom: 0;
text-decoration: underline;
text-underline-position: under;
transform: translateY(-1px);
}
&__content {
display: none;
}
}
&__icon {
display: none;
}
&--open & {
&__icon {
left: -0.1rem;
top: 0.1rem;
transform: rotate(90deg);
}
&__content {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 1rem 0 0;
padding: 0 0 0 1.3em;
.ons-btn {
margin-bottom: 0.5rem;
}
}
}
&--accordion {
margin: 0;
&.ons-collapsible--open {
.ons-svg-icon {
left: 0.4rem;
position: absolute;
top: 0.25rem;
}
}
}
&--accordion & {
&__heading {
border-top: 1px solid $color-borders;
margin: 0;
padding-bottom: 1rem;
padding-top: 1rem;
width: 100%;
&:focus {
outline: none;
}
}
&__title {
margin: 0 1rem 0 0;
}
&__icon {
top: 0.8rem;
@include mq(s) {
top: 1.15rem;
}
}
&__controls {
align-items: center;
display: flex;
justify-content: space-between;
}
&__btn {
align-self: flex-start;
width: auto;
}
&__content {
border-left: 0;
margin: 0;
padding: 0;
}
}
&--simple & {
&__icon {
top: 0.8rem;
}
}
}
When to use this component
Use the collapsible component to make a page easier to read by condensing information that is only needed by some users.
The collapsible can be used to condense a single block of content into a single selectable heading, allowing the user to reveal it if and when they need it.
It also includes a hide button to close the collapsible when needed. We recommend adding aria-hidden="true"
to the button in order so that screen reading software will not pick this up.
Good uses of the collapsible component are:
- to reveal additional help at the point where a user may need it, for example, to help answer a question
- to show the definition of a term that may not be well understood
When not to use this component
Don’t use the collapsible component to hide information that the majority of your users will need to progress with their task.
Alternative components
Accordions, tabs and collapsible all hide sections of content which a user can show or hide.
Variants
Use the collapsible component instead of tabs or accordions if there is only one section of content that needs to be condensed.
Collapsible with save state enabled
<div id="collapsible-with-save" class="ons-collapsible ons-js-collapsible" data-btn-close="Hide this" data-save-state="true">
<div class="ons-collapsible__heading ons-js-collapsible-heading">
<div class="ons-collapsible__controls">
<h2 class="ons-collapsible__title">What is a photovoltaic system?</h2>
<span class="ons-collapsible__icon">
<svg class="ons-svg-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
</svg>
</span>
</div>
</div>
<div id="collapsible-with-save-content" class="ons-collapsible__content ons-js-collapsible-content">
<p>A typical photovoltaic system employs solar panels, each comprising a number of solar cells, which generate electrical power. PV installations may be ground-mounted, rooftop mounted or wall mounted. The mount may be fixed, or use a solar tracker to follow the sun across the sky.</p>
<button type="button" class="ons-btn ons-js-collapsible-button ons-u-d-no ons-btn--secondary ons-btn--small" aria-hidden="true">
<span class="ons-btn__inner ons-js-collapsible-button-inner"><span class="ons-btn__text">Hide this</span>
</span>
<span class="ons-btn__context ons-u-vh">What is a photovoltaic system? content</span>
</button>
</div>
</div>
{% from "components/collapsible/_macro.njk" import onsCollapsible %}
{{
onsCollapsible({
"id": "collapsible-with-save",
"title": "What is a photovoltaic system?",
"content": "<p>A typical photovoltaic system employs solar panels, each comprising a number of solar cells, which generate electrical power. PV installations may be ground-mounted, rooftop mounted or wall mounted. The mount may be fixed, or use a solar tracker to follow the sun across the sky.</p>",
"button": {
"close": "Hide this",
"attributes": {
"aria-hidden": "true"
}
},
"saveState": "true"
})
}}
{% macro onsCollapsible(params) %}
{% from "components/button/_macro.njk" import onsButton %}
<div
id="{{ params.id }}"
class="ons-collapsible ons-js-collapsible{% if params.isAccordion is defined and params.isAccordion %} ons-collapsible--accordion{% endif %}{% if params.classes is defined and params.classes %} {{ params.classes }}{% endif %}{% if params.variants is defined and params.variants %}{% if params.variants is not string %}{% for variant in params.variants %} ons-collapsible--{{ variant }}{% endfor %}{% else %} ons-collapsible--{{ params.variants }}{% endif %}{% endif %}"
{% if params.button is defined and params.button and params.button.close is defined and params.button.close %} data-btn-close="{{ params.button.close }}"{% endif %}
{% if params.group is defined and params.group %} data-group="{{ params.group }}"{% endif %}
{% if params.attributes is defined and params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
{% if params.saveState is defined and params.saveState %} data-save-state="true"{% endif %}
{% if params.open is defined and params.open %} data-open="true"{% endif %}
>
<div
class="ons-collapsible__heading ons-js-collapsible-heading"
{% if params.headingAttributes is defined and params.headingAttributes %}{% for attribute, value in (params.headingAttributes.items() if params.headingAttributes is mapping and params.headingAttributes.items else params.headingAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{# Required to use display flex on Safari as it's not currently supported: https://bugs.webkit.org/show_bug.cgi?id=167111 #}
<div class="ons-collapsible__controls">
{% set titleTag = params.titleTag | default("h2") %}
<{{ titleTag }} class="ons-collapsible__title">{{ params.title }}</{{ titleTag }}>
<span class="ons-collapsible__icon">
{% from "components/icons/_macro.njk" import onsIcon %}
{{
onsIcon({
"iconType": "chevron"
})
}}</span>
{% if params.button is defined and params.button and params.button.open is defined and params.button.open and params.isAccordion is defined and params.isAccordion %}
{{
onsButton({
"type": "button",
"text": params.button.open,
"classes": "ons-collapsible__btn ons-js-collapsible-button ons-u-d-no ons-u-d-no@xxs@s",
"innerClasses": "ons-js-collapsible-button-inner",
"variants": ["secondary", "small"],
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
<div id="{{ params.id }}-content" class="ons-collapsible__content ons-js-collapsible-content"
{% if params.contentAttributes is defined and params.contentAttributes %}{% for attribute, value in (params.contentAttributes.items() if params.contentAttributes is mapping and params.contentAttributes.items else params.contentAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{% if params.isAccordion is defined and params.isAccordion %}
{{ params.content | safe }}{{ caller() if caller }}
{% else %}
{{ params.content | safe }}{{ caller() if caller }}
{{
onsButton({
"type": "button",
"text": params.button.close | default ('Hide this'),
"buttonContext": (params.button.context | default(params.title)) + " " + params.button.contextSuffix | default("content"),
"classes": "ons-js-collapsible-button ons-u-d-no " + (params.button.classes | default("ons-btn--secondary")),
"innerClasses": "ons-js-collapsible-button-inner",
"variants": "small",
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
{% endmacro %}
$collapsible-caret-width: 1.5rem;
.ons-collapsible {
&--initialised & {
&__heading {
color: $color-text-link;
cursor: pointer;
display: inline-block;
outline: none;
padding: 0 0 0 $collapsible-caret-width;
pointer-events: initial;
position: relative;
&::marker {
display: none;
}
&:focus {
.ons-collapsible__title {
@extend %a-focus;
// extend collapsible focus background behind caret
margin-left: -$collapsible-caret-width;
padding-left: $collapsible-caret-width;
}
.ons-collapsible__icon .ons-svg-icon {
fill: $color-text-link-focus;
}
}
&:hover:not(:focus) {
color: $color-text-link-hover;
.ons-collapsible__icon {
fill: $color-text-link-hover;
}
.ons-collapsible__title {
text-decoration: underline solid $color-text-link-hover 2px;
}
}
}
&__icon {
display: inline-block;
fill: $color-text-link;
height: $collapsible-caret-width;
left: -0.15rem;
position: absolute;
top: -0.25rem;
width: $collapsible-caret-width;
}
&__title {
font-size: 1rem;
font-weight: $font-weight-bold;
margin-bottom: 0;
text-decoration: underline;
text-underline-position: under;
transform: translateY(-1px);
}
&__content {
display: none;
}
}
&__icon {
display: none;
}
&--open & {
&__icon {
left: -0.1rem;
top: 0.1rem;
transform: rotate(90deg);
}
&__content {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 1rem 0 0;
padding: 0 0 0 1.3em;
.ons-btn {
margin-bottom: 0.5rem;
}
}
}
&--accordion {
margin: 0;
&.ons-collapsible--open {
.ons-svg-icon {
left: 0.4rem;
position: absolute;
top: 0.25rem;
}
}
}
&--accordion & {
&__heading {
border-top: 1px solid $color-borders;
margin: 0;
padding-bottom: 1rem;
padding-top: 1rem;
width: 100%;
&:focus {
outline: none;
}
}
&__title {
margin: 0 1rem 0 0;
}
&__icon {
top: 0.8rem;
@include mq(s) {
top: 1.15rem;
}
}
&__controls {
align-items: center;
display: flex;
justify-content: space-between;
}
&__btn {
align-self: flex-start;
width: auto;
}
&__content {
border-left: 0;
margin: 0;
padding: 0;
}
}
&--simple & {
&__icon {
top: 0.8rem;
}
}
}
Collapsible with warning panel
<div id="collapsible" class="ons-collapsible ons-js-collapsible" data-btn-close="Hide this">
<div class="ons-collapsible__heading ons-js-collapsible-heading">
<div class="ons-collapsible__controls">
<h2 class="ons-collapsible__title">Need to answer separately from your household?</h2>
<span class="ons-collapsible__icon">
<svg class="ons-svg-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false" fill="currentColor">
<path d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z" transform="translate(-5.02 -1.59)" />
</svg>
</span>
</div>
</div>
<div id="collapsible-content" class="ons-collapsible__content ons-js-collapsible-content">
<p>If you need to answer separately from the people you live with, you can <a href="#0">request an individual access code</a> to start a separate census.</p>
<div class="ons-panel ons-panel--warn ons-panel--no-title">
<span class="ons-panel__icon" aria-hidden="true">!</span>
<span class="ons-panel__assistive-text ons-u-vh">Warning: </span>
<div class="ons-panel__body">
Someone in your household must still complete a census using a household access code
</div>
</div>
<button type="button" class="ons-btn ons-js-collapsible-button ons-u-d-no ons-btn--secondary ons-btn--small" aria-hidden="true">
<span class="ons-btn__inner ons-js-collapsible-button-inner"><span class="ons-btn__text">Hide this</span>
</span>
<span class="ons-btn__context ons-u-vh">Need to answer separately from your household? content</span>
</button>
</div>
</div>
{% from "components/collapsible/_macro.njk" import onsCollapsible %}
{% from "components/panel/_macro.njk" import onsPanel %}
{%
call onsCollapsible({
"id": "collapsible",
"title": "Need to answer separately from your household?",
"button": {
"close": "Hide this",
"contextSuffix": "content",
"attributes": {
"aria-hidden": "true"
}
}
})
%}
<p>If you need to answer separately from the people you live with, you can <a href="#0">request an individual access code</a> to start a separate census.</p>
{% call onsPanel({
type: "warn"
})
%}
Someone in your household must still complete a census using a household access code
{% endcall %}
{% endcall %}
{% macro onsCollapsible(params) %}
{% from "components/button/_macro.njk" import onsButton %}
<div
id="{{ params.id }}"
class="ons-collapsible ons-js-collapsible{% if params.isAccordion is defined and params.isAccordion %} ons-collapsible--accordion{% endif %}{% if params.classes is defined and params.classes %} {{ params.classes }}{% endif %}{% if params.variants is defined and params.variants %}{% if params.variants is not string %}{% for variant in params.variants %} ons-collapsible--{{ variant }}{% endfor %}{% else %} ons-collapsible--{{ params.variants }}{% endif %}{% endif %}"
{% if params.button is defined and params.button and params.button.close is defined and params.button.close %} data-btn-close="{{ params.button.close }}"{% endif %}
{% if params.group is defined and params.group %} data-group="{{ params.group }}"{% endif %}
{% if params.attributes is defined and params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
{% if params.saveState is defined and params.saveState %} data-save-state="true"{% endif %}
{% if params.open is defined and params.open %} data-open="true"{% endif %}
>
<div
class="ons-collapsible__heading ons-js-collapsible-heading"
{% if params.headingAttributes is defined and params.headingAttributes %}{% for attribute, value in (params.headingAttributes.items() if params.headingAttributes is mapping and params.headingAttributes.items else params.headingAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{# Required to use display flex on Safari as it's not currently supported: https://bugs.webkit.org/show_bug.cgi?id=167111 #}
<div class="ons-collapsible__controls">
{% set titleTag = params.titleTag | default("h2") %}
<{{ titleTag }} class="ons-collapsible__title">{{ params.title }}</{{ titleTag }}>
<span class="ons-collapsible__icon">
{% from "components/icons/_macro.njk" import onsIcon %}
{{
onsIcon({
"iconType": "chevron"
})
}}</span>
{% if params.button is defined and params.button and params.button.open is defined and params.button.open and params.isAccordion is defined and params.isAccordion %}
{{
onsButton({
"type": "button",
"text": params.button.open,
"classes": "ons-collapsible__btn ons-js-collapsible-button ons-u-d-no ons-u-d-no@xxs@s",
"innerClasses": "ons-js-collapsible-button-inner",
"variants": ["secondary", "small"],
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
<div id="{{ params.id }}-content" class="ons-collapsible__content ons-js-collapsible-content"
{% if params.contentAttributes is defined and params.contentAttributes %}{% for attribute, value in (params.contentAttributes.items() if params.contentAttributes is mapping and params.contentAttributes.items else params.contentAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
>
{% if params.isAccordion is defined and params.isAccordion %}
{{ params.content | safe }}{{ caller() if caller }}
{% else %}
{{ params.content | safe }}{{ caller() if caller }}
{{
onsButton({
"type": "button",
"text": params.button.close | default ('Hide this'),
"buttonContext": (params.button.context | default(params.title)) + " " + params.button.contextSuffix | default("content"),
"classes": "ons-js-collapsible-button ons-u-d-no " + (params.button.classes | default("ons-btn--secondary")),
"innerClasses": "ons-js-collapsible-button-inner",
"variants": "small",
"attributes": params.button.attributes
})
}}
{% endif %}
</div>
</div>
{% endmacro %}
$collapsible-caret-width: 1.5rem;
.ons-collapsible {
&--initialised & {
&__heading {
color: $color-text-link;
cursor: pointer;
display: inline-block;
outline: none;
padding: 0 0 0 $collapsible-caret-width;
pointer-events: initial;
position: relative;
&::marker {
display: none;
}
&:focus {
.ons-collapsible__title {
@extend %a-focus;
// extend collapsible focus background behind caret
margin-left: -$collapsible-caret-width;
padding-left: $collapsible-caret-width;
}
.ons-collapsible__icon .ons-svg-icon {
fill: $color-text-link-focus;
}
}
&:hover:not(:focus) {
color: $color-text-link-hover;
.ons-collapsible__icon {
fill: $color-text-link-hover;
}
.ons-collapsible__title {
text-decoration: underline solid $color-text-link-hover 2px;
}
}
}
&__icon {
display: inline-block;
fill: $color-text-link;
height: $collapsible-caret-width;
left: -0.15rem;
position: absolute;
top: -0.25rem;
width: $collapsible-caret-width;
}
&__title {
font-size: 1rem;
font-weight: $font-weight-bold;
margin-bottom: 0;
text-decoration: underline;
text-underline-position: under;
transform: translateY(-1px);
}
&__content {
display: none;
}
}
&__icon {
display: none;
}
&--open & {
&__icon {
left: -0.1rem;
top: 0.1rem;
transform: rotate(90deg);
}
&__content {
border-left: 4px solid $color-borders-indent;
display: block;
margin: 1rem 0 0;
padding: 0 0 0 1.3em;
.ons-btn {
margin-bottom: 0.5rem;
}
}
}
&--accordion {
margin: 0;
&.ons-collapsible--open {
.ons-svg-icon {
left: 0.4rem;
position: absolute;
top: 0.25rem;
}
}
}
&--accordion & {
&__heading {
border-top: 1px solid $color-borders;
margin: 0;
padding-bottom: 1rem;
padding-top: 1rem;
width: 100%;
&:focus {
outline: none;
}
}
&__title {
margin: 0 1rem 0 0;
}
&__icon {
top: 0.8rem;
@include mq(s) {
top: 1.15rem;
}
}
&__controls {
align-items: center;
display: flex;
justify-content: space-between;
}
&__btn {
align-self: flex-start;
width: auto;
}
&__content {
border-left: 0;
margin: 0;
padding: 0;
}
}
&--simple & {
&__icon {
top: 0.8rem;
}
}
}
How to use this component
The collapsible component uses JavaScript so when it’s turned off, the section of content is expanded and displayed as a standard heading and paragraph.
Use an appropriate heading tag (h2, h3 etc) for the ons-collapsible__title
to provide the correct semantic hierarchy to the document with the rest of the page.
Use a clear label
The collapsible component hides content so make sure your heading is clear so the user doesn’t need to work hard to understand if they need to click on it.
Accessibility
The collapsible component is made accessible by using the following aria
attributes which are attached on domready
via Javascript:
Element | ARIA attribute | Description |
---|---|---|
.ons-collapsible
|
aria-expanded="true/false"
|
Indicates the state of the associated .ons-collapsible__heading
|
aria-selected="true/false"
|
Indicates the selected state of the focused .ons-collapsible element
|
|
.collapsible__heading
|
aria-controls="{ID}-content"
|
Indicates the id of the display controller element for the associated .collapsible__content block.
|
button
|
aria-controls="{ID}-content"
|
Indicates the id of the display controller element for the associated .ons-collapsible__content block.
|
.ons-collapsible__content
|
aria-hidden="true/false"
|
Indicates the visibility of the element and all of its descendants. |
Google analytics
Optionally pass event tracking data
attributes for Google Analytics using data-ga="click"
, data-ga-category="definition"
, data-ga-action="Open/Close panel"
, data-ga-label="{TITLE}"
Help improve this component
Let us know how we could improve this component or share your user research findings. Discuss the ‘Collapsible’ component on GitHub