A normal accordion grows the page when it opens. Some careers platforms measure the activity once, when it loads, so the grown content spills over the Submit button underneath. Everything built here stays exactly the same height however much the student clicks.
Sections
Each one has a name and its own content.
Look
One colour for headings, borders and the open section.
Headings, selected section, borders
Each block gets its own name so two on the same page never
interfere. Tick this only to regenerate it — for instance if you pasted the
same code twice by mistake.
Preview
Paste this into your platform’s source or HTML view, the </> button in most editors. Pasted into the normal typing view it shows as text instead.
How this works
This is not the accordion failing to reflow. Browsers always push content down when a
section opens, and that part is reliable. What appears to happen in some careers platforms
is that the activity content sits in a container whose height is measured once when the
page loads, with the Submit button placed directly after it. The container is fixed at,
say, 900px, Submit sits at 900px, and the moment your content grows past that it spills
out and renders over the button.
That is inferred from how it renders rather than from digging through the platform, so
treat it as a working theory — but it predicts the behaviour accurately.
The rule that fixes it
Do not let your content change its own height after the page loads. If the total
height never changes, none of this can happen — and you can still have things expand,
collapse and swap over.
The trick behind the first two patterns is one line: hide panels with
visibility: hidden, never
display: none. display: none
takes the element out of the layout entirely, so the container shrinks and grows as you
click, which is exactly what causes the problem.
visibility: hidden keeps the element’s space reserved
and just makes it invisible. Every panel is stacked in a single CSS grid cell
(grid-area: 1/1) with all but one hidden that way, so the
container is permanently as tall as your longest panel whichever one is showing.
The third pattern takes a different route: genuine
<details> accordions inside a fixed-height box with
overflow-y: auto. They expand into the box’s own scroll
area instead of into the page. Open all of them at once and the box still does not budge.
No JavaScript anywhere
The first two are built from radio buttons and labels, so they are keyboard-navigable
for free — arrow keys move between sections — and screen readers announce them
sensibly. The third uses the browser’s own
<details> element. Nothing here needs a script, which is
what lets it survive the security filters that strip scripts out of most platforms.
Two things this does for you
Every block gets a unique name. Written by hand, these patterns use fixed ids,
so two on one page fight over the same radio group and clicking one changes the other.
Here the ids, the group name and every single CSS class carry a random per-block token,
so you can paste as many as you like into one activity. Generate each separately rather
than copying one block twice and editing the text.
Colours are checked for contrast. The selected section is white text on your
brand colour, and a lot of pleasant-looking greens and blues are too light to carry white
text. Whatever you pick is darkened just enough to clear 4.5:1, keeping the hue.
Worth knowing
The first two need a style block. There is no way to express
:checked as an inline style, and that is the mechanism the
whole thing runs on. Some platform vendors advise against style blocks in activities, so
factor in your own institution’s position.
The real risk with a style block is CSS escaping and affecting the rest of the
platform page. Every rule generated here is scoped under this block’s own unique
class so that cannot happen. If you write anything of your own, keep that discipline
— never write a bare button {} or
.card {} rule inside an activity.
If you want to avoid style blocks entirely, the scroll box is the pattern to
use — height and overflow are ordinary properties. An embedded iframe from your own
web server is the other route.
Keep the focus outlines. They are how keyboard users see where they are, and
they are easy to strip out by accident when restyling.
Your body text can contain HTML — paragraphs, lists, links, bold. The
section names are plain text and are escaped for you.