šŸ”¹ Card-mod - Add css styles to any lovelace card

somehow, Ive always used custom:button-card to make the headers of my compound listing cards (entities, vertical-stack) when in need of some templated value in the header.

my regular headers are:

        ha-card.class-header-margin .card-header {
          background: var(--background-color-off);
          font-weight: 400;
          font-size: 20px;
          color: var(--text-color-off);
          padding: 0px 12px;
          margin: 0px 0px 16px 0px;
        }

in card-mod theme, and they are matched by this button-card template:

button_default_title:
  show_state: false
  show_icon: false
  tap_action:
    action: none
  styles:
    card:
      - background: var(--background-color-off)
      - color: var(--text-color-off)
      - font-size: 20px
      - font-weight: 400
      - padding: 12px
    name:
      - justify-self: left

and make this possible:

  - type: custom:button-card
    template: button_default_title
    name: >
      [[[ return 'Kies Activiteit: ' + states['input_select.activiteit'].state; ]]]

only now (ā€¦) it dawned on me, I could also use a markdown card for the templated content, so I copied the style, but it doesnā€™t exactly fit.

  - type: markdown
    content: >
      Kies Activiteit: {{states('input_select.activiteit')}}
    card_mod:
      style: |
        ha-card.type-markdown {
          background: var(--background-color-off);
          color: var(--text-color-off);
          font-size: 20px;
          font-weight: 400;
        }
        .no-header {
           padding: 8px 12px 14px 12px;
        }

itā€™s almost there, but the margins are a bit peculiar. Ive set them on the .no-header now, at forst I had set them on the card, but apparently the markdown has its own stylings that interfere

as it stands its very nice, but not exact, and need a second eye to see where I should change the padding to make it perfect.
The top card is the button-card, with a perfectly centered name. the bottom one is the markdown, which slightly changes:

I could probably customize those paddings more meticulously, as I had to do with the new section heading

        ha-card.class-section-heading .container {
          background: var(--background-color-off);
          --ha-heading-card-title-color: var(--text-color-off) !important;
          --ha-heading-card-title-font-size: 20px !important;
          --ha-heading-card-title-font-weight: 400;
          height: 24px;
          padding: 12px 8px 12px 12px;
        }

but maybe I am targeting the wrong element in the Markdown ?

btw Iā€™ve filed a FR for adding actions to Markdown please consider upvoting that

Hi,
Can you please advise how exactly you put this class in the theme? Cam you maybe show the full structure. I was not able to reproduce.

    card-mod-card-yaml: |

      .: |

        ha-card.class-section-heading .container {
          background: var(--background-color-off);
          --ha-heading-card-title-color: var(--text-color-off) !important;
          --ha-heading-card-title-font-size: 20px !important;
          --ha-heading-card-title-font-weight: 400;
          height: 24px;
          padding: 12px 8px 12px 12px;
        }
1 Like

Hi,
is it possible to add the standard border and backgroud to a grid so it looks like a card?
I populated a grid with multiple heading and followed previous posts to add border and background to each of them but i prefer to have all in one.

image

Could anyone please help me move the Home icon left to align with the floorplan icon? Iā€™d also like to give it a background in the same mannerā€¦

Itā€™s
<state-badge class=" pointer " tabindex="0" icon=""></state-badge>

Code for the relevant part of the card at the moment is

type: entities
entities:
  - entity: input_text.alexa_announcement_string
    name: Alexa Announcement
    icon: mdi:home-sound-out-outline
    secondary_info: none
show_header_toggle: false
state_color: false

card_mod:
  style: |
    ha-card {
      border-radius: 100px!important;
    }

I tried adding

    ha-state-badge {
      background: red;
    }

but doesnā€™t seem to do anythingā€¦ I think iā€™m fundamentally misunderstanding how cardmod works somewhere because I copy code from elsewhere and try to rationally adjust but I have a 50% hit rate on it working or not!

Adapting custom:button-card for Sections (for anyone using Sections):
post
image

1 Like

We have had custom dashboards using card-mod for awhile now. we have modified a few things but most importantly have been using it to change the grid card so that the contents can have specific column span and row span. this worked great until this spring (sorry not exactly sure what version of HS broke it ~ 2024-05?)

I have been trying various configurations of card-mod to get this to work again to no avail. i have some sample code that was working just fine - and would make a 3x3 grid, with the first card taking up 2x2. any idea how to get this to work properly now? thanks in advance.

  - title: Nurse
    path: nurse
    type: custom:mod-card
    card:
      square: false
      type: grid
      cards:
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/C0zwc7l50KmBqslb
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
          card_mod:
            style: |
              :host {
                grid-column: span 2;
                grid-row: span 2;
              }
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/ffituAXS8Efc6Ktw
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/ffituAXS8Efc6Ktw
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/sinRmeL0hx9nnC8R
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/FkVWg1EpbrdAuqzU
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
        - type: custom:webrtc-camera
          url: rtsp://10.0.0.34:7447/YMjb6dcj34OBuHse
          style: '.mode {display: none} video {aspect-ratio: 16/9; object-fit: cover;}'
      columns: 3
    card_mod:
      style: |
        ha-card {
          background-color: #000;
        }
        :host {
          --grid-card-gap: 0px;
          --ha-card-border-width: 0px;
          --ha-card-border-radius: 0px;
        }```

nvm - i ended up switching from grid to custom:layout-card grid and all is working well. only using card-mod for overriding borders etc. thx!

I think you can use the heading cards and the badges for this

The user asked about a possibility to INPUT values directly.
Otherwise a simple Glance card might be enough: a horizontal row with 4 static values, a more-info pop up with a possibility to input on a tap_action.
Heading may provide a similar look - but needs modding since all entities will be aligned on the right.

I have this card for controling my TVR

Przechwytywanie

features:
  - type: climate-hvac-modes
    hvac_modes:
      - auto
      - heat
      - 'off'
type: tile
entity: climate.zigbee_grzejnik_salon
name: Grzejnik salon
icon: mdi:radiator
tap_action:
  action: more-info
card_mod:
  style: |
    ha-card {
      position: relative;
    }
    ha-card::before {
      content: '{{ states("sensor.zigbee_grzejnik_salon_position") }}%';
      position: absolute;
      top: 16px;
      right: 16px;
      z-index: 1;
      font-weight: bold;
    }

Iā€™ve managed to get the position state to show on the card, but now how can I get more info of the position sensor when clicking it? Also can I add a valve icon in front of the position %?

1 Like

Thanks, very helpful! I replicated your headings card-mod code but I canā€™t figure out how to vertically center the text. Any thoughts?

You seem to have changed a height of the heading, right? Probably you need to align a container (which includes all elements) vertically. Check in Code Inspector, find this container and play with corr attributes, cannot tell more, no access to pc

Nope. The heading card has this extra space on top if itā€™s not contained in a vertical stack card. Itā€™s truly infuriating.

This is called a margin-top. Try to reduce it then.

Trying to implement the following as a template:

card_mod:
  style: |
    /* Styles for mobile devices */
    @media (max-width: 767px) {
      ha-card {
        position: fixed;
        bottom: 0px;
        left: 0px;
        width: 100%;
        height: 80px;
        box-shadow: 0px -5px 10px rgba(0, 0, 0, 0.3);  
      }
    }
    /* Styles for desktop devices */
    @media (min-width: 766px) {
      ha-card {
        position: fixed;
        bottom: 0px;
        left: 0px;
        width: 20%;
        height: 75px;
        padding: 5px;
      }
    }

However when putting the following in the theme file:

.nav-bar {
  /* Styles for mobile devices */
    @media (max-width: 767px) {
      ha-card {
        position: fixed;
        bottom: 0px;
        left: 0px;
        width: 100%;
        height: 80px;
        box-shadow: 0px -5px 10px rgba(0, 0, 0, 0.3);  
      }
    }
    /* Styles for desktop devices */
    @media (min-width: 766px) {
      ha-card {
        position: fixed;
        bottom: 0px;
        left: 0px;
        width: 20%;
        height: 75px;
        padding: 5px;
      }
    }
}
card_mod:
  class: nav-bar

and assigning the card mod as a template, it doesnā€™t seem to take. Not sure how to utilize the @media functions within a template.

I have this weird issue that my column id (in hui view) has a certain width but the class for some reason has a max-width (purple is the ā€œpaddingā€)
image

It is basically nor dynamically adjusting to the screen width (e.g. when I flip the phone)

My theme file does not command any sizes or widths and each view starts with a simple vertical-stack. I tried to apply widths directly to the cards to no avail.

The only thing I could think of was my use of kiosk mode but even without it, the column width is not dynamic.

Any help is appreciated. Iā€™m running out of ideas here.

This is wrong syntax. You placed a media query between 2 selectors. It must be topmost. Imagine that simple removing media query should not break the syntax - but it breaks in your case.

Not quite sure what youā€™re suggesting to write out. I tried this as well:

card-mod-theme: theme
card-mod-card: | 
  /* Styles for mobile devices */
  @media (max-width: 767px) {
    ha-card(.nav-bar)  {
      position: fixed;
      bottom: 0px;
      left: 0px;
      width: 100%;
      height: 80px;
      box-shadow: 0px -5px 10px rgba(0, 0, 0, 0.3);  
    }
  }
  /* Styles for desktop devices */
  @media (min-width: 766px) {
    ha-card(.nav-bar) {
      position: fixed;
      bottom: 0px;
      left: 0px;
      width: 20%;
      height: 75px;
      padding: 5px;
    }
  }
card_mod:
  class: nav-bar

No success

This is also wrong.
Do you want to say that ā€œnav-barā€ class contains ha-card element?
Anyway, suggest you first to achieve your goal in a theme without using media query - to find out a proper DOM path.

If ā€œhav-barā€ is a class of a card - then probably a proper path should be ā€œha-card.nav-barā€.
So try this (untested):


card-mod-card: | 
  /* Styles for mobile devices */
  @media (max-width: 767px) {
    ha-card.nav-bar  {
      ā€¦.
    }
  }

Also, discussing themes is not supposed to be done here, find a dedicated card-mod-themes thread.