Skip to main content
The event_styles configuration lets you define a list of rules that change how individual events look on your calendar. Each rule specifies which events to target through a match object and how to style them through a style object. When multiple rules match the same event, conflicts are resolved per style property: the matching rule with the highest priority for that property wins. This makes it easy to build layered styling — for example, dimming all past events while still highlighting specific recurring ones at a higher priority.

Rule Structure

Each entry in event_styles is a rule with the following top-level keys:
  • match — describes which events the rule applies to. when is accepted as an alias.
  • style — describes how matching events should look
  • priority — optional integer (default 0) that controls which rule wins when multiple rules set the same style property
  • id — optional string identifier. Auto-generated (event-style-1, event-style-2, …) if omitted.
event_styles, day_styles, and day_badges all share the same advanced match schema. Anything you learn here applies to the other two rule types.
For one-off, per-device recoloring — for example, giving a single event a distinctive color on the family dashboard without changing the calendar — use the Custom Color action in the event detail modal instead of event_styles. Modal overrides win over the color / background_color set here, but do not affect other style properties.

Advanced match schema

The match object supports two scopes and the standard logical operators:
  • match.event — event-scoped conditions (title, calendar, all_day, etc.). For event_styles, fields written at the top level of match are implicitly treated as event conditions, so match: { title: 'standup' } and match: { event: { title: 'standup' } } are equivalent.
  • match.day — day-scoped conditions (today, weekend, has_event, …). See Day match fields for the full list. Useful when you want a rule to fire only on certain dates, e.g. weekdays.
  • match.any / match.all / match.and / match.not — combine nested match blocks with OR / AND / NOT logic.

Example: match a calendar only on weekdays

Event match fields

Use one or more of the following fields inside match (or match.event) to filter by event properties. By default, an event must satisfy all specified fields to be considered a match. For OR / NOT logic, use the logical operators below.
string
The entity ID of a specific Home Assistant calendar. Only events from that calendar entity will match. Aliases: calendar_entity, entity_id, entity.
string
A substring to look for in the event title. The match is case-insensitive. You can also pass a regex pattern wrapped in forward slashes, e.g. /standup/i. Alias: title_contains: foo is equivalent to title: 'contains:foo'.
string
Alias for match.title. Both names map to the event summary field. Use whichever feels more natural. Alias: summary_contains.
string
A substring to look for in the event description field. Alias: description_contains.
string
A substring to look for in the event location field. Alias: location_contains.
boolean
When true, only matches all-day events. When false, only matches timed events. Alias: all_day_event.
boolean
When true, only matches events whose end time is in the past. When false, only matches events that are not yet past.

Logical Operators

For compound rules, match accepts three logical operator keys. Each operator takes either a single sub-condition object or an array of sub-condition objects, and sub-conditions use the same match-field syntax as a top-level match block — including nested operators.
array
OR logic. The rule matches when at least one of the listed sub-conditions matches.
array
AND logic. The rule matches when all listed sub-conditions match. Same as combining fields at the top level, but useful when nesting inside any or not.
array
Alias for match.all.
object | array
NOT logic. The rule matches when the listed sub-condition (or none of the listed sub-conditions) matches.

Example: events on the work OR personal calendar

Example: all-day events that are NOT in the past

Style Fields

The style object accepts the following properties to control how matched events are rendered.
string
Alias for style.background_color. Hex color string (e.g. '#1565C0') applied to the event’s background or bar color.
string
Hex color string applied to the event’s background or bar color. Equivalent to style.color.
string
Hex color string applied to the event’s text. Use this to ensure readable contrast when you change the background color.
number
A number between 0 and 1 that controls the event’s transparency. Use 0.4 to visually mute events without hiding them entirely.
string
A CSS filter string applied to the event element. For example, grayscale(100%) removes all color from matching events.
string
An MDI icon name (e.g. mdi:repeat) to attach to matching events. Combine with icon_position to control placement.
string
default:"before_title"
Controls where the icon is rendered. Use before_title to place it inline before the event title, or corner to display it as a small overlay in the corner of the event chip.
string
Hex color string applied to the matched style icon. Defaults to the event’s text color.
string | number
Overrides the icon size. Accepts a number (interpreted as pixels) or any CSS length string such as '14px' or '1.1em'.
boolean
When true, matching events are completely removed from the calendar view. Hidden events are not counted toward day event totals.
boolean
When true, suppresses the time label on matching events even if times would otherwise be shown.
boolean
When true, forces the time label to render on matching events even if it would otherwise be hidden (for example, by hide_times_for_calendars).
boolean
When true, hides the small calendar-color dot on matching events. Useful when you’ve added a custom icon and don’t want the default indicator competing with it.
boolean
Per-rule override of the global show_event_location setting. Set to true to force locations on for matching events, or false to hide them on matching events only.
boolean
Per-rule override of the global use_short_location setting.
string | number
Per-rule override of the event title font size. Accepts a number (pixels) or CSS length string.
string | number
Per-rule override of the event time font size. Accepts a number (pixels) or CSS length string.
string | number
Per-rule override of the event location font size. Accepts a number (pixels) or CSS length string.
string
Per-rule override of the global event_title_prefix mode. Accepted values: none, badge_icon, friendly_name.

Priority

integer
default:"0"
When two or more rules match the same event, conflicts are resolved per style property. For each property, the rule with the highest priority wins. If priorities are equal, the rule defined earlier in the list wins. Properties that aren’t set by the winning rule fall through to the next matching rule, so styles from different rules can compose on the same event.
Use priority to layer general rules with specific overrides. For example, set a low-priority rule that dims all past events, then add a high-priority rule that keeps a specific calendar’s events fully visible regardless.

Examples

Color all events from a work calendar

This rule applies a deep blue background and white text to every event from calendar.work.

Hide events titled “Free”

This rule completely removes any event whose title contains the word “Free” from the calendar view.

Add a corner icon to a specific calendar’s events

This rule stamps a briefcase icon in the corner of every event from calendar.work. A priority of 5 ensures it takes precedence over lower-priority color rules.

Mute all-day events with opacity

This rule reduces the opacity of all-day events to 0.4, visually de-emphasizing them without hiding them.

Dim past events

This rule applies a grayscale filter and reduced opacity to any event that has already passed, giving the calendar a clear visual split between past and upcoming.

Combine multiple match conditions

You can narrow a rule by specifying more than one match field at the same time. This rule applies a grayscale filter only to past all-day events from a specific calendar.
All style values are sanitized before they are applied to the DOM. Attempting to inject HTML or JavaScript through a color, filter, or other style field will be stripped out automatically.