Skip to content

Commit

Permalink
Adjust ratio for opacity
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesnw committed Dec 10, 2024
1 parent 2fbf5f0 commit 9c239d7
Show file tree
Hide file tree
Showing 2 changed files with 37 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
21 changes: 19 additions & 2 deletions src/lib/components/ratio/index.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
<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 +34,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 9c239d7

Please sign in to comment.