bump
This commit is contained in:
133
GRADIENT_CONTRAST_FIX.md
Normal file
133
GRADIENT_CONTRAST_FIX.md
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# Gradient Contrast Detection Fix
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
The contrast checking tool was reporting false positives for text on gradient backgrounds. Two specific issues were identified:
|
||||||
|
|
||||||
|
### Issue 1: White-on-White False Positives
|
||||||
|
**Example:** Vision Leadership sponsor page (https://visionleadership.org/sponsor-opportunities/)
|
||||||
|
- **Reported:** White text `rgb(255, 255, 255)` on white background `rgb(255, 255, 255)` = 1:1 ratio (FAIL)
|
||||||
|
- **Reality:** White text on gradient background `linear-gradient(rgb(12, 90, 201) 0%, rgb(0, 0, 0) 100%)`
|
||||||
|
- **Actual Contrast:** 6.32:1 to 21:1 (PASS)
|
||||||
|
|
||||||
|
**Root Cause:** The gradient was on a parent container (`.et_pb_section`), not directly on the text elements. The tool only checked the element itself for gradients, not parent elements.
|
||||||
|
|
||||||
|
### Issue 2: Gradient Applied to Wrong Elements
|
||||||
|
After the initial fix, the tool became too aggressive:
|
||||||
|
- **Reported:** 54 elements with blue background `rgb(12, 90, 201)` (from gradient)
|
||||||
|
- **Reality:** Those elements were on light gray `rgb(252, 252, 252)` background
|
||||||
|
- **Root Cause:** Gradient detection walked up the tree but didn't stop when it encountered solid backgrounds
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Modified the gradient detection logic in `daemon/daemon.go` to:
|
||||||
|
|
||||||
|
1. **Walk up the DOM tree** to find gradient backgrounds on parent elements
|
||||||
|
2. **Stop at solid backgrounds** - if a solid background color is found before a gradient, use the solid color
|
||||||
|
3. **Only apply gradients** when no solid background exists between the element and the gradient
|
||||||
|
|
||||||
|
### Code Changes
|
||||||
|
|
||||||
|
#### 1. Enhanced `analyzeGradientContrast` Function (Lines 9152-9220)
|
||||||
|
|
||||||
|
**Before:** Only checked the element itself for gradients
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
- Walks up the DOM tree looking for gradients
|
||||||
|
- Checks for solid backgrounds at each level
|
||||||
|
- Returns `null` if a solid background is found (gradient doesn't apply)
|
||||||
|
- Only returns gradient info if no solid background blocks it
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function analyzeGradientContrast(element, textColor) {
|
||||||
|
let current = element;
|
||||||
|
while (current && current !== document.documentElement.parentElement) {
|
||||||
|
const style = window.getComputedStyle(current);
|
||||||
|
|
||||||
|
// Check for solid background first - if found, gradient doesn't apply
|
||||||
|
const bgColor = style.backgroundColor;
|
||||||
|
if (!isTransparent(bgColor)) {
|
||||||
|
return null; // Solid background found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for gradient
|
||||||
|
const bgImage = style.backgroundImage;
|
||||||
|
if (bgImage && bgImage.includes('gradient')) {
|
||||||
|
// Extract and analyze gradient colors...
|
||||||
|
return gradientInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current.parentElement;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Updated Background Detection Logic (Lines 9305-9340)
|
||||||
|
|
||||||
|
**Before:** Always checked for gradients, even when solid backgrounds were found
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
- Tier 1: Check for solid backgrounds via DOM tree walking
|
||||||
|
- Tier 2: Check for solid backgrounds via stacking context
|
||||||
|
- Tier 3: Only check for gradients if no solid background found
|
||||||
|
- Fallback: Use white if nothing found
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Tier 1: DOM tree walking for solid colors
|
||||||
|
bgColor = getEffectiveBackgroundDOMTree(element);
|
||||||
|
|
||||||
|
// Tier 2: Stacking context analysis (if Tier 1 failed)
|
||||||
|
if (!bgColor) {
|
||||||
|
bgColor = getBackgroundFromStackingContext(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tier 3: Check for gradients (only if no solid color found)
|
||||||
|
if (!bgColor) {
|
||||||
|
gradientInfo = analyzeGradientContrast(element, fgColor);
|
||||||
|
if (gradientInfo) {
|
||||||
|
bgColor = gradientInfo.colors[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to white
|
||||||
|
if (!bgColor) {
|
||||||
|
bgColor = 'rgb(255, 255, 255)';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
After deploying the fix, test on:
|
||||||
|
|
||||||
|
1. **Vision Leadership sponsor page** - Should correctly detect gradient and report passing contrast
|
||||||
|
2. **Elements with solid backgrounds** - Should not incorrectly apply gradients from parent containers
|
||||||
|
3. **Nested backgrounds** - Should use the closest background (solid or gradient)
|
||||||
|
|
||||||
|
## Expected Results
|
||||||
|
|
||||||
|
### Vision Leadership Hero Section
|
||||||
|
- **H1 "Sponsorship Opportunities That Work For You"**
|
||||||
|
- Detection method: `gradient-analysis`
|
||||||
|
- Gradient colors: `rgb(12, 90, 201)` to `rgb(0, 0, 0)`
|
||||||
|
- Worst contrast: 6.32:1 (PASS AA for large text)
|
||||||
|
- Best contrast: 21:1 (PASS AAA)
|
||||||
|
|
||||||
|
### Elements with Solid Backgrounds
|
||||||
|
- **Text on light gray `rgb(252, 252, 252)`**
|
||||||
|
- Detection method: `dom-tree` or `stacking-context`
|
||||||
|
- Should NOT use gradient from parent
|
||||||
|
- Should calculate contrast against actual gray background
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
1. Build the daemon: `make daemon`
|
||||||
|
2. Build the MCP server: `make mcp`
|
||||||
|
3. Restart the cremote daemon (deployment-specific process)
|
||||||
|
4. Restart the MCP server or Augment extension to pick up changes
|
||||||
|
|
||||||
|
## Files Modified
|
||||||
|
|
||||||
|
- `daemon/daemon.go` - Lines 9152-9220 (gradient analysis function)
|
||||||
|
- `daemon/daemon.go` - Lines 9305-9340 (background detection logic)
|
||||||
|
|
||||||
@@ -9150,15 +9150,24 @@ func (d *Daemon) checkContrast(tabID string, selector string, timeout int) (*Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tier 3: Gradient analysis - walks up DOM tree to find gradient backgrounds
|
// Tier 3: Gradient analysis - walks up DOM tree to find gradient backgrounds
|
||||||
|
// Only returns gradient info if no solid background color is found first
|
||||||
function analyzeGradientContrast(element, textColor) {
|
function analyzeGradientContrast(element, textColor) {
|
||||||
try {
|
try {
|
||||||
// Walk up the DOM tree to find a gradient background
|
// Walk up the DOM tree to find a gradient background
|
||||||
|
// Stop if we encounter a solid background color first
|
||||||
let current = element;
|
let current = element;
|
||||||
while (current && current !== document.documentElement.parentElement) {
|
while (current && current !== document.documentElement.parentElement) {
|
||||||
const style = window.getComputedStyle(current);
|
const style = window.getComputedStyle(current);
|
||||||
const bgImage = style.backgroundImage;
|
|
||||||
|
// Check for solid background color first - if found, gradient doesn't apply
|
||||||
|
const bgColor = style.backgroundColor;
|
||||||
|
if (!isTransparent(bgColor)) {
|
||||||
|
// Solid background found - gradient doesn't apply to this element
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if background is a gradient
|
// Check if background is a gradient
|
||||||
|
const bgImage = style.backgroundImage;
|
||||||
if (bgImage && bgImage.includes('gradient')) {
|
if (bgImage && bgImage.includes('gradient')) {
|
||||||
// Extract gradient colors using regex
|
// Extract gradient colors using regex
|
||||||
const colorRegex = /rgba?\([^)]+\)|#[0-9a-f]{3,6}/gi;
|
const colorRegex = /rgba?\([^)]+\)|#[0-9a-f]{3,6}/gi;
|
||||||
@@ -9312,14 +9321,16 @@ func (d *Daemon) checkContrast(tabID string, selector string, timeout int) (*Con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tier 3: Check for gradient backgrounds (always check, even if solid color found)
|
// Tier 3: Check for gradient backgrounds (only if no solid color found)
|
||||||
// Gradients take precedence over solid colors when present
|
// Gradient analysis will return null if a solid background is found before the gradient
|
||||||
gradientInfo = analyzeGradientContrast(element, fgColor);
|
if (!bgColor) {
|
||||||
if (gradientInfo) {
|
gradientInfo = analyzeGradientContrast(element, fgColor);
|
||||||
detectionMethod = 'gradient-analysis';
|
if (gradientInfo) {
|
||||||
// Use a representative color from the gradient for the background_color field
|
detectionMethod = 'gradient-analysis';
|
||||||
// We'll use the worst-case color for reporting purposes
|
// Use a representative color from the gradient for the background_color field
|
||||||
bgColor = gradientInfo.colors[0] || bgColor;
|
// We'll use the first color for reporting purposes
|
||||||
|
bgColor = gradientInfo.colors[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final fallback to white if no background detected
|
// Final fallback to white if no background detected
|
||||||
|
|||||||
Reference in New Issue
Block a user