This PR introduces support for dark background colors on post labels.
Specifically, the following changes have been made:
Luminance & Color Contrast: Added isDark and contrastingTextColor getters in ColorViewModel. The color contrast detection has been improved to use the standard sRGB relative luminance formula (per WCAG 2.x standard) with a threshold of 0.179 to determine if a background is dark, ensuring much more accurate contrast adjustments than a simple YIQ calculation.
Text Color Adjustment: Sets the text color of the PostLabel dynamically to #ffffff if the background is dark, and inherits the default color if the background is light.
Indicator Dot Styling: Adjusts the background color of the small decorative dot inside PostLabel using a lighter variant (lighten(0.4)) on dark labels, and a darker variant (darken(0.2)) on light labels to ensure visual clarity.
### Description
This PR introduces support for dark background colors on post labels.
Specifically, the following changes have been made:
1. **Luminance & Color Contrast**: Added `isDark` and `contrastingTextColor` getters in `ColorViewModel`. The color contrast detection has been improved to use the standard sRGB relative luminance formula (per WCAG 2.x standard) with a threshold of `0.179` to determine if a background is dark, ensuring much more accurate contrast adjustments than a simple YIQ calculation.
2. **Text Color Adjustment**: Sets the text color of the `PostLabel` dynamically to `#ffffff` if the background is dark, and inherits the default color if the background is light.
3. **Indicator Dot Styling**: Adjusts the background color of the small decorative dot inside `PostLabel` using a lighter variant (`lighten(0.4)`) on dark labels, and a darker variant (`darken(0.2)`) on light labels to ensure visual clarity.
### Package Changes
_No response_
### Screenshots
_No response_
### Reference
Resolves #165
### Checklist
- [x] A milestone is set
- [x] The related issues has been linked to this branch
squid
changed title from BLOG-165 feat: adjust label text color based on background luminance for better contrast to BLOG-165 Adjust label text color based on background luminance for better contrast2026-05-23 00:01:20 +08:00
The YIQ formula is a decent approximation for perceived brightness, but for web accessibility, the W3C recommends a more accurate formula for relative luminance. Using the standard WCAG formula will ensure better contrast calculations across a wider range of colors and align with modern accessibility guidelines.
get isDark(): boolean {
- const yiq = (this.red * 299 + this.green * 587 + this.blue * 114) / 1000;
- return yiq < 128;
+ // Per WCAG 2.0, https://www.w3.org/TR/WCAG20-TECHS/G17.html
+ const sRGB = [this.red, this.green, this.blue].map((c) => {
+ const s = c / 255;
+ return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
+ });
+ const luminance = 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2];
+ // The threshold 0.179 is where contrast with white and black is equal.
+ return luminance < 0.179;
}
Suggestion importance[1-10]: 8
__
Why: This is an excellent suggestion. The YIQ formula is a good approximation, but the WCAG formula for relative luminance is the standard for web accessibility. Using it ensures more accurate contrast calculations and better adherence to modern accessibility guidelines.
Medium
Possible issue
Use specific color for better contrast
Using inherit for the text color on light backgrounds relies on the parent element having a dark text color. This assumption can fail in different contexts, such as a dark-themed page, leading to unreadable text with low contrast. To ensure the component is robust and accessible, it's better to return a specific dark color like #000000.
Why: The suggestion correctly points out that using inherit can lead to poor contrast if the parent element's color is not dark. Replacing it with a specific dark color like #000000 makes the component more robust and improves accessibility.
Medium
## PR Code Suggestions ✨
<!-- -->
<table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=1>General</td>
<td>
<details><summary>Use WCAG formula for luminance</summary>
___
**The YIQ formula is a decent approximation for perceived brightness, but for web <br>accessibility, the W3C recommends a more accurate formula for relative luminance. <br>Using the standard WCAG formula will ensure better contrast calculations across a <br>wider range of colors and align with modern accessibility guidelines.**
[frontend/src/lib/label/adapter/presenter/colorViewModel.ts [86-89]](https://git.squidspirit.com/squid/blog/src/branch/BLOG-165_support_dark_color_label_for_posts/frontend/src/lib/label/adapter/presenter/colorViewModel.ts#L86-L89)
```diff
get isDark(): boolean {
- const yiq = (this.red * 299 + this.green * 587 + this.blue * 114) / 1000;
- return yiq < 128;
+ // Per WCAG 2.0, https://www.w3.org/TR/WCAG20-TECHS/G17.html
+ const sRGB = [this.red, this.green, this.blue].map((c) => {
+ const s = c / 255;
+ return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
+ });
+ const luminance = 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2];
+ // The threshold 0.179 is where contrast with white and black is equal.
+ return luminance < 0.179;
}
```
<details><summary>Suggestion importance[1-10]: 8</summary>
__
Why: This is an excellent suggestion. The YIQ formula is a good approximation, but the WCAG formula for relative luminance is the standard for web accessibility. Using it ensures more accurate contrast calculations and better adherence to modern accessibility guidelines.
</details></details></td><td align=center>Medium
</td></tr><tr><td rowspan=1>Possible issue</td>
<td>
<details><summary>Use specific color for better contrast</summary>
___
**Using <code>inherit</code> for the text color on light backgrounds relies on the parent element <br>having a dark text color. This assumption can fail in different contexts, such as a <br>dark-themed page, leading to unreadable text with low contrast. To ensure the <br>component is robust and accessible, it's better to return a specific dark color like <br><code>#000000</code>.**
[frontend/src/lib/label/adapter/presenter/colorViewModel.ts [91-93]](https://git.squidspirit.com/squid/blog/src/branch/BLOG-165_support_dark_color_label_for_posts/frontend/src/lib/label/adapter/presenter/colorViewModel.ts#L91-L93)
```diff
get contrastingTextColor(): string {
- return this.isDark ? '#ffffff' : 'inherit';
+ return this.isDark ? '#ffffff' : '#000000';
}
```
<details><summary>Suggestion importance[1-10]: 7</summary>
__
Why: The suggestion correctly points out that using `inherit` can lead to poor contrast if the parent element's color is not dark. Replacing it with a specific dark color like `#000000` makes the component more robust and improves accessibility.
</details></details></td><td align=center>Medium
</td></tr></tr></tbody></table>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
This PR introduces support for dark background colors on post labels.
Specifically, the following changes have been made:
isDarkandcontrastingTextColorgetters inColorViewModel. The color contrast detection has been improved to use the standard sRGB relative luminance formula (per WCAG 2.x standard) with a threshold of0.179to determine if a background is dark, ensuring much more accurate contrast adjustments than a simple YIQ calculation.PostLabeldynamically to#ffffffif the background is dark, and inherits the default color if the background is light.PostLabelusing a lighter variant (lighten(0.4)) on dark labels, and a darker variant (darken(0.2)) on light labels to ensure visual clarity.Package Changes
No response
Screenshots
No response
Reference
Resolves #165
Checklist
BLOG-165 feat: adjust label text color based on background luminance for better contrastto BLOG-165 Adjust label text color based on background luminance for better contrast/improve
PR Code Suggestions ✨
Use WCAG formula for luminance
The YIQ formula is a decent approximation for perceived brightness, but for web
accessibility, the W3C recommends a more accurate formula for relative luminance.
Using the standard WCAG formula will ensure better contrast calculations across a
wider range of colors and align with modern accessibility guidelines.
frontend/src/lib/label/adapter/presenter/colorViewModel.ts [86-89]
Suggestion importance[1-10]: 8
__
Why: This is an excellent suggestion. The YIQ formula is a good approximation, but the WCAG formula for relative luminance is the standard for web accessibility. Using it ensures more accurate contrast calculations and better adherence to modern accessibility guidelines.
Use specific color for better contrast
Using
inheritfor the text color on light backgrounds relies on the parent elementhaving a dark text color. This assumption can fail in different contexts, such as a
dark-themed page, leading to unreadable text with low contrast. To ensure the
component is robust and accessible, it's better to return a specific dark color like
#000000.frontend/src/lib/label/adapter/presenter/colorViewModel.ts [91-93]
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly points out that using
inheritcan lead to poor contrast if the parent element's color is not dark. Replacing it with a specific dark color like#000000makes the component more robust and improves accessibility.9a3dddaebb