Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions wcag-checker/README.md
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)
* **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
Copy link

Copilot AI Dec 6, 2025

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 "Required for EyeDropper functionality" 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 (like a button click in the popup).

Suggested change
- `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.

Copilot uses AI. Check for mistakes.
- `scripting`: Required for extension popup interaction

---

# WCAG Contrast Checker - Extensão Chrome

> Uma extensão leve para Chrome que verifica a conformidade de contraste de cores WCAG, construída como parte do projeto [100LinesOfCode](https://github.com/josharsh/100LinesOfCode).

Esta extensão oferece uma forma interativa para desenvolvedores e designers verificarem taxas de contraste de cores e garantir que seus designs atendem aos padrões de acessibilidade WCAG - direto da barra de ferramentas do navegador.

## Funcionalidades

* **Três Métodos de Seleção de Cores:**
- 🎨 Seletores de cores interativos
- 💧 Ferramenta conta-gotas para pegar cores diretamente de qualquer página
- ⌨️ Entrada manual (formato HEX ou RGB)
* **Cálculo de Contraste em Tempo Real:** Veja instantaneamente a taxa de contraste entre suas cores
* **Verificação de Conformidade WCAG:** Validação automática contra padrões WCAG AA (4.5:1) e AAA (7:1)
* **Suporte a Múltiplos Formatos:** Obtenha e insira valores de cores em formatos HEX e RGB
* **Visualização ao Vivo:** Veja exatamente como seu texto ficará com a combinação de cores
* **Copiar para Área de Transferência:** Funcionalidade de cópia com um clique
* **Design Compacto:** Interface otimizada (400px de largura) perfeita para verificações rápidas
* **Design Acessível:** Construído pensando em acessibilidade

## Estrutura do Projeto

```
wcag-checker/
├── index.html # Estrutura HTML do popup principal
├── style.css # Estilos otimizados com organização limpa
├── script.js # Lógica JavaScript (menos de 100 linhas!)
├── manifest.json # Manifest da extensão Chrome v3
└── README.md # Documentação do projeto
```

## Instalação

### Opção 1: Instalar do Código Fonte (Modo Desenvolvedor)
1. Clone ou baixe este repositório
2. Abra o Chrome e navegue até `chrome://extensions/`
3. Ative o "Modo do desenvolvedor" (toggle no canto superior direito)
4. Clique em "Carregar sem compactação"
5. Selecione a pasta `wcag-checker`
6. O ícone da extensão aparecerá na sua barra de ferramentas!

### Opção 2: Testar Localmente (Sem Instalar)
```bash
# Navegue até a pasta do projeto
cd wcag-checker

# Inicie um servidor local
python -m http.server 8000
# ou
npx http-server
```

Em seguida, abra seu navegador e navegue até `http://localhost:8000`

## Como Usar

1. **Clique no ícone da extensão** na barra de ferramentas do Chrome
2. **Escolha suas cores** usando um dos três métodos:
- Clique nas caixas de seleção de cor
- Clique em "Pick from Page" para usar o conta-gotas em qualquer cor visível
- Digite diretamente nos campos HEX (`#FF5733`) ou RGB (`rgb(255, 87, 51)`)
3. **Veja os resultados instantâneos:**
- Taxa de contraste exibida de forma proeminente
- Status PASS/FAIL para padrões WCAG AA e AAA
- Pré-visualização ao vivo da aparência do texto
4. **Copie valores** com um clique para usar em seus projetos

## Padrões WCAG

- **WCAG AA (4.5:1):** Taxa de contraste mínima para texto normal, necessária para a maioria dos conteúdos web
- **WCAG AAA (7:1):** Taxa de contraste aprimorada para o mais alto nível de acessibilidade

## Stack Tecnológica

* **HTML5:** Estrutura semântica (145 linhas, otimizado)
* **CSS3:** Estilização moderna com layout Flexbox
* **JavaScript Vanilla:** Toda a lógica em menos de 100 linhas (96 linhas)
Copy link

Copilot AI Dec 6, 2025

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.

Suggested change
* **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 uses AI. Check for mistakes.
* **APIs de Extensão Chrome:** Manifest V3, EyeDropper API
* **Web APIs:** API Clipboard para funcionalidade de cópia

## Suporte de Navegadores

Requer:
- Chrome 95+ (para EyeDropper API)
- Suporte à API Clipboard
- Recursos JavaScript ES6+

## Permissões

- `activeTab`: Necessária para a funcionalidade do conta-gotas pegar cores da página atual
Copy link

Copilot AI Dec 6, 2025

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.

Suggested change
- `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 uses AI. Check for mistakes.
Copy link

Copilot AI Dec 8, 2025

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.

Suggested change
- `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

Copilot uses AI. Check for mistakes.
- `scripting`: Necessária para interação do popup da extensão
140 changes: 140 additions & 0 deletions wcag-checker/index.html
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" />
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing ARIA labels for the color picker inputs. Screen reader users won't get sufficient context when interacting with these color inputs. Consider adding aria-label attributes to the color input elements to describe their purpose (e.g., aria-label="Select text color").

Suggested change
<input type="color" id="text-color-input" value="#000000" />
<input type="color" id="text-color-input" value="#000000" aria-label="Select text color" />

Copilot uses AI. Check for mistakes.
</div>
<button id="text-eye-dropper-btn" class="dropper-btn-small">
<svg width="14" height="14" viewBox="0 0 24 24">
<path d="m2 22 1-1h3l9-9"></path>
<path d="M3 21v-3l9-9"></path>
<path d="m15 6 3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l-3-3Z"></path>
</svg>
Pick from Page
</button>
<div class="output-group">
<input type="text" id="text-hex-value" value="#000000" placeholder="#000000" />
<button class="copy-btn" data-target="text-hex-value">
<svg width="16" height="16" viewBox="0 0 24 24">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
Comment on lines +33 to +38
Copy link

Copilot AI Dec 8, 2025

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").

Copilot uses AI. Check for mistakes.
</div>
<div class="output-group">
<input type="text" id="text-rgb-value" value="rgb(0, 0, 0)" placeholder="rgb(0, 0, 0)" />
<button class="copy-btn" data-target="text-rgb-value">
<svg width="16" height="16" viewBox="0 0 24 24">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
</div>
<div class="selector-group">
<label for="bg-color-input">Background Color</label>
<div class="color-input-wrapper">
<input type="color" id="bg-color-input" value="#FFFFFF" />
</div>
<button id="bg-eye-dropper-btn" class="dropper-btn-small">
<svg width="14" height="14" viewBox="0 0 24 24">
<path d="m2 22 1-1h3l9-9"></path>
<path d="M3 21v-3l9-9"></path>
<path d="m15 6 3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l-3-3Z"></path>
</svg>
Pick from Page
</button>
<div class="output-group">
<input type="text" id="bg-hex-value" value="#FFFFFF" placeholder="#FFFFFF" />
<button class="copy-btn" data-target="bg-hex-value">
<svg width="16" height="16" viewBox="0 0 24 24">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
<div class="output-group">
<input type="text" id="bg-rgb-value" value="rgb(255, 255, 255)" placeholder="rgb(255, 255, 255)" />
<button class="copy-btn" data-target="bg-rgb-value">
<svg width="16" height="16" viewBox="0 0 24 24">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
</div>
</div>

<h2 class="section-divider">Preview</h2>
<div class="preview-container">
<div id="preview-box">
<p>This is how your text will look.</p>
<p><strong>This is bold text.</strong></p>
</div>
</div>
</div>
</div>

<div class="column-right">
<div class="card-section">
<h2>Contrast Score</h2>
<div class="results-container">
<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>
Comment on lines +98 to +104
Copy link

Copilot AI Dec 8, 2025

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.

Suggested change
<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 uses AI. Check for mistakes.
<label>WCAG AAA</label>
Comment on lines +100 to +105
Copy link

Copilot AI Dec 8, 2025

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.

Suggested change
<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>

Copilot uses AI. Check for mistakes.
</div>
</div>

<h2 class="section-divider info-title">
<svg width="20" height="20" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="16" x2="12" y2="12"></line>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
</svg>
About WCAG
</h2>
<div class="info-container">
<p>
This tool measures the contrast ratio based on the
<strong>WCAG (Web Content Accessibility Guidelines)</strong>, the global standard for ensuring web
content is accessible to people with visual impairments.
</p>
<ul>
<li>
<strong>Level AA (Passes at 4.5:1):</strong>
This is the accepted minimum standard for most web content.
</li>
<li>
<strong>Level AAA (Passes at 7:1):</strong>
This is the enhanced standard for the highest level of accessibility.
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
13 changes: 13 additions & 0 deletions wcag-checker/manifest.json
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
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The activeTab and scripting permissions are declared but not actually used by the extension. The extension only uses:

  1. EyeDropper API (which doesn't require special permissions in Manifest V3)
  2. Clipboard API (write access doesn't require permissions)

These permissions grant unnecessary access to user browsing data. Consider removing them unless there are plans to add features that genuinely require them.

Suggested change
"permissions": [
"activeTab",
"scripting"
]
// "permissions": [
// "activeTab",
// "scripting"
// ]

Copilot uses AI. Check for mistakes.
}
Loading
Loading