Color filters¶
Color filters let the card transform colors before they are rendered.
They are useful when you want to reuse an existing layout or palette, but adjust its visual appearance. For example, you can make a card grayscale, apply a monochrome look, reduce saturation, adjust opacity, or create a duotone effect.
Unlike browser CSS filters, color_filter does not apply a visual filter on top of the rendered card. Instead, the card resolves the actual color first and then transforms that color into a normal RGB or RGBA value before rendering.
This means color_filter works on real color values such as fill, stroke, color, stop-color, and flood-color.
Below some examples. The first two cards have a slightly different configuration, but you can see that the second card has a grayscale filter.
Card 55 displays the original pollen colors, but has a gray filter on the scale of the horseshoe. The scale has a color stop defined to show segments, but I wanted the scale in this case to become gray to make the filled segments stand-out.

1 2 3 4 5 6 7 8 9 | |
Card 54 has a grayscale and lightness filter active at the card level.

1 2 3 4 5 6 | |
The color filters do not alter external images and svgs
Card 53 is a different card, but also has a filter defined at the card level:
1 2 3 4 5 6 | |
And the last ones:
- On the left the original card
- On the right the same card but with a teal filter, except for the central arc background which keeps its own color

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Basic idea¶
A color filter is configured with color_filter.
1 2 | |
This turns supported colors fully grayscale.
You can also use smaller values:
1 2 | |
This mixes the original color with a grayscale version.
Supported color properties¶
Color filters are applied to concrete color properties used by the card.
Supported properties are:
| Property | Common use |
|---|---|
fill | SVG fills, text fills, icon fills, shape fills |
stroke | Lines, outlines, strokes |
color | General CSS color values |
stop-color | Gradient color stops |
flood-color | Filter or SVG flood colors where supported |
Color values such as none, currentColor, inherit, and url(...) are skipped because they are not concrete colors.
Where color filters can be used¶
color_filter follows the same general idea as styling: higher-level configuration can define a default, and lower-level configuration can override or extend it.
Color filters can be configured at several levels, depending on the item:
| Level | Purpose |
|---|---|
Root card color_filter | Applies a default filter to the card |
Group color_filter | Applies a filter to items placed in a group |
Item or tool color_filter | Applies a filter to one layout item or visual part |
Layer-specific color_filter | Applies a filter to a specific visual layer where supported |
State or color-stop specific color_filter | Applies a filter after a specific state or color stop has selected a color |
The final filter is built from the active levels in order. Lower-level settings can refine or override higher-level settings.
Inheritance¶
By default, color filters cascade from higher levels to lower levels.
For example, a card-level filter can affect all items unless a lower level overrides it.
1 2 3 4 5 6 7 8 | |
In this example, the state item inherits the card-level saturation filter.
To stop inheriting filters from higher levels, use inherit: false.
1 2 3 4 5 | |
After inherit: false, only filters defined at that level and below remain active.
Global filters and property-specific filters¶
A color filter can apply to all supported color properties:
1 2 | |
You can also target a specific property, such as only fill or only stroke.
1 2 3 4 5 6 | |
Global filter keys and property-specific filter keys are merged for each property. Property-specific settings win for that property.
For example:
1 2 3 4 5 | |
Here, most supported color properties use saturation: 0.5, but fill uses saturation: 1.
Processing order¶
The filter order is fixed by the card.
Users do not configure the order.
The card processes colors in this order:
source color
-> resolve CSS color or CSS variable to RGBA
-> grayscale
-> monochrome
-> duotone
-> lightness
-> brightness
-> contrast
-> saturation
-> opacity
-> RGB/RGBA for render
This means a color is first resolved to a real color. Then the configured filters are applied. Finally, the transformed RGB or RGBA color is rendered.
Supported filters¶
The following filters are currently supported:
| Filter | Purpose |
|---|---|
grayscale | Mixes a color toward grayscale or maps lightness to a grayscale range |
monochrome | Maps colors to one color family |
duotone | Maps colors between a dark and light endpoint color |
preserve_neutral | Keeps black, white, and neutral gray unchanged for monochrome and duotone |
lightness | Sets or maps OKLCH lightness |
brightness | Multiplies OKLCH lightness |
contrast | Moves RGB channels away from or toward middle gray |
saturation | Multiplies OKLCH chroma |
opacity | Multiplies the current alpha channel |
The following filters are not currently supported:
theme_monochrometheme_duotone- hue rotation
- tint
- invert
- sepia
- threshold
Grayscale¶
grayscale converts colors toward grayscale.
A value of 1 means full grayscale:
1 2 | |
A value between 0 and 1 mixes the original color with the grayscale result:
1 2 | |
You can also use a mapping object with min and max.
1 2 3 4 | |
This maps the source lightness into the configured range and returns a grayscale color.
Lightness¶
lightness changes OKLCH lightness.
A numeric value sets an absolute lightness:
1 2 | |
You can also map the current lightness into a range:
1 2 3 4 | |
This keeps relative differences between colors, but limits them to the configured lightness range.
Monochrome¶
monochrome maps colors to one color family while preserving source lightness.
The simplest form uses a color name or color value:
1 2 | |
The object form lets you control the amount.
1 2 3 4 | |
amount: 1 means full monochrome. Lower values mix the monochrome result with the original color.
Duotone¶
duotone maps colors between two endpoint colors.
The source lightness is used as the mix position between the dark and light colors.
1 2 3 4 | |
You can also add amount.
1 2 3 4 5 | |
amount: 1 means full duotone. Lower values mix the duotone result with the original color.
Preserve neutral colors¶
preserve_neutral keeps black, white, and neutral gray unchanged for monochrome and duotone.
1 2 3 4 5 | |
This is useful when you want to restyle a card, but keep text, dividers, and neutral backgrounds readable.
Brightness¶
brightness multiplies OKLCH lightness.
1 2 | |
Values above 1 make colors brighter. Values below 1 make colors darker.
Contrast¶
contrast moves RGB channels away from or toward middle gray.
1 2 | |
Values above 1 increase contrast. Values below 1 reduce contrast.
Saturation¶
saturation multiplies OKLCH chroma.
1 2 | |
Values below 1 reduce saturation. Values above 1 increase saturation.
Opacity¶
opacity multiplies the current alpha channel.
1 2 | |
This does not replace the original alpha value. It multiplies it.
For example, a color with 0.8 alpha and opacity: 0.5 renders with 0.4 alpha.
Color filters and color stops¶
Color filters are separate from color stops.
Color stops choose a color based on a value. Color filters can then transform the selected color before it is rendered.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
In this example, the color stop first chooses green, yellow, or red. After that, color_filter reduces the saturation of the selected color.
Theme-aware color stops and color filters¶
Theme-aware color stops are related, but separate from color_filter.
Color stops can define different values for Home Assistant light and dark mode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
The active color stop mode is selected from the current Home Assistant theme mode. After that, a color_filter can still transform the resulting color during render.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Here, the color is selected from the active theme mode first. Then the brightness filter is applied.
Recipes¶
Grayscale scale with colored state¶
Put the filter on the scale only:
1 2 3 4 5 | |
Do not put the same filter on horseshoe_state if the active state should keep the original color stop color.
Monochrome card with neutral text preserved¶
Use a card-level monochrome filter and preserve neutral colors:
1 2 3 4 5 | |
This gives the card a consistent color family while keeping neutral text and dividers readable.
Fill only¶
Use a property-specific filter when only one color property should be transformed.
1 2 3 4 5 6 | |
This applies the duotone filter only to fill.
Stroke only¶
1 2 3 | |
This reduces saturation only for strokes.
Disable inheritance for one group¶
1 2 3 4 5 | |
This prevents the group from inheriting color filters from higher levels.
Apply a filter to one layout item¶
1 2 3 4 5 6 7 8 | |
This affects only that state item.
Practical tips¶
Use card-level color_filter for broad visual changes, such as making a whole card monochrome or less saturated.
Use item-level color_filter when only one visual element should change.
Use property-specific filters when the fill and stroke should behave differently.
Use inherit: false when a group or item should not inherit a filter from the card or group above it.
Keep filters simple. A small number of well-placed filters is easier to understand than many filters spread across different levels.
Use color stops to choose colors based on values. Use color filters to transform the color after it has been chosen.
Troubleshooting¶
If a color does not change, check whether the value is a concrete color. Values such as none, currentColor, inherit, and url(...) are skipped.
If the result looks different than expected, remember that the processing order is fixed. For example, saturation is applied after brightness and contrast.
If too many elements are affected, check whether a card-level or group-level filter is being inherited.
If an item should ignore inherited filters, add:
1 2 | |
If no color_filter is configured, colors are not changed.