Developing Accessible Vue Applications
Best practices for ensuring Vue applications are accessible to users with disabilities, adhering to WCAG guidelines.
0 likes
182 views
Rule Content
title: Developing Accessible Vue Applications
description: Best practices for ensuring Vue applications are accessible to users with disabilities, adhering to WCAG guidelines.
category: Vue Cursor Rules
rules:
- id: vue-accessibility-semantic-html
description: Ensure the use of semantic HTML elements to improve accessibility and assistive technology support.
severity: error
pattern: |
<div\s+.*?\brole\s*=\s*["'](button|link|heading|navigation|main|article|section|footer|header)["'].*?>
replacement: |
<\1>
message: "Replace <div> with the appropriate semantic HTML element: <button>, <a>, <h1>-<h6>, <nav>, <main>, <article>, <section>, <footer>, or <header>."
example: |
<div role="button" @click="handleClick">Click Me</div>
correction: |
<button @click="handleClick">Click Me</button>
- id: vue-accessibility-aria-attributes
description: Ensure appropriate use of ARIA attributes to enhance accessibility.
severity: warning
pattern: |
<(button|a|input|select|textarea)\s+.*?\baria-(label|describedby|hidden|role)\s*=\s*["'].*?["'].*?>
message: "Verify that ARIA attributes are used correctly and enhance accessibility without redundancy."
example: |
<button aria-label="Submit" @click="submitForm">Submit</button>
correction: |
<button @click="submitForm">Submit</button>
- id: vue-accessibility-keyboard-navigation
description: Ensure all interactive elements are keyboard accessible.
severity: error
pattern: |
<div\s+.*?\btabindex\s*=\s*["']0["'].*?>
replacement: |
<button>
message: "Replace <div> with a semantic <button> element to ensure keyboard accessibility."
example: |
<div tabindex="0" @click="toggleModal">Open Modal</div>
correction: |
<button @click="toggleModal">Open Modal</button>
- id: vue-accessibility-color-contrast
description: Ensure sufficient color contrast between text and background.
severity: warning
pattern: |
color:\s*#([0-9a-fA-F]{6}|[0-9a-fA-F]{3});
background-color:\s*#([0-9a-fA-F]{6}|[0-9a-fA-F]{3});
message: "Check that the color contrast ratio between text and background meets WCAG guidelines (minimum 4.5:1 for normal text)."
example: |
color: #666;
background-color: #fff;
correction: |
color: #000;
background-color: #fff;
- id: vue-accessibility-alt-text
description: Ensure all images have descriptive alt text.
severity: error
pattern: |
<img\s+.*?\bsrc\s*=\s*["'].*?["'].*?>
replacement: |
<img src="..." alt="...">
message: "Add a descriptive alt attribute to the <img> tag to improve accessibility."
example: |
<img src="logo.png">
correction: |
<img src="logo.png" alt="Company Logo">
- id: vue-accessibility-form-labels
description: Ensure all form inputs have associated labels.
severity: error
pattern: |
<input\s+.*?\btype\s*=\s*["'](text|email|password|number|tel|url)["'].*?>
replacement: |
<label for="...">...</label>
<input id="..." type="...">
message: "Add a <label> element associated with the <input> to improve accessibility."
example: |
<input type="text" id="username">
correction: |
<label for="username">Username</label>
<input type="text" id="username">
- id: vue-accessibility-focus-management
description: Ensure proper focus management for dynamic content.
severity: warning
pattern: |
this\.\$refs\.\w+\.focus\(\);
message: "Verify that focus is managed appropriately when dynamic content is displayed to assist keyboard and screen reader users."
example: |
this.$refs.modal.focus();
correction: |
this.$nextTick(() => {
this.$refs.modal.focus();
});
- id: vue-accessibility-skip-links
description: Provide skip links to allow users to bypass repetitive content.
severity: warning
pattern: |
<a\s+.*?\bhref\s*=\s*["']#main-content["'].*?>
message: "Ensure a skip link is present to allow users to bypass repetitive navigation and go directly to the main content."
example: |
<a href="#main-content" class="skip-link">Skip to main content</a>
correction: |
<a href="#main-content" class="skip-link">Skip to main content</a>
<style>
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
</style>
- id: vue-accessibility-live-regions
description: Use ARIA live regions to announce dynamic content updates.
severity: warning
pattern: |
<div\s+.*?\brole\s*=\s*["']alert["'].*?>
message: "Ensure that ARIA live regions are used appropriately to announce dynamic content updates to assistive technologies."
example: |
<div role="alert">{{ notification }}</div>
correction: |
<div role="alert" aria-live="assertive">{{ notification }}</div>
- id: vue-accessibility-media-captions
description: Provide captions for all media content.
severity: error
pattern: |
<video\s+.*?>
replacement: |
<video>
<track kind="captions" src="..." srclang="en" label="English">
</video>
message: "Add a <track> element with kind='captions' to provide captions for media content."
example: |
<video controls>
<source src="video.mp4" type="video/mp4">
</video>
correction: |
<video controls>
<source src="video.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English">
</video>