šŸ”¹ Card-mod - Super-charge your themes!

You should only need to put it once, outside of modes.

You can create a theme that doesnā€™t change anything but adds card-mod.

It sounds like thereā€™s a problem with your code.

It tells card-mod what to do, and it lets you create separate themes with styles you can tack on to another one.

You can create a variable, even if it isnā€™t included in HA. Then you could reference it like margin: var(--margin-in-dark-mode) in card-mod if you set it up like margin-in-dark-mode: 20px in your theme.

Which code exacltly? Themes are working = custom light & dark, noctis.
At least if I change some variable in any theme then I see effects in views.

This example I took from card-mod repository (put it inside Noctis):

noctis:  

  card-mod-theme: noctis
  card-mod-view-yaml: |
    hui-masonry-view:
      $: |
        #columns .column > * {
          margin: 32px 16px;
        }

Suppose these ā€œcard-mod-view-yamlā€-like sections (which defining styles, I think) are placed below that ā€œcard-mod-theme: noctisā€ line.
All this code is placed inside some theme (but outside modes) - I guess that this code already belongs to this particular theme, it is strange for me that we need to specify a name again.
Also, if some theme is called ā€œtheme123ā€ - should that ā€œnameā€ line be "card-mod-theme: theme123" (i.e. same name)? And if the theme is called ā€œCustom Themeā€?
Update: seems that this line must be exactly the same as the themeā€™s name (i.e. "card-mod-theme: "Custom Theme"" )

Yes, I call them ā€œuser-defined variablesā€.
So, if I understood your post properly, I got this code:

noctis:  

  card-mod-theme: noctis
  card-mod-view-yaml: |
    hui-masonry-view:
      $: |
        #columns .column > * {
          margin: var(--user-margin-between-cards);
        }
  user-margin-between-cards: 32px 16px

OMG! I do not understand what happened - but I succeeded with this old code (as well as with using variable, see above):

noctis:  

  card-mod-theme: noctis
  card-mod-view-yaml: |
    hui-masonry-view:
      $: |
        #columns .column > * {
          margin: 64px 32px;
        }

and with my custom theme:

Custom Theme:

  card-mod-theme: "Custom Theme"
  card-mod-view-yaml: |
    hui-masonry-view:
      $: |
        #columns .column > * {
          margin: 32px 32px;
        }

My 1st small victory! (have no idea why it did not work earlierā€¦)
Anyway, do not understand the meaning of that "card-mod-theme: "Custom Theme"" - since it repeats the name of the theme.

This mod is just awesome!
Opened new horizons)))

As I have answered above. :joy:

And regarding the why of card-mod-theme, I think it is the mapping to the theme, so that it is applied to the selected one.

Did you have already investigated the wiki pages? Next to the link to your non-theme examples. There it is described the same way.

No no no, it was not working first ))) I have no idea why!

Oh, that was a real starting point, thank you.
Actually, I was not going to dig into card-mod-themes right NOW - I planned to start learning it a bit later.
But I needed to set a fixed width to the right sidebar - so I started thinking about card-mod-themes.

Good tutorial, btw.

this is the name of the card-mod theme. you create the card-mod-theme, like I posted:

custom-header:

  card-mod-theme: custom-header

and then in your actual theme, say Dark red, use that card-mod-theme:

frontend:
  themes:
    Dark red:
      card-mod-theme: custom-header
      rest of your theme settings

you can see it as an !include really.

you can ofc name it anything, the name here is used because it pertains to my custom header settings. This works for my Christmas theme:

Christmas:

  card-mod-theme: christmas-theme

which is declared like:

christmas-theme:
  card-mod-theme: christmas-theme
  <<: *main
  card-mod-card: |
    ha-card {
      overflow: hidden;
    }

(<<: *main is a huge section I repeated from another card-mod-theme)

having an issue myself currently with the dark mode (specifically on Maps), only being applied on my iPhone, and not on any other device: Maps dont follow modes: dark: consistently Ā· Issue #11027 Ā· home-assistant/frontend Ā· GitHub

How to set a fixed width for a conventional right sidebar:

  card-mod-view-yaml: |
    hui-sidebar-view:
      $: |
        .container div#sidebar {
          min-width: 400px;
          width: -webkit-fill-available;
        }
2 Likes

OMG, one more excited post:
just yesterday started learning this mod - now I think card-mod-themes is one of greatest fundamental features in HA frontend like decluttering-card.
Thank you, @thomasloven !

All I want to do is add a clock to the header. This was easy with CCH but for some reason Iā€™m having trouble using Card-mod. I added this to the end of my theme (Github Dark Theme)

card-mod-theme: "Github Dark Theme"
  # Header
  card-mod-root-yaml: |
    mwc-icon-button[slot="trigger"] > ha-svg-icon {
      display: none;
    }

    mwc-icon-button[slot="trigger"]::after {
      font-size: 22px;
      height: 20px; 
      width: 100px;
      margin-left: 0px;
      margin-right: 0px;
      content: "{{ states('sensor.time') }}";
      position: absolute;
      top: 14px;
      right: 0px;
    }

I also added this to my sensor.yaml

- platform: time_date
  display_options:
    - "time"
    - "date"
    - "date_time"
    - "date_time_utc"
    - "date_time_iso"
    - "time_date"
    - "time_utc"
    - "beat"

The instructions of how to add this to a theme seem a little confusing to me so any help would be appreciated.

I guess that code is now outdated since HA changed a structure of a page.
Try the code below.
I changed a DOM path (did not touch height, width & position).

  card-mod-root-yaml: |
    ha-button-menu ha-icon-button $ mwc-icon-button: |
      ha-svg-icon {
        display: none;
      }
      mwc-icon-button::after {
        font-size: 22px;
        height: 20px; 
        width: 100px;
        margin-left: 0px;
        margin-right: 0px;
        content: "{{ '13:34:21' }}";
        position: absolute;
        top: 14px;
        right: 0px;
      }

ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ

Or you may have this button still displayed:

  card-mod-root-yaml: |
    ha-button-menu ha-icon-button $: |
      mwc-icon-button::before {
        font-size: 22px;
        height: 20px; 
        width: 100px;
        margin-left: 0px;
        margin-right: 30px;
        content: "{{ '13:34:21' }}";
        position: absolute;
        top: 14px;
        right: 0px;
      }

ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ

2 Likes

trying to change the icon of a tab is about the only thing left I like to establish in replacing my Custom Header from the old days. Please help me figuring this out.

We can change the color of a tab with:

        paper-tab[aria-label='Home'] {
          color: {{'red' if states('sensor.count_alerts_notifying') > '0'}};
        }

but adding an icon line there wont work, inspector says the icon is inherited from ha-tabs, and shows a yellow exclamation mark.

If I try and do something like:

/* Set the color of the currently selected tab indicator. */
        ha-tabs {
          --paper-tabs-selection-bar-color: black !important;
          --paper-tab[aria-label='Home summary'] {
            ha-icon: mdi:help !important;
          };
        }

nothing happens, except for the tab indicator being colored black.

same for:

        paper-tab[aria-selected='Home'] > ha-svg-icon {
          icon: mdi:help !important;
        }

Hope someone can assist me in finding the correct item in inspector to set an iconā€¦

this works for me:

        /* Optionally set a replacement template text. */
        ha-button-menu::before {
          content: "{% if states('sensor.browser_mod_safari') not in ['unknown','unavailable'] %}{{states('sensor.custom_header_template')}}{%endif%}";
          color: var(--text-primary-color);
          visibility: visible;
          position: relative;
          top: 24px;
          white-space: nowrap;
        }

Looking for this?
ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ

      paper-tab[aria-label='test'] ha-icon::after {
        margin-left: 10px;
        content: "xxxxxxxxxxxxxxx";
      }

Just specify an icon for the tab settings.

Good, easy & simple))

dont think so, I want to replace the icon set in the view, with a state dependent icon.

for example this is what we do in the regular Views:

title: Home
icon: mdi:home
path: home

in Custom Header we did:

tab_icons:
  settings_motion: >-
    {%- if states('binary_sensor.motion_sensors_all') == 'on' -%}mdi:motion-sensor
    {%- else -%}mdi:motion-sensor-off
    {%- endif -%}

which in a card-mod-theme would become something like:

        paper-tab[aria-label='Home'] ha-icon {
          icon:  {{'mdi:motion-sensor' if states('binary_sensor.motion_sensors_all') == 'on' else 'mdi:motion-sensor-off'}}
        }

ofc this doesnt workā€¦

I am not sure it is possible to REPLACE an icon in the tab.
I tried using --card-mod-icon - seems it does not work here.

Alternatively, you may add a state-dependent IMAGE instead of icon:

    paper-tab[aria-label='zont'] ha-icon $: |
      ha-svg-icon {
        display: none;
      }
    .: |
      paper-tab[aria-label='zont'] ha-icon::before {
        background: url("/local/images/persons/ildar.png");
        content: " --------------";
        color: transparent;         
        background-size: 100% 100%;
      }
      paper-tab[aria-label='zont'] ha-icon::after {
        margin-left: 10px;
        content: "my tab";
      }

ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ


Update: this variant allows to show a square image:
ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ

    paper-tab[aria-label='CM-themes-3'] ha-icon $: |
      ha-svg-icon {
        display: none !important;
      }
    .: |
      paper-tab[aria-label='CM-themes-3'] ha-icon::before {
        background: url("/local/images/persons/ildar.png");
        content: "-";
        color: transparent;         
        background-size: 100% 100%;
        height: 40px;
        width: 40px;
      }
      paper-tab[aria-label='CM-themes-3'] ha-icon {
        display: contents;
      }
      paper-tab[aria-label='CM-themes-3'] ha-icon::after {
        margin-left: 10px;
        content: "my tab";
      }
2 Likes

Nice :wink:

not what I was looking for, but at least some progress ā€¦

maybe we could ask Thomas for a FR here, since if you arenā€™t able to do it, it probably isnt an option currently :wink:

And these ::after & ::before stuff does not look as a reliable decision, does not work sometimes.

right, and, tbh, even the

        paper-tab[aria-label='Home'] ha-icon $: |
          ha-svg-icon {
            display: none;
          }

doesnt remove the icon in my configā€¦
o. wait, I had to move it up, directly under the card-mod-root-yaml. now it works :wink:

One more attempt (seems to be same, but just in case):

    paper-tab[aria-label='zont'] ha-icon:
      $: |
        ha-svg-icon {
          display: none;
        }
      .: |
        paper-tab[aria-label='zont'] ha-icon::before {
          background: url("/local/images/persons/ildar.png");
          content: " --------------";
          color: transparent;         
          background-size: 100% 100%;
        }
        paper-tab[aria-label='zont'] ha-icon::after {
          margin-left: 10px;
          content: "my tab";
        }

As I said it is not stable - in my setup it works after F5

maybe we should investigate another way, just like we can do with the background:

weather-background:
  card-mod-theme: weather-background
  card-mod-view: |
    hui-masonry-view {
      background: url({{state_attr('camera.buienradar','entity_picture')}});
    }

which overrides a background set in the regular View:

title: Solar
path: solar
icon: mdi:solar-power
background: center / cover no-repeat url('/local/images/solar_grid.png') fixed

maybe we can also override the icon like that?
answering myself: no we cantā€¦ there simpā€™y doesnt seem to be an item to override (set a value for in card-mod-theme) for icon?

Background may be changed by a corresponding property.
Icon may be changed by a brute force method:
Untitled Projectxcvrfe3333

  card-mod-root-yaml: |
    paper-tab[aria-label='zont'] ha-icon $ ha-svg-icon $: |
      path {
        {% if is_state('input_boolean.test_boolean','on') %}
        d: path("M 20.2 5.9 L 21 5.1 C 19.6 3.7 17.8 3 16 3 C 14.2 3 12.4 3.7 11 5.1 L 11.8 5.9 C 13 4.8 14.5 4.2 16 4.2 C 17.5 4.2 19 4.8 20.2 5.9 M 19.3 6.7 C 18.4 5.8 17.2 5.3 16 5.3 C 14.8 5.3 13.6 5.8 12.7 6.7 L 13.5 7.5 C 14.2 6.8 15.1 6.5 16 6.5 C 16.9 6.5 17.8 6.8 18.5 7.5 L 19.3 6.7 M 19 13 H 17 V 9 H 15 V 13 H 5 A 2 2 0 0 0 3 15 V 19 A 2 2 0 0 0 5 21 H 19 A 2 2 0 0 0 21 19 V 15 A 2 2 0 0 0 19 13 M 8 18 H 6 V 16 H 8 V 18 M 11.5 18 H 9.5 V 16 H 11.5 V 18 M 15 18 H 13 V 16 H 15 V 18 Z") !important;
        color: magenta !important;
        {% else %}
        d: path("M 12 2 A 10 10 0 0 0 2 12 A 10 10 0 0 0 12 22 A 10 10 0 0 0 22 12 A 10 10 0 0 0 12 2 M 16.2 16.2 L 11 13 V 7 H 12.5 V 12.2 L 17 14.9 L 16.2 16.2 Z") !important;
        color: cyan !important;
        {% endif %}
      }

Cannot say that this is a stable solution.

1 Like