How to overrule a global theme for a specific card

I have created my personal theme with card-background-color set to color Mirage and so on.
This theme I have assigned to my preferences and it’s working fine.

Now I would like to overrule this global theme for only 1 card.
This overruling changes something, but not in the right direction.

Here is my setup.

configuration.yaml

frontend:
  themes: !include_dir_merge_named themes/

The themes folder has 2 files, one for my personal theme which is working fine on global level,
a 2nd one playground_themes.yaml with some playground themes in it, all for local assignement on card level.

Here the content of playground_themes.yaml

black_background_theme:
  modes:
    dark:
      card-background-color: black;
      primary-text-color: yellow;
    light:
      card-background-color: yellow;
      primary-text-color: blue;

no_background_theme:
  modes:
    dark:
      primary-text-color: yellow;
    light:
      primary-text-color: blue;

And here the card where I’m testing this theme:

type: entities
title: Playground Theme
entities:
  - sun.sun
  - sensor.moon_phase
theme: black_background_theme

The strange thing is, when I set the card theme to no_background_theme the background color is set to the default grey of HA.
And when I set the card theme to black_background_theme the background color is set to Mirage, which is the color from my global theme.

This means,
every card specific theme where I try to set the card-background-color will leave this color as it is defined by my global theme,
every card specific theme where I do not set the card-background-color will leave this color as it is defined by HA default,
but no card specific theme makes the expected change.

My question now, is it possible to overrule a global theme from user preference for any single card?
If yes, what could be my error.

I think it only works for some cards. Button cards allow you to set a theme.

The problem seems to be somewhere else.

I have now tested with Button card and the issue is exactly the same here.

type: button
entity: sun.sun
theme: no_background_theme
type: button
entity: sun.sun
theme: black_background_theme

Both cards are able to assign a theme, but my themes are not doing what I expect.

My themes look a bit different…

#################################################################
#                                                               #
#                    TRANSPARENT BUTTON                         #
#                                                               #
#################################################################

transparent_button:

  # The same as default theme except that card background and border are 
  # the same as primary background.
  
  # For use only on nlight themed dashboards.

  # Text Colors
  primary-text-color: "#212121"
  secondary-text-color: "#727272"
  text-primary-color: "#ffffff"
  text-light-primary-color: "#212121"
  disabled-text-color: "#bdbdbd"

  # Main Interface Colors
  primary-color: "#03a9f4"
  dark-primary-color: "#0288d1"
  light-primary-color: "#b3e5fC"
  accent-color: "#ff9800"
  divider-color: "rgba(0, 0, 0, .12)"
  scrollbar-thumb-color: "rgb(194, 194, 194)"
  error-color: "#db4437"
  warning-color: "#FF9800"
  success-color: "#0f9d58"
  info-color: "#4285f4"

  #States and Badges
  state-icon-color: "#44739e"
  state-icon-active-color: "#FDD835"

  #Background and Sidebar
  primary-background-color: "#fafafa"
  secondary-background-color: "#e5e5e5" #behind the cards on state

...and so on

Thanks a lot for your example, now I found my bug, the semicolon was wrong.

I have now managed to overrule a global theme by a card specific theme,
and the line “primary-text-color: yellow” is also working,
but none of the card-mod-card-yaml line are working.

Here the theme.yaml

playground_theme:
  card-mod-card-yaml: |
    .: |
      :host(.class_playground) ha-card {
        background-color: blue !important;
      }
  primary-text-color: yellow

And here the code for the card:

type: entities
title: Playground Theme
entities:
  - sun.sun
  - sensor.moon_phase
theme: playground_theme
card_mod:
  class: class_playground
  style: |
    ha-card {
      border: solid 3px red;
    }

Many things are working now, like:
“primary-text-color: yellow” from the playground_theme
“border: solid 3px red” from the card_mod

But class_playground is not working.
Is there still any bug in my code?

Did you follow the part of the card_mod guide on setting a card-mod-theme variable?

It’s not in the code snippet you’ve shared at least.

Thanks a lot, exactly this was my bug.

I played with so many playground_themes now, and the other ones had it, just this one was missing it.

playground_theme:
  card-mod-theme: playground_theme

Now I can start investigating, what all I can do with this great card_mod themes.

Thanks to all of you who helped me, doing this first step.

1 Like

It seems to me, that the card_mod class is overruling all other settings.

card_mod class has higher prio than card_mod style => OK

But why is primary-text-color from the theme no longer working?
This color should stay yellow because no class setting is overruling it.

Is there a way to combine theme settings with card-mod class settings?

My goal is to have all color settings in the theme and some border settings in a card_mod class.

Which you can (usually) reverse by adding
!important to your specific CSS style.

It should be, and does in my experience, although I’ve not tried what you are doing specifically by setting the theme at card level.

If you can reproduce this consistently - with all the usual caveats: clear browser cache; reload HA themes in Developer Tools > Actions - then it could be a bug, and worth reporting in the card_mod GitHub.

I have done both, clear browser cache, frontend.reload_themes
also added important, but all of them is not working.

My theme is having text-color green, which is not being set

playground_theme:
  primary-text-color: green
  card-mod-theme: playground_theme
  card-mod-card-yaml: |
    .: |
      :host(.class_playground) ha-card {
        background-color: blue;
        border: solid 3px red;
      }

My card is setting the border to green, which is also not being applied.

type: entities
title: Playground Theme
entities:
  - sun.sun
  - sensor.moon_phase
theme: playground_theme
card_mod:
  class: class_playground
  style: |
    ha-card {
      border: solid 3px green;
    }

When I’m removing the line card-mod-theme, the green text is being shown.
When I’m removing the line “class: class_playground”, the green border is being shown.

I also changed card-mod-card-yaml to card-mod-card, but then this part did no longer work.

Update: Setting card-mod-card-yaml to card-mod-card and back to card-mod-card-yaml made the green text color working now. Maybe it was a caching problem.

I have now managed to apply a card-mod theme to many cards, but not to custom:layout-card.

It seems that for this card I have to modify something in the DOM string.

Here is the theme.yaml where an orange box-shadow should be applied.

orange_theme:
  card-mod-theme: orange_theme
  card-mod-card-yaml: |
    .: |
      :host(.class_orange) ha-card {
      box-shadow: 0 0 5px 1px orange;
      }
  card-background-color: "#161925"
  primary-text-color: orange

And here is the card.

type: custom:layout-card
layout_type: custom:vertical-layout
layout: {}
cards:
  - type: entities
    title: custom:layout-card
    entities:
      - sun.sun
    theme: orange_theme
    card_mod:
      class: class_orange
  - type: entities
    entities:
      - sensor.moon_phase
    card_mod:
      style: |
        ha-card {
          box-shadow: 0 0 5px 1px orange;
        }

In the upper part, the card-background-color and primary-text-color from the theme is applied, but not the orange box-shadow via class_orange.

In the lower part the box shadow is created via card_mod directly.

My question is, what do I need to change in the following line: :host(.class_orange) ha-card
to make my card-mod theme also work for custom:layout-card, because for all other cards it’s working.

custom:layout-card fits the application note as per streamlined card. For this situation use dual selector approach.

Dual CSS selectors

:host(.my-class) ha-card selector for cards loaded by Frontend. ha-card.myclass for custom cards using a divergent structure, or for cards loaded by custom cards.

 card_mod:
   style: |
     :host(.my-class) ha-card,
     ha-card.myclass {
       background-color: red !important;
     }

Thanks a lot for your premium support, now it’s also working for (most of) my special cases with layout-card, which I like because of the grid feature.

:host(.class_shadow_inset) ha-card, ha-card.class_shadow_inset

I do not want to bother you too much, but I have still one case I can’t solve without expert support. It’s a combination of layout-card & decluttering-card with auto-entities.

I have reduced my complex code to a dummy code, which makes no sense any more but reproduces the problem easier.

Here the code for my dummy card.

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  grid-template-columns: 47% 53%
  grid-template-rows: auto
  grid-template-areas: "'a1 a2'"
cards:
  - type: custom:auto-entities
    view_layout:
      grid-area: a1
    card:
      type: entities
    filter:
      include:
        - entity_id: 'sensor.*'
          options:
            type: custom:template-entity-row
    sort:
      method: state
      count: 5
    card_mod:
      class: class_orange
  - type: custom:decluttering-card
    view_layout:
      grid-area: a2
    template: dummy_card
    card_mod:
      class: class_orange
card_mod:
  class: class_orange

As you can see, I have placed the card_mod class on many different places but nothing worked. I have many such combinations of layout-card & decluttering-card, none of them are working with card-mod, but the problem is also reproducable without decluttering-card as shown in first part.

And here the code for the dummy decluttering template, also with card_mod on different places.

decluttering_templates:
  dummy_card:
    default:
      - ENTITY_ID: sensor.*
      - COUNT: 5
    card:
      type: custom:auto-entities
      card:
        type: entities
      filter:
        include:
          - entity_id: '[[ENTITY_ID]]'
            options:
              type: custom:template-entity-row
              card_mod:
                class: class_orange
      sort:
        method: state
        count: '[[COUNT]]'
      card_mod:
        class: class_orange

I’m still in the learning phase but struggling with CSS and did not find my way how to generate a working card-mod code based on a given DOM structure.

Thanks for the test case. For completeness I will work through each level of applying card_mod so you can choose and others can take away any learnings.

Here, the layout-card will get the class. However there is then DOM elements between the layout-card and the cards included in the layout.

A possible solution is below, though is dependent on structure and would be used as a last resort. Templates always get config so this is where you can check the class as since this is using yaml selector you can’t use :host(.class_orange) like you can with CSS selector. The examople code assumes one class as string, and would need to be updated if list was to be used.

Tip: If you need to easily see what variables are available for a template, in the style string use {# card_mod.debug #} and an empty template {{ "" }} to force template rendering

  card-mod-card-yaml: |
    "grid-layout $ hui-entities-card $ ha-card": |
      {% set card_mod_config = config.card_mod if 'card_mod' in config else {} %}
      {% if card_mod_config.class == 'class_orange' %}
      ha-card {
        box-shadow: 0 0 5px 1px orange;
      }
      {% endif %}

Here you need to move card_mod to the card being rendered by auto_entities. Then ha_card.class_orange {} CSS selector will work.

- type: custom:auto-entities
    view_layout:
      grid-area: a1
    card:
      type: entities
      card_mod: # <- add card_mod here to target the card auto-entities will render
        class: class_orange
    filter:
      include:
        - entity_id: 'sensor.*'
          options:
            type: custom:template-entity-row
    sort:
      method: state
      count: 5
    # card_mod:
    #   class: class_orange

When decluttering-card is used, both the above need to be considered in the context depending on card used. Specifically for your template: dummy_card you need to move card_mod from auto-entities root config to the card being rendered.

decluttering_templates:
  dummy_card:
    default:
      - ENTITY_ID: sensor.*
      - COUNT: 5
    card:
      type: custom:auto-entities
      card:
        type: entities
        card_mod: # <- add card_mod here
          class: class_orange
      filter:
        include:
          - entity_id: '[[ENTITY_ID]]'
            options:
              type: custom:template-entity-row
              card_mod:
                class: class_orange
      sort:
        method: state
        count: '[[COUNT]]'
      # card_mod:
      #   class: class_orange

Thank you so much for your detailed explanation, it’s working now.
I will still need time to understand all the topics you have explained, but a big step forward of understanding how card_mod is working I’ve now done.

1 Like