Copied to Clipboard
Best practices:
- Always document shortcuts
- Avoid overriding browser defaults
- Provide alternative UI access
Keyboard shortcuts should enhance usability — not replace accessibility.
🟢 ARIA Labels & Roles
ARIA (Accessible Rich Internet Applications) attributes help screen readers understand UI meaning when semantic HTML is not enough.
aria-label
Useful when visual text is not descriptive:
<button aria-label="Close modal" @click="close">
✕
</button>
Without aria-label, a screen reader might only read "button".
aria-hidden
Hide decorative elements from assistive technologies:
<span aria-hidden="true">🎉</span>
aria-live
For dynamic updates (like notifications):
<div aria-live="polite">
{{ message }}
</div>
This informs screen readers that content has changed.
Proper Roles
If you create custom components (dropdowns, tabs, modals), use appropriate roles:
<div role="dialog" aria-modal="true">
<h2>Settings</h2>
</div>
However, remember:
👉 Native HTML elements are always preferred over ARIA when possible.
🟢 Focus Management
Focus management is one of the most overlooked accessibility issues in Vue apps.
Especially when dealing with:
- Modals
- Route changes
- Dynamic content
- Dropdowns
Managing Focus in Modals
When opening a modal:
- Move focus into the modal
- Trap focus inside
- Return focus when closing
Example:
<script setup>
import { ref, nextTick } from 'vue'
const modalRef = ref(null)
function openModal() {
isOpen.value = true
nextTick(() => {
modalRef.value?.focus()
})
}
</script>
<template>
<div
v-if="isOpen"
ref="modalRef"
tabindex="-1"
role="dialog"
>
Modal content
</div>
</template>
Focus After Route Changes
In SPAs, screen readers do not automatically detect route changes.
You should move focus to the main heading after navigation.
Example:
<script setup>
import { useRoute } from 'vue-router'
import { watch, nextTick } from 'vue'
const route = useRoute()
watch(() => route.path, async () => {
await nextTick()
document.querySelector('h1')?.focus()
})
</script>
And ensure the heading is focusable:
<h1 tabindex="-1">
Page Title
</h1>
Avoid Focus Traps
Common mistakes:
- Removing elements without restoring focus
- Dynamically hiding focused elements
- Infinite focus loops
Always test:
- Tab navigation
- Shift + Tab navigation
- Screen reader behavior
🧪 Quick Accessibility Checklist for Vue
Before shipping your feature:
- ✅ Can I navigate everything using only keyboard?
- ✅ Are all buttons real
<button> elements?
- ✅ Do interactive icons have
aria-label?
- ✅ Does focus move correctly after modals and navigation?
- ✅ Are dynamic updates announced properly?
These small checks dramatically improve usability.
📖 Learn more
If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:
Vue School Link
It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉
🧪 Advance skills
A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.
Check out Certificates.dev by clicking this link or by clicking the image below:
Certificates.dev Link
Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!
✅ Summary
Accessibility in Vue does not require massive architectural changes — it requires intentional implementation.
Small improvements make your app:
- More inclusive
- More professional
- More compliant
- More usable for everyone
Take care!
And happy coding as always 🖥️