Interactive portfolio sites: accessible 3D scenes, games, custom cursors and scroll effects
How to make an interactive designer or studio portfolio accessible: text versions of canvas and 3D scenes, projects reachable without the gimmick, game keys that don't trap the keyboard, focus outlines with custom cursors, pause and reduced motion, no scroll-jacking, AI prompt wording and a 5-minute check.
Designers, studios and freelancers are now building show-off portfolio sites with AI coding agents: 3D hero scenes, animated mascots, custom cursors, scroll-driven stories and even small playable games. They can look great. They are also where the basics quietly break: the canvas has no text, the game grabs the arrow keys, the custom cursor hides the focus outline and the "scroll experience" hijacks the page. A hiring manager or client who uses a keyboard, a screen reader, a magnifier or voice control may never reach your case studies or your contact form. Here's how to keep the creative parts and make sure everyone can still get the point.
1. Give the canvas, 3D scene or game a text version
A <canvas>, WebGL scene or Lottie animation is a picture to assistive technology. Give it a short accessible name, and put what matters (your name, what you do, the projects) in real HTML text next to it, not only inside the drawing. If the scene is purely decorative, hide it from screen readers. (WCAG 1.1.1)
<!-- decorative 3D background: hidden from screen readers --> <canvas id="hero-scene" aria-hidden="true"></canvas> <h1>Ada Example, product designer</h1> <p>I design banking and health apps. <a href="#work">See case studies</a>.</p> <!-- a meaningful game or demo: name it and describe it --> <canvas id="sword-game" role="img" aria-label="Mini game: a knight slashes falling project cards to open them"></canvas> <p><a href="#work">Skip the game and see the projects as a list</a></p> <!-- example name and wording, use your own -->
2. Make sure every project is reachable without the gimmick
If projects only open by playing the game, flying through a 3D room or dragging a carousel, many visitors can't reach them. Keep a plain, linked list of case studies (a heading and a link each) and a skip link past any intro or scene. (WCAG 2.1.1, WCAG 2.4.1, WCAG 2.5.1)
<a class="skip" href="#work">Skip to projects</a>
...
<section id="work" tabindex="-1">
<h2>Selected work</h2>
<ul>
<li><a href="/work/mobile-banking-app">Mobile banking app redesign</a></li>
<li><a href="/work/clinic-booking">Clinic booking flow</a></li>
</ul>
</section>
<!-- example projects, use your own -->
3. Don't trap the keyboard or steal single keys
Games often listen for arrow keys, the space bar or single letters (W, A, S, D) on the whole page. That stops keyboard users scrolling and can fire by accident for speech-input users. Only listen for game keys while the game itself has focus, let Escape or Tab leave it, and say how to exit. If you use single-character shortcuts elsewhere, give a way to turn them off or change them. (WCAG 2.1.2, WCAG 2.1.4)
<div id="game-wrap" tabindex="0" aria-describedby="game-help">
<canvas id="sword-game" role="img" aria-label="Mini game: slash the falling project cards"></canvas>
</div>
<p id="game-help">Click or press Enter to play. Arrow keys move, Space slashes, Escape or Tab leaves the game.</p>
<script>
const wrap = document.getElementById('game-wrap');
wrap.addEventListener('keydown', (e) => { // only while the game has focus
if (e.key === 'Escape') { wrap.blur(); return; }
if (['ArrowLeft','ArrowRight',' '].includes(e.key)) {
e.preventDefault(); // stop page scroll only inside the game
handleGameKey(e.key); // your game logic
}
});
</script>
<!-- example controls, use your own -->
4. Keep the focus outline when you replace the cursor
Custom cursors and "magnetic" buttons are fine for mouse users, but sites that use them often also remove the focus outline with outline: none. Keep a clear outline on links and buttons, and keep the native pointer for text fields and form controls. (WCAG 2.4.7) See focus outlines and skip links.
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
outline: 3px solid #1a56db;
outline-offset: 3px;
}
input, textarea, select { cursor: auto; } /* keep the real cursor in forms */
5. Let people pause motion and sound
An intro animation, looping 3D scene or particle background that runs for more than five seconds needs a pause button, and background music that plays for more than three seconds needs a way to stop it or turn it down. Nothing should flash more than three times a second. Respect the visitor's reduced-motion setting, so parallax and big scroll-triggered movement calm down for people who get motion sick. (WCAG 2.2.2, WCAG 1.4.2, WCAG 2.3.1, and the stricter AAA guideline 2.3.3)
<button type="button" id="motion-toggle" aria-pressed="false">Pause animation</button>
<style>
@media (prefers-reduced-motion: reduce) {
.parallax, .float, .scroll-reveal { animation: none; transform: none; transition: none; }
}
</style>
<script>
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduce) stopScene(); // your animation loop's stop function
document.getElementById('motion-toggle').addEventListener('click', (e) => {
const paused = e.currentTarget.getAttribute('aria-pressed') === 'true';
paused ? startScene() : stopScene();
e.currentTarget.setAttribute('aria-pressed', String(!paused));
e.currentTarget.textContent = paused ? 'Pause animation' : 'Play animation';
});
</script>
See animations, background video and motion for more.
6. Don't hijack scrolling
"Scroll-jacking" (where one scroll moves you a whole screen, or scrolling plays an animation instead of moving the page) breaks the order in which keyboard and screen reader users meet your content, and it fights zoom. Let the page scroll normally, keep the reading order in the HTML the same as the visual order, and check the site at 200% zoom on a phone-width window. (WCAG 2.4.3, WCAG 1.4.10)
7. Name your custom controls
Icon-only buttons (a sound toggle, "next project" arrows, a menu blob) need an accessible name and, if they toggle, their state. Use real <button> and <a> elements rather than clickable <div>s. (WCAG 4.1.2) See link text and buttons.
<button type="button" aria-pressed="false" aria-label="Background music"> <svg aria-hidden="true" focusable="false">...</svg> </button>
8. When an AI agent builds it
AI coding tools will happily produce a canvas game, a custom cursor and smooth-scroll libraries, but they rarely add the text version, the pause button or the keyboard exit unless asked. Add something like this to your prompt (example wording): "Keep all project content as real HTML text and links. Add a skip link past the hero. Hide decorative canvas from screen readers. Game keys only while the game has focus, Escape exits. Keep visible focus outlines. Add a pause button and honour prefers-reduced-motion. No scroll-jacking. Use real buttons with names." Then test it yourself, because the tool can't. See checking an AI-built website.
Platform notes
- Framer and Webflow: scroll effects and interactions are built in. Check that each one has a reduced-motion version, and that the page still reads in order with effects off. See Webflow fixes.
- Three.js, Spline, Lottie and other embeds: treat the embed as an image. Name it or hide it, and put the real content in HTML beside it. Check whether an embedded scene captures scrolling or keys.
- Squarespace, Wix and WordPress portfolio themes: watch for intro animations, full-screen loaders and gallery-only navigation. See photographer and portfolio websites.
Common mistakes
- Your name and job title only exist inside the 3D scene or an image.
- Projects open only by playing a game or dragging.
- Arrow keys and the space bar are captured on the whole page.
outline: noneto suit a custom cursor.- A long intro loader with no skip.
- Background music that starts by itself.
- Scroll-jacked sections that skip content for keyboard users.
A 5-minute check you can do today
- Open your portfolio and put the mouse away.
- Press Tab. Is the first stop a skip link or your main links, and can you always see where you are?
- Reach a case study and your contact form with the keyboard alone.
- If there's a game, tab into it, then press Escape or Tab. Do you get out?
- Turn on reduced motion in your device settings (macOS, Windows, iOS and Android all have it) and reload. Does the big movement calm down? Is there a pause button?
- Zoom to 200% on a phone-width window. Does the page still scroll normally?
What a scan can and can't check here
An automated scan finds only part of the barriers on the pages it visits. It can flag a canvas or image with no name, unnamed icon buttons, removed focus outlines in some cases and low contrast. It can't play your game, tell whether keys are trapped, judge whether motion is too much or follow a scroll-driven story, which is why the 5-minute check matters.
Related: photographer and portfolio websites, animation and motion, 5-minute keyboard test, client handoff checklist for web designers.
This is general technical guidance, not legal advice, and it doesn't certify compliance with the ADA or any law, or protect against claims.
Want the fixes written for you?
Start with a free homepage snapshot. The $149 Fix-Pack scans up to 10 pages and gives copy-paste fixes for your platform within 48 hours, with a 14-day refund promise. See a sample report first.
This is general technical guidance, not legal advice, and it does not certify compliance with the ADA or any law.
Related guides
- Website redesign or platform move: an accessibility checklist (WordPress to Astro, Webflow and more)
- GivingTuesday and year-end donation pages everyone can use: amounts, monthly gifts, progress bars and receipts
- Accessibility feature tags and filters for online stores: how to list them clearly and honestly
- Cognitive accessibility for small-business websites: easier for ADHD, autism, dyslexia and memory differences
This guide is general technical information, not legal advice. Following it does not certify ADA or any legal compliance. Automated checks find only part of accessibility barriers.
Check your own site, then decide
- Free homepage snapshot. Your top 3 issues in about a minute. No signup, no card.
- $149 Fix-Pack, if you want the full list. Up to 10 pages scanned, issues ranked by impact, copy-paste fixes for your platform, delivered within 48 hours, plus one re-scan after you apply them.
Get my free snapshot Order the Fix-Pack – $149
14-day refund promise. See a sample report first. A technical report, not legal advice; automated checks find only part of accessibility barriers.