BLOG-165 Adjust label text color based on background luminance for better contrast (#298)
All checks were successful
Frontend CI / build (push) Successful in 1m39s
All checks were successful
Frontend CI / build (push) Successful in 1m39s
### 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 Reviewed-on: #298 Co-authored-by: SquidSpirit <squid@squidspirit.com> Co-committed-by: SquidSpirit <squid@squidspirit.com>
This commit was merged in pull request #298.
This commit is contained in:
@@ -83,6 +83,24 @@ export class ColorViewModel {
|
||||
return hexString.slice(0, 7);
|
||||
}
|
||||
|
||||
get isDark(): boolean {
|
||||
const normalize = (val: number) => {
|
||||
const c = val / 255;
|
||||
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
||||
};
|
||||
|
||||
const r = normalize(this.red);
|
||||
const g = normalize(this.green);
|
||||
const b = normalize(this.blue);
|
||||
|
||||
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
return luminance < 0.179;
|
||||
}
|
||||
|
||||
get contrastingTextColor(): string {
|
||||
return this.isDark ? '#ffffff' : 'inherit';
|
||||
}
|
||||
|
||||
private toHsl(): Hsl {
|
||||
const r = this.red / 255;
|
||||
const g = this.green / 255;
|
||||
|
||||
@@ -6,8 +6,13 @@
|
||||
|
||||
<div
|
||||
class="flex h-fit w-fit flex-row flex-nowrap items-center gap-x-1 rounded-full px-2 py-0.5"
|
||||
style="background-color: {label.color.hex};"
|
||||
style="background-color: {label.color.hex}; color: {label.color.contrastingTextColor};"
|
||||
>
|
||||
<div class="size-2 rounded-full" style="background-color: {label.color.darken(0.2).hex};"></div>
|
||||
<div
|
||||
class="size-2 rounded-full"
|
||||
style="background-color: {label.color.isDark
|
||||
? label.color.lighten(0.4).hex
|
||||
: label.color.darken(0.2).hex};"
|
||||
></div>
|
||||
<span class="text-xs text-nowrap">{label.name}</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user