add guide body for contrast-color#966
Conversation
jamesnw
left a comment
There was a problem hiding this comment.
This is looking good! I have a few suggestions, and I think the demo will need to be updated to more closely match the guide.
I think we should also add notes that caution against using contrast-color() over gradients, images, or backgrounds with transparency.
|
|
||
| # Ensure text readability with dynamic background colors | ||
|
|
||
| When building reusable UI components (like badges or buttons) or supporting dynamic themes, ensuring text is readable against an unpredictable background color can be challenging. The `contrast-color()` CSS function automatically selects either black or white to maximize the contrast ratio against a specified background color. |
There was a problem hiding this comment.
| When building reusable UI components (like badges or buttons) or supporting dynamic themes, ensuring text is readable against an unpredictable background color can be challenging. The `contrast-color()` CSS function automatically selects either black or white to maximize the contrast ratio against a specified background color. | |
| When building reusable UI components (like badges or buttons) or supporting dynamic themes, ensuring text is readable against an unpredictable background color can be challenging. The `contrast-color()` CSS function resolves to `black` or `white`, maximizing the contrast ratio against the specified background color. |
|
|
||
| This guide explains how to use `contrast-color()` to guarantee text legibility. |
There was a problem hiding this comment.
| This guide explains how to use `contrast-color()` to guarantee text legibility. |
I don't think this is needed.
|
|
||
| When an element has a variable or dynamically injected background color, you can rely on the browser to compute the safest text color. | ||
|
|
||
| MANDATORY: You must define a fallback strategy for older browsers, such as using an `@supports` query with a `text-shadow` or variant-specific colors, because a single static fallback color will inevitably fail against some dynamic backgrounds. |
There was a problem hiding this comment.
I don't think we need to talk about fallbacks in the main section of the guide
|
|
||
| MANDATORY: You must define a fallback strategy for older browsers, such as using an `@supports` query with a `text-shadow` or variant-specific colors, because a single static fallback color will inevitably fail against some dynamic backgrounds. | ||
|
|
||
| MANDATORY: Set the `color` property using the `contrast-color()` function, passing the effective background color (or its custom property) as the argument. |
There was a problem hiding this comment.
I'm not sure what's meant by "effective" here- I think it can be removed?
| } | ||
| ``` | ||
|
|
||
| DO: Use `contrast-color()` primarily when backgrounds are distinctly light or dark. Because the function currently only selects between black or white, mid-tone backgrounds (such as royal blue) may result in suboptimal contrast even when the mathematical maximum is chosen. |
There was a problem hiding this comment.
Rather than mid-tone, would it make sense to say lightness specifically?
| @supports (color: contrast-color(red)) { | ||
| .button:hover { | ||
| /* Darken the background; the text color re-derives on its own */ | ||
| --button-bg: oklch(from #4f46e5 calc(l - 0.1) c h); |
There was a problem hiding this comment.
It might make sense to make this example actually flip the text from white to black- this should do it.
| --button-bg: oklch(from #4f46e5 calc(l - 0.1) c h); | |
| --button-bg: oklch(from #4f46e5 calc(1 - l) c h); |
|
|
||
| ## Fallback strategies | ||
|
|
||
| {{ FEATURE_FALLBACKS("contrast-color") }} |
There was a problem hiding this comment.
| {{ FEATURE_FALLBACKS("contrast-color") }} | |
| {{ BASELINE_STATUS("contrast-color") }} |
|
|
||
| {{ FEATURE_FALLBACKS("contrast-color") }} | ||
|
|
||
| Due to its limited availability, `contrast-color()` must be applied using progressive enhancement. If the background color is known and fixed for a specific CSS class (like a `.badge-dark` variant), declaring a variant-specific safe default `color` immediately before the `contrast-color()` rule is sufficient, because browsers ignore CSS values they do not understand. |
There was a problem hiding this comment.
I don't think the prose needs to talk about availability.
| Due to its limited availability, `contrast-color()` must be applied using progressive enhancement. If the background color is known and fixed for a specific CSS class (like a `.badge-dark` variant), declaring a variant-specific safe default `color` immediately before the `contrast-color()` rule is sufficient, because browsers ignore CSS values they do not understand. | |
| For browsers that do not yet support `contrast-color()`, use it as a progressive enhancement. If the background color is known and fixed for a specific CSS class (like a `.badge-dark` variant), declare a variant-specific safe default `color` immediately before the `contrast-color()` rule. |
|
|
||
| Due to its limited availability, `contrast-color()` must be applied using progressive enhancement. If the background color is known and fixed for a specific CSS class (like a `.badge-dark` variant), declaring a variant-specific safe default `color` immediately before the `contrast-color()` rule is sufficient, because browsers ignore CSS values they do not understand. | ||
|
|
||
| However, if the background color is highly dynamic and unpredictable (such as user-injected themes), a single static fallback will inevitably fail. In these cases, you MUST use an `@supports` feature query to apply a robust fallback strategy, such as a text shadow or translucent background, to guarantee readability. |
There was a problem hiding this comment.
We could also mention using a library like ColorJS to compute a contrast color in JavaScript.
Another option would be using RCS, but that isn't widely available yet. Perhaps we don't need to mention that. https://lea.verou.me/blog/2024/contrast-color/#using-rcs-to-automatically-compute-a-contrasting-text-color
Follow-up to #753, which merged
contrast-coloras a stub (step 1: frontmatter + demo.html). This adds the fullguide.mdbody.Restores the guidance written earlier and incorporates the use cases @jamesnw suggested in the #753 review:
contrast-color()re-derive the foreground (algorithmic hover states).contrast-color()result into relative color syntax, with an explicit accessibility caveat that the contrast guarantee no longer holds once the value is transformed.Use cases: optimal text color, custom-property theming, hover/interaction states, derived colors, plus fallback strategy.
Refs #687