-
Notifications
You must be signed in to change notification settings - Fork 332
Add WCAG Contrast Checker Utility #452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 9 commits
4d37753
256ca0b
ccf229d
0677c5b
827530a
51a68fb
36d8998
7395704
c18e6cb
ac9bbc0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,185 @@ | ||||||||||
| # WCAG Contrast Checker - Chrome Extension | ||||||||||
|
|
||||||||||
| > A lightweight Chrome extension for checking WCAG color contrast compliance, built as part of the [100LinesOfCode](https://github.com/josharsh/100LinesOfCode) project. | ||||||||||
|
|
||||||||||
| This browser extension provides an interactive way for developers and designers to check color contrast ratios and ensure their designs meet WCAG accessibility standards - right from their browser toolbar. | ||||||||||
|
|
||||||||||
| ## Features | ||||||||||
|
|
||||||||||
| * **Triple Color Selection Methods:** | ||||||||||
| - 🎨 Interactive color pickers | ||||||||||
| - 💧 EyeDropper tool to pick colors directly from any webpage | ||||||||||
| - ⌨️ Manual input (HEX or RGB format) | ||||||||||
| * **Real-time Contrast Calculation:** Instantly see the contrast ratio between your selected colors | ||||||||||
| * **WCAG Compliance Check:** Automatic validation against WCAG AA (4.5:1) and AAA (7:1) standards | ||||||||||
| * **Multiple Format Support:** Get and input color values in both HEX and RGB formats | ||||||||||
| * **Live Preview:** See exactly how your text will look with the selected color combination | ||||||||||
| * **Copy to Clipboard:** One-click copy functionality for all color values | ||||||||||
| * **Compact Design:** Optimized popup interface (400px width) perfect for quick checks | ||||||||||
| * **Accessible Design:** Built with accessibility in mind, following best practices | ||||||||||
|
|
||||||||||
| ## Project Structure | ||||||||||
|
|
||||||||||
| ``` | ||||||||||
| wcag-checker/ | ||||||||||
| ├── index.html # Main popup HTML structure | ||||||||||
| ├── style.css # Optimized styling with clean organization | ||||||||||
| ├── script.js # JavaScript logic (under 100 lines!) | ||||||||||
| ├── manifest.json # Chrome extension manifest v3 | ||||||||||
| └── README.md # Project documentation | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Installation | ||||||||||
|
|
||||||||||
| ### Option 1: Install from Source (Developer Mode) | ||||||||||
| 1. Clone or download this repository | ||||||||||
| 2. Open Chrome and navigate to `chrome://extensions/` | ||||||||||
| 3. Enable "Developer mode" (toggle in top-right corner) | ||||||||||
| 4. Click "Load unpacked" | ||||||||||
| 5. Select the `wcag-checker` folder | ||||||||||
| 6. The extension icon will appear in your toolbar! | ||||||||||
|
|
||||||||||
| ### Option 2: Test Locally (Without Installing) | ||||||||||
| ```bash | ||||||||||
| # Navigate to the project folder | ||||||||||
| cd wcag-checker | ||||||||||
|
|
||||||||||
| # Start a local server | ||||||||||
| python -m http.server 8000 | ||||||||||
| # or | ||||||||||
| npx http-server | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Then open your browser and navigate to `http://localhost:8000` | ||||||||||
|
|
||||||||||
| ## How to Use | ||||||||||
|
|
||||||||||
| 1. **Click the extension icon** in your Chrome toolbar | ||||||||||
| 2. **Choose your colors** using one of three methods: | ||||||||||
| - Click the color picker boxes | ||||||||||
| - Click "Pick from Page" to use the EyeDropper on any visible color | ||||||||||
| - Type directly in the HEX (`#FF5733`) or RGB (`rgb(255, 87, 51)`) fields | ||||||||||
| 3. **View instant results:** | ||||||||||
| - Contrast ratio displayed prominently | ||||||||||
| - PASS/FAIL status for WCAG AA and AAA standards | ||||||||||
| - Live preview of text appearance | ||||||||||
| 4. **Copy values** with one click for use in your projects | ||||||||||
|
|
||||||||||
| ## WCAG Standards | ||||||||||
|
|
||||||||||
| - **WCAG AA (4.5:1):** Minimum contrast ratio for normal text, required for most web content | ||||||||||
| - **WCAG AAA (7:1):** Enhanced contrast ratio for the highest level of accessibility | ||||||||||
|
|
||||||||||
| ## Tech Stack | ||||||||||
|
|
||||||||||
| * **HTML5:** Semantic structure (145 lines, optimized) | ||||||||||
| * **CSS3:** Modern styling with Flexbox layout | ||||||||||
| * **Vanilla JavaScript:** All logic in under 100 lines (96 lines) | ||||||||||
joaogsribeiro marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| * **Chrome Extension APIs:** Manifest V3, EyeDropper API | ||||||||||
| * **Web APIs:** Clipboard API for copy functionality | ||||||||||
|
|
||||||||||
| ## Browser Support | ||||||||||
|
|
||||||||||
| Requires: | ||||||||||
| - Chrome 95+ (for EyeDropper API) | ||||||||||
| - Clipboard API support | ||||||||||
| - ES6+ JavaScript features | ||||||||||
|
|
||||||||||
| ## Permissions | ||||||||||
|
|
||||||||||
| - `activeTab`: Required for EyeDropper functionality to pick colors from the current page | ||||||||||
|
||||||||||
| - `activeTab`: Required for EyeDropper functionality to pick colors from the current page | |
| - `activeTab`: (Optional) May be required for other extension features, but **not** required for EyeDropper functionality in Chrome. The EyeDropper API works without special permissions when called from a user gesture in the popup. |
joaogsribeiro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The README claims the script is "96 lines" but the actual script.js file is 97 lines. Update line counts to be accurate.
| * **JavaScript Vanilla:** Toda a lógica em menos de 100 linhas (96 linhas) | |
| * **JavaScript Vanilla:** Toda a lógica em menos de 100 linhas (97 linhas) |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misleading documentation. The README states that activeTab is "Necessária para a funcionalidade do conta-gotas pegar cores da página atual" (Required for the eyedropper functionality to pick colors from the current page) but the EyeDropper API doesn't require the activeTab permission in Chrome. The EyeDropper API works without any special permissions when called from a user gesture.
| - `activeTab`: Necessária para a funcionalidade do conta-gotas pegar cores da página atual | |
| - `activeTab`: Necessária para permitir que a extensão interaja com a aba atual (por exemplo, para executar scripts ou acessar o conteúdo da página) |
Copilot
AI
Dec 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Portuguese translation also incorrectly states that activeTab is necessary for the eyedropper functionality ("Necessária para a funcionalidade do conta-gotas pegar cores da página atual"). This is the same inaccuracy as in the English section - the EyeDropper API doesn't require this permission.
| - `activeTab`: Necessária para a funcionalidade do conta-gotas pegar cores da página atual | |
| - `activeTab`: Permite que a extensão acesse a aba ativa quando necessário |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,140 @@ | ||||||||||||||||||||||||||||||
| <!DOCTYPE html> | ||||||||||||||||||||||||||||||
| <html lang="en"> | ||||||||||||||||||||||||||||||
| <head> | ||||||||||||||||||||||||||||||
| <meta charset="UTF-8" /> | ||||||||||||||||||||||||||||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||||||||||||||||||||||||||||
| <title>WCAG Contrast Checker</title> | ||||||||||||||||||||||||||||||
| <link rel="stylesheet" href="style.css" /> | ||||||||||||||||||||||||||||||
| </head> | ||||||||||||||||||||||||||||||
| <body> | ||||||||||||||||||||||||||||||
| <div class="picker-container"> | ||||||||||||||||||||||||||||||
| <h1>WCAG Contrast Checker</h1> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <div class="main-content-wrapper"> | ||||||||||||||||||||||||||||||
| <div class="column-left"> | ||||||||||||||||||||||||||||||
| <div class="card-section"> | ||||||||||||||||||||||||||||||
| <h2>Choose Colors</h2> | ||||||||||||||||||||||||||||||
| <div class="color-selectors"> | ||||||||||||||||||||||||||||||
| <div class="selector-group"> | ||||||||||||||||||||||||||||||
| <label for="text-color-input">Text Color</label> | ||||||||||||||||||||||||||||||
| <div class="color-input-wrapper"> | ||||||||||||||||||||||||||||||
| <input type="color" id="text-color-input" value="#000000" /> | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| <input type="color" id="text-color-input" value="#000000" /> | |
| <input type="color" id="text-color-input" value="#000000" aria-label="Select text color" /> |
Copilot
AI
Dec 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copy buttons lack accessible labels. Screen reader users won't know what each copy button is copying. Add aria-label attributes to these buttons to describe what they copy (e.g., aria-label="Copy text hex value").
joaogsribeiro marked this conversation as resolved.
Show resolved
Hide resolved
joaogsribeiro marked this conversation as resolved.
Show resolved
Hide resolved
Copilot
AI
Dec 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initial page load doesn't call handleColorChange(), so the contrast ratio and WCAG status are hardcoded in the HTML (line 98 shows "21.00 : 1" and lines 100, 104 show "PASS"). If JavaScript fails to load or execute, users will see incorrect information. Consider either calling handleColorChange() on page load or setting more neutral initial values in the HTML.
| <div id="contrast-ratio-value">21.00 : 1</div> | |
| <div class="status-group"> | |
| <span id="wcag-aa-status">PASS</span> | |
| <label>WCAG AA</label> | |
| </div> | |
| <div class="status-group"> | |
| <span id="wcag-aaa-status">PASS</span> | |
| <div id="contrast-ratio-value">--</div> | |
| <div class="status-group"> | |
| <span id="wcag-aa-status">Unknown</span> | |
| <label>WCAG AA</label> | |
| </div> | |
| <div class="status-group"> | |
| <span id="wcag-aaa-status">Unknown</span> |
Copilot
AI
Dec 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The status labels and values are positioned in reverse reading order. Currently showing status value first, then label. Consider swapping the order in the HTML or using flexbox flex-direction: row-reverse to maintain the current visual layout while improving the DOM order for screen readers.
| <span id="wcag-aa-status">PASS</span> | |
| <label>WCAG AA</label> | |
| </div> | |
| <div class="status-group"> | |
| <span id="wcag-aaa-status">PASS</span> | |
| <label>WCAG AAA</label> | |
| <label>WCAG AA</label> | |
| <span id="wcag-aa-status">PASS</span> | |
| </div> | |
| <div class="status-group"> | |
| <label>WCAG AAA</label> | |
| <span id="wcag-aaa-status">PASS</span> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||||||
| { | ||||||||||||||||||
| "manifest_version": 3, | ||||||||||||||||||
| "name": "WCAG Contrast Checker", | ||||||||||||||||||
| "version": "1.0", | ||||||||||||||||||
| "description": "Check color contrast and accessibility (WCAG) compliance for any website.", | ||||||||||||||||||
| "action": { | ||||||||||||||||||
| "default_popup": "index.html" | ||||||||||||||||||
| }, | ||||||||||||||||||
| "permissions": [ | ||||||||||||||||||
| "activeTab", | ||||||||||||||||||
| "scripting" | ||||||||||||||||||
| ] | ||||||||||||||||||
|
Comment on lines
+9
to
+12
|
||||||||||||||||||
| "permissions": [ | |
| "activeTab", | |
| "scripting" | |
| ] | |
| // "permissions": [ | |
| // "activeTab", | |
| // "scripting" | |
| // ] |
Uh oh!
There was an error while loading. Please reload this page.