Accordion
الأقسام المطويةaria-expanded + aria-controls
also calledcollapsible، collapse، expansion panel، disclosure group، expander، أكورديون، قوائم قابلة للطيّ، أقسام قابلة للتوسيع، لوحات مطوية، كولابس
An accordion is a vertical stack of headers, each one a button that expands or collapses a panel of content directly beneath it. The unit is the item, meaning a header plus its own panel, and the group as a whole is governed by one policy: exactly one panel open at a time, or several at once. It is not tabs. Tabs are peers sharing one fixed-height frame that shows a single panel and can never show two together, while an expanding accordion item pushes everything below it down and changes the height of the page itself. A dropdown is not the same thing either: it floats in a layer above the page and hands the page back untouched when it closes, whereas an accordion panel lives inside the content flow and reflows what surrounds it. Nor is it a single disclosure, which is one standalone button revealing one block, with no siblings and no policy coordinating them. The details and summary elements are the browser's own implementation: they give you the behaviour and the accessibility semantics without a line of JavaScript, but animating their height is painful because the browser swaps state in a single frame. As a practical rule, never fold away content the reader has to read anyway. Collapsing is for secondary or repetitive material such as FAQs and order details.
If you called it…
Live specimen
Interact with the demo. Every part is real and numbered.
التبويبات إطار ثابت الارتفاع؛ القسم يدفع ما تحته.
يعطيك السلوك والوصولية بلا JavaScript، لكن تحريكه متعب.
الأول فقط، أو لا شيء إذا كفت العناوين وحدها.
Anatomy: every part, named
Hover a row to locate it in the demo above.
Build prompt
How it behaves right-to-left
This section is ours alone.
Where the indicator sits
mirrorsThe indicator belongs at the logical end of the header: right in English, left in Arabic. Make the header a flex row with justify-content: space-between and put the indicator last in DOM order, and it moves on its own when the page flips, with no extra rule. A position: absolute; right: 12px leaves it sitting on top of the Arabic text, so use inset-inline-end: 12px instead.
A chevron that rotates
never mirrorsA chevron that points down while collapsed and rotates 180° on open is completely direction-neutral; never mirror it. Any angle other than 180° needs more care. If the collapsed state is rotate(-90deg), scaleX(-1) on top of it reverses the sign of the angle, so the icon spins the other way and settles upside down. The second trap is that transform is a single non-accumulating property: a transform: rotate(180deg) rule for the open state wipes out a transform: scaleX(-1) rule completely, so either combine them in one declaration or use the standalone rotate and scale properties, which do compose.
A sideways indicator
mirrorsIf the indicator points sideways while collapsed it is a purely directional icon that must point left in Arabic, but how you flip it depends on how it is drawn. An SVG path is geometry, not text, so the direction property never touches it and you have to flip it explicitly with transform: scaleX(-1) under [dir="rtl"] or :dir(rtl). A literal › character, by contrast, is Bidi_Mirrored in Unicode, so the browser already draws it reversed inside an rtl paragraph and adding scaleX(-1) flips it back to the wrong side. An icon-font glyph lives in the Unicode Private Use Area, which carries no mirroring property at all, so it never flips on its own.
Indentation and padding
mirrorsA nested accordion indents child headers from the parent header by a fixed step. Use padding-inline-start on the header instead of padding-left, or the indent lands on the wrong edge: the children look perfectly flush with their parent and the gap shows up at the end of the line instead. The same rule covers panel padding (padding-inline, not padding-left/right) and the vertical guide line that signals nesting, where border-inline-start replaces border-left so the line stands beside the content instead of behind it.
The navigation keys
never mirrorsThe accordion axis is vertical, so its keyboard model does not mirror: ArrowDown and ArrowUp still move between headers and Home/End still jump to the first and last, whatever the page direction. ArrowLeft and ArrowRight do flip, if you support them: in horizontal orientation (orientation="horizontal") or in a tree-style pattern where one arrow opens the item and the other closes it. Because event.key reports the physical key and knows nothing about direction, read the direction yourself with getComputedStyle(el).direction or el.matches(":dir(rtl)") and swap the two handlers, or pass dir="rtl" to the Radix root and let it do the swap.
In code
Each row is one framework's word for the same thing. Take the row your project speaks.
See also
Updated · 2026-08-19