<div class="bux-details__wrapper">
    <details class="bux-details">
        <summary class="bux-details__summary">Title of Accordion</summary>
        <div class="bux-details__inner">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        </div>
    </details>
</div>
<div class="bux-details__wrapper">
    <details class="bux-details">
        <summary class="bux-details__summary">Title of Accordion</summary>
        <div class="bux-details__inner">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        </div>
    </details>
</div>
<div class="bux-details__wrapper">
    <details class="bux-details">
        <summary class="bux-details__summary">Title of Accordion</summary>
        <div class="bux-details__inner">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        </div>
    </details>
</div>
{# 

Accordion

Available variables:

- modifier:         Sets the type of accordion. 'default' or 'details'.  
- heading_level:    Integer value that sets the heading level of the title.
- items:            An array containing the accordion items.
- item.id:          Unique id for the accordion.
- item.title:       Title of the accordion.
- item.content:     Content of the accordion.

#}

{% if modifier == "default" %}
<div class="bux-accordion" data-allow-multiple>
	{% for item in items %}
		{% set triggerId = "bux-accordion__trigger--" ~ item.id %}
		{% set panelId = "bux-accordion__panel--" ~ item.id %}
		<h{{heading_level|default("2")}} class="bux-accordion__heading">
			<button id="{{ triggerId }}" type="button" class="bux-accordion__trigger" aria-controls="{{ panelId }}" aria-expanded="false">
				<span class="bux-accordion__icon" aria-hidden="true"></span>
				<span class="bux-accordion__title">
					{{ item.title }}
				</span>
			</button>
		</h{{heading_level|default("2")}}>
		<div id="{{ panelId }}" class="bux-accordion__panel" role="region" aria-labelledby="{{ triggerId }}" hidden>
			{{ item.content }}
		</div>
	{% endfor %}
</div>
{% elseif modifier == "details" %}
{% for item in items %}
<div class="bux-details__wrapper">
<details class="bux-details">
  <summary class="bux-details__summary">{{ item.title }}</summary>
  <div class="bux-details__inner">
		{{ item.content }}
	</div>
</details>
</div>
{% endfor %}
{% endif %}
site_name_prefix: Office of
site_name: Learning Relations Excellence
site_slogan: Additional text or site slogan
address_1: 100 Building Name
address_2: 1 Oval Mall
city: Columbus
state: OH
zip: '43210'
contact_email: email@osu.edu
contact_phone: 614-292-OHIO
contact_tty: 614-688-8605
heading_level: 3
items:
  '1':
    id: 1
    title: Title of Accordion
    content: >-
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
      veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
      commodo consequat.
  '2':
    id: 2
    title: Title of Accordion
    content: >-
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
      veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
      commodo consequat.
  '3':
    id: 3
    title: Title of Accordion
    content: >-
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
      veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
      commodo consequat.
modifier: details
  • Content:
    .bux-accordion {
    	border-bottom: 2px solid $gray-light-80;
    }
    
    .bux-accordion__heading {
    	margin-bottom: 0;
    }
    
    .bux-accordion__trigger {
    	@include button-reset;
    	color: $gray-dark-80;
    	background-color: $white;
    	border-top: 2px solid $gray-light-80;
    	padding: $sp-16;
    	width: 100%;
    	text-align: left;
    	position: relative;
    	&:focus,
    	&:hover {
    		color: $gray-dark-80;
    		background: $gray-light-90;
    		border: none;
    		border-top: 2px solid $gray-light-80;
    	}
    	&:focus {
            outline: 2px solid $focus;
    		outline-offset: -2px;
    	}
    }
    
    .bux-accordion__trigger[aria-expanded="true"] {
    	background: $white;
    	&:hover {
    		background: $gray-light-90;
    	}
    }
    
    .bux-accordion__title {
    	font-size: $ts-base;
    	display: block;
    	pointer-events: none;
    	font-weight: 700;
    	padding-left: rem-calc(26);
    }
    
    .bux-accordion__icon:before {
    	position: absolute;
    	color: $scarlet;
    	font-size: $ts-base;
    	left: $sp-16;
    	top: 36%;
    	content: "\f005";
    	font-family: $icon;
    }
    
    .bux-accordion__trigger[aria-expanded="true"] .bux-accordion__icon:before {
    	content: "\f007";
    }
    
    .bux-accordion__panel {
    	margin: 0;
    	padding: rem-calc(8 16 24 44);
    	font-family: $sans;
    	font-size: $ts-base;
    	background-color: $white;
    
        p {
            font-family: $sans;
        }
    }
    
    /* For Edge bug https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4806035/ */
    .bux-accordion__panel[hidden] {
    	display: none;
    }
    
    /* Fix for accordion list font family */
    
    .bux-accordion ul.bux-list-ul {
    	font-family: $sans;
    }
    
    .bux-details {
    	width: 100%;
    	text-align: left;
    }
    
    .bux-details__summary {
    	list-style: none;
    	border-top: none;
    	border-bottom: 2px solid $gray-light-80;
    	padding: $sp-16;
    	font-size: $ts-base;
    	font-weight: 700;
    	line-height: normal;
    
    	
    	&:focus,
    	&:hover {
    		background: $gray-light-90;
    	}
    	&:focus {
    		outline-offset: -2px;
    		outline: 2px solid $focus;
    	}
    
    	&:before {
    		position: relative;
    		top: 2px;
    		margin-right: rem-calc(10);
    		color: $scarlet;
    		font-size: $ts-base;
    		content: "\f005";
    		font-family: $icon;
    	}
    }
    
    .bux-details__wrapper .bux-detail:first-child .bux-details__summary {
    	border-top: 2px solid $gray-light-80;
    }
    
    .bux-details__inner {
    	padding: rem-calc(8 16 24 44);
    
    	ul.bux-list-ul {
    		font-family: $sans;
    	}
    
    	p:last-child {
    		margin-bottom: 0;
    	}
    }
    
    // When open.
    .bux-details[open] {
    	border-bottom: 2px solid $gray-light-80;
    
    	.bux-details__summary {
    		background: $white;
    		border-bottom: none;
    
    		&:hover {
    			background: $gray-light-90;
    		}
    
    		&:before {
    			content: "\f007";
    		}
    	}
    }
    
    // Fix for double arrow in Safari
    *::-webkit-details-marker {
    	display: none;
    }
    
  • URL: /components/raw/accordion-group/_accordion-group.scss
  • Filesystem Path: src/components/accordion-group/_accordion-group.scss
  • Size: 2.6 KB
  • Content:
        const accordionClass = "bux-accordion";
    
    	let accordions = document.querySelectorAll(`.${accordionClass}`);
    	accordions = Array.prototype.slice.call(accordions);
    
    	accordions.forEach((accordion) => {
    		let triggers = accordion.querySelectorAll(`.${accordionClass}__trigger`);
    		triggers = Array.prototype.slice.call(triggers);
    
    		let panels = accordion.querySelectorAll(`.${accordionClass}__panel`);
    		panels = Array.prototype.slice.call(panels);
    
    		triggers.forEach((trigger) => {
    			trigger.addEventListener("keydown", handleKeys);
    			trigger.addEventListener("click", (event) => {
    				const { currentTarget: currentTrigger } = event;
    
    				if (!allowMultipleOpen(currentTrigger)) {
    					closeAccordionItems(currentTrigger, triggers, panels);
    				}
    
    				toggleAccordionItem(currentTrigger);
    			});
    		});
    	});
    
    	function handleKeys(event) {
    		const {
    			key: currentKey,
    			currentTarget: currentTrigger,
    			currentTarget: {
    				parentNode: { parentNode: currentAccordion },
    			},
    		} = event;
    
    		let triggers = currentAccordion.querySelectorAll(`.${accordionClass}__trigger`);
    		triggers = Array.prototype.slice.call(triggers);
    
    		const currentTriggerIndex = triggers.indexOf(currentTrigger);
    
    		switch (currentKey) {
    			case keys.up:
    				if (currentTriggerIndex === 0) {
    					triggers[triggers.length - 1].focus();
    				} else {
    					triggers[currentTriggerIndex - 1].focus();
    				}
    				event.preventDefault();
    				break;
    			case keys.down:
    				if (currentTriggerIndex === triggers.length - 1) {
    					triggers[0].focus();
    				} else {
    					triggers[currentTriggerIndex + 1].focus();
    				}
    				event.preventDefault();
    				break;
    			case keys.home:
    				triggers[0].focus();
    				event.preventDefault();
    				break;
    			case keys.end:
    				triggers[triggers.length - 1].focus();
    				event.preventDefault();
    				break;
    		}
    	}
    
    	function isHeading(element) {
    		return element && element.classList.contains(`${accordionClass}__heading`);
    	}
    
    	function toggleAccordionItem(element) {
    		let currentTriggerExpanded = element.getAttribute("aria-expanded");
    		currentTriggerExpanded = currentTriggerExpanded === "true" ? true : false;
    
    		element.setAttribute("aria-expanded", !currentTriggerExpanded);
    
    		const currentPanelId = element.getAttribute("aria-controls");
    		const currentPanel = document.querySelector(`#${currentPanelId}`);
    		let currentPanelHidden = currentPanel.getAttribute("hidden");
    
    		if (currentPanelHidden !== null) {
    			currentPanel.removeAttribute("hidden");
    		} else {
    			currentPanel.setAttribute("hidden", "hidden");
    		}
    	}
    
    	function allowMultipleOpen(element) {
    		const {
    			parentNode: { parentNode: currentAccordion },
    		} = element;
    
    		const {
    			dataset: { allowMultiple: hasAllowMultiple },
    		} = currentAccordion;
    
    		return hasAllowMultiple !== undefined ? true : false;
    	}
    
    	function closeAccordionItems(trigger, triggers, panels) {
    		const otherTriggers = triggers.filter((element) => element !== trigger);
    
    		otherTriggers.forEach((otherTrigger) => {
    			otherTrigger.setAttribute("aria-expanded", false);
    		});
    
    		const currentPanelId = trigger.getAttribute("aria-controls");
    		const currentPanel = document.querySelector(`#${currentPanelId}`);
    		const otherPanels = panels.filter((element) => element !== currentPanel);
    
    		otherPanels.forEach((otherPanel) => {
    			otherPanel.setAttribute("hidden", "hidden");
    		});
    	}
    
  • URL: /components/raw/accordion-group/accordion-group.js
  • Filesystem Path: src/components/accordion-group/accordion-group.js
  • Size: 3.3 KB
  • Handle: @accordion-group--details
  • Preview:
  • Filesystem Path: src/components/accordion-group/accordion-group.twig

Accordion component

This component is based on the guidelines laid out in the W3’s example, Accordion Example.

Keyboard support

Key Fuction
Space or Enter

When focus is on the accordion header of a collapsed section, expands the section.

Tab
  • Moves focus to the next focusable element.
  • All focusable elements in the accordion are included in the page tab sequence.
Shift + Tab
  • Moves focus to the previous focusable element.
  • All focusable elements in the accordion are included in the page tab sequence.
Down Arrow
  • When focus is on an accordion header, moves focus to the next accordion header.
  • When focus is on last accordion header, moves focus to first accordion header.
Up Arrow
  • When focus is on an accordion header, moves focus to the previous accordion header.
  • When focus is on first accordion header, moves focus to last accordion header.
Home

When focus is on an accordion header, moves focus to the first accordion header.

End

When focus is on an accordion header, moves focus to the last accordion header.

Data attributes

Multiple accordion items open

data-allow-multiple — By adding this data attribute to the accordion multiple accordion items can be open at any given time.