Skip to content

Commit

Permalink
Account for opacity
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesnw committed Dec 10, 2024
1 parent 036b217 commit d8b5bba
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
18 changes: 18 additions & 0 deletions src/lib/components/ratio/ColorIssues.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@
adjust the color to be in gamut.
</p>
</dd>
<dt>Background Color Alpha Values</dt>
<dd>
<p>
WCAG 2 contrast does not consider alpha values. Because we don't know
what is behind your background color, we can't estimate the contrast. If
the background color is not opaque, the contrast ratio is computed
without background or foreground opacity.
</p>
</dd>
<dt>Foreground Color Alpha Values</dt>
<dd>
<p>
WCAG 2 contrast does not consider alpha values, but we can approximate a
ratio by premultiplying a semi-transparent foreground color in the sRGB
space. In practice, the displayed foreground color may vary, depending
on the display and browser.
</p>
</dd>
</dl>
</details>

Expand Down
22 changes: 20 additions & 2 deletions src/lib/components/ratio/index.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
<script lang="ts">
import { contrast } from 'colorjs.io/fn';
import { contrast, mix } from 'colorjs.io/fn';
import ColorIssues from '$lib/components/ratio/ColorIssues.svelte';
import Result from '$lib/components/ratio/Result.svelte';
import ExternalLink from '$lib/components/util/ExternalLink.svelte';
import Icon from '$lib/components/util/Icon.svelte';
import { RATIOS } from '$lib/constants';
import { bg, fg } from '$lib/stores';
let ratio = $derived(contrast($bg, $fg, 'WCAG21'));
let fgPremultiplied = $derived.by(() => {
if ($fg.alpha === 1 || $bg.alpha !== 1) return $fg;
return mix($bg, $fg, $fg.alpha, {
space: 'srgb',
premultiplied: false,
});
});
let ratio = $derived(contrast($bg, fgPremultiplied, 'WCAG21'));
let displayRatio = $derived(Math.round((ratio + Number.EPSILON) * 100) / 100);
let pass = $derived(ratio >= RATIOS.AA.Normal);
let alphaWarning = $derived.by(() => {
if ($bg.alpha !== 1)
return 'Alpha is not considered when the background is not opaque.';
if ($fg.alpha !== 1) return 'This ratio is our best estimate.';
return null;
});
</script>

<aside data-layout="results">
Expand All @@ -20,6 +35,9 @@
<span class="sr-only">The contrast ratio is</span>
<span class="result-ratio-number">{displayRatio}:1</span>
</h3>
{#if alphaWarning}
<p><Icon name="warning" />{alphaWarning}</p>
{/if}

<p class="result-intro">
In WCAG 2, contrast is a measure of the difference in perceived brightness
Expand Down

0 comments on commit d8b5bba

Please sign in to comment.