šŸ”¹ Layout-card - Take control of where your cards end up

Hey there,

i need some help.
I cant get my Tablet Dashboard to fit perfectly.
What i want is that the left column is on the very left side of the screen, but no matter how much i increase padding it wont move more to the left.

How can i achieve this?

This is the code i currently use

type: horizontal-stack
cards:
  - type: custom:layout-card
    layout_type: custom:vertical-layout
    cards:
      - type: custom:stack-in-card
        cards:
          - type: custom:mushroom-template-card
            primary: '{{ states(''sensor.time'') }}'
            secondary: '{{ now().strftime(''%d.%m.%y'') }}'
            icon: ''
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 75px;
                  --card-secondary-font-size: 35px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                  --spacing: -10px;
                }
          - type: custom:gap-card
            height: 2
          - type: custom:mushroom-template-card
            primary: Ɯbersicht
            icon: mdi:view-dashboard
            icon_color: brown
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/0
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
          - type: custom:mushroom-template-card
            primary: KlimagerƤte
            icon: mdi:air-conditioner
            icon_color: light-blue
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/klima
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
          - type: custom:mushroom-template-card
            primary: Energie
            icon: mdi:lightning-bolt
            icon_color: green
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/energie
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
          - type: custom:mushroom-template-card
            primary: Hausdaten
            icon: mdi:home
            icon_color: grey
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/hausdaten
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
          - type: custom:mushroom-template-card
            primary: Sensoren
            icon: mdi:thermometer
            icon_color: red
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/sensoren
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
          - type: custom:mushroom-template-card
            primary: Media
            icon: mdi:play-box
            icon_color: purple
            layout: horizontal
            fill_container: false
            hold_action:
              action: none
            double_tap_action:
              action: none
            tap_action:
              action: navigate
              navigation_path: /dashboard-bastitabletv2/media
            card_mod:
              style: |
                ha-card {
                  --card-primary-font-size: 20px;
                  text-align: center;
                  --ha-card-background: #3b6687;
                }
    layout:
      width: 250
      padding: 4px 600px 0px 0px
  - type: custom:layout-card
    layout_type: custom:vertical-layout
    cards:
      - type: horizontal-stack
        cards:
          - type: custom:mushroom-template-card
            primary: Basti
            secondary: ''
            icon: |-
              {% if is_state('person.basti', 'Tenowo') %}
                mdi:briefcase
              {% elif is_state('person.basti','BadTaura') %}
                mdi:swim
              {% else %}
                mdi:home
              {% endif %}
            icon_color: |-
              {% if is_state('person.basti', 'home') %}
                green
              {% elif is_state('person.basti', 'Tenowo') %}
                red
              {% elif is_state('person.basti','BadTaura') %}
                blue
              {% else %}
                grey
              {% endif %}
            entity: person.basti
            layout: vertical
            card_mod:
              style: |
                ha-card {
                  --icon-size: 50px;
                  --card-primary-font-size: 20px;
                }
          - type: custom:mushroom-template-card
            primary: Saskia
            secondary: ''
            icon: mdi:home
            icon_color: |2-
                    {% if is_state('person.saskia', 'home') %}
                      green
                    {% else %}
                      grey
                    {% endif %}
            layout: vertical
            card_mod:
              style: |
                ha-card {
                  --icon-size: 50px;
                  --card-primary-font-size: 20px;
                }
          - type: custom:mushroom-template-card
            primary: >-
              {% set tage = ((state_attr('calendar.abfall_2', 'start_time') |
              as_datetime |

              as_local).date() - now().date()).days %}

              {% if tage == 0 %}
                Heute
              {% elif tage == 1 %}
                Morgen
              {% elif tage > 1 %}
                in {{ tage }} Tagen
              {% endif %}
            secondary: ''
            icon: |-
              {% set art = state_attr('calendar.abfall_2', 'message') %}
              {% if art == 'gelbetonne' %}
                mdi:recycle-variant
              {% elif art == 'restmuell' %}
                mdi:trash-can
              {% elif art == 'papier' %}
                mdi:note-text
              {% elif art == 'biotonne' %}
                mdi:delete-empty
              {% else %}
                mdi:chat-question
              {% endif %}
            icon_color: |-
              {% set art = state_attr('calendar.abfall_2', 'message') %}
              {% if art == 'gelbetonne' %}
                yellow
              {% elif art == 'restmuell' %}
                blue-grey
              {% elif art == 'papier' %}
                blue
              {% elif art == 'biotonne' %}
                brown
              {% endif %}
            layout: vertical
            card_mod:
              style: |
                ha-card {
                  --icon-size: 50px;
                  --card-primary-font-size: 20px;
                }
      - type: custom:mushroom-title-card
        title: ''
        subtitle: Temperatur
      - type: horizontal-stack
        cards:
          - type: custom:mini-graph-card
            hour24: true
            hours_to_show: 12
            points_per_hour: 3
            update_interval: 60
            height: 70
            line_width: 3
            animate: true
            align_state: center
            font_size: 95
            show:
              name: true
              icon: false
              legend: false
            entities:
              - entity: sensor.stubentemp
                name: Innen
                show_state: true
                color: '#ff0000'
            card_mod:
              style: |
                ha-card {
                  font-size: 16px !important;
                }
          - type: custom:mini-graph-card
            hour24: true
            hours_to_show: 12
            points_per_hour: 3
            update_interval: 60
            height: 70
            line_width: 3
            animate: true
            align_state: center
            font_size: 95
            show:
              name: true
              icon: false
              legend: false
            entities:
              - entity: sensor.aussentemperatur_jens_2
                name: AuƟen
                show_state: true
                color: '#00e1ff'
            card_mod:
              style: |
                ha-card {
                  font-size: 16px !important;
                }
    layout:
      width: 650
      padding: 0px 0px 0px 100px

EDIT:

I figured it out! I was using a horizontal stack, now im using 2 layout card in vertical mode.

1 Like

Hi I see that you managed to change the ā€œstateā€-icon for the heatpump? I have the same application and would like to change the threeway valve and also the icon for when the compressor and circulation pump are active. How did you resolve this?

My whole config is included with my original message for reference. Use the image type picture element with an ā€˜onā€™ and an ā€˜offā€™ image.

Hi All,

First, thank you @thomasloven for both the layout-card and card-mod. They are both very powerful and at the same time confound me with all the options! (in a good way).

In the GitHub README.md, it says:
NOTE: Please be aware that layout-card is itself a CARD

So, ā€¦ if layout-card is a card itself, (at least in my simple way of approaching this) shouldnā€™t it have its own background color, border-radius, etc

Iā€™m trying to put together 5 weather elements. Iā€™m using some gauges, and some bar charts, etc. (yes, WAY too over-engineered!). So far, each of the elements inside the custom:grid-layout card is working. I even set the background to completely transparent for each card.

BUT, if custom:layout-card is a card itself, then I should be able to apply a consistent background color for the entire layout-card, right? I should also be able to do more funky things like border-radius, etc. etc.

Iā€™ve tried the following:

card_mod:
  style: |
    ha-card {
      background: pink;
      border: 2px;
    }

But the entire layout-card itself does not change colors. Where am I going wrong?

This is a part of my YAML:

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  grid-template-columns: 20% 20% 20% 20% 20%
  padding: 0px
  margin: 0px
  card_margin: 0px
cards:
  - type: gauge
    entity: sensor.just_uv
    needle: true
    name: ''
    min: 0
    max: 12
    card_mod:
      style: |
        .type-gauge {
          padding: 0px;
          border: 0px;
          border-radius: 0px;
          background: rgba(0, 0, 0, 0)
        }
    segments:
      - from: 0
        color: green
      - from: 3
        color: yellow
      - from: 6
        color: orange
      - from: 8
        color: red
      - from: 10
        color: maroon
  - type: custom:gap-card

Hi,

Basically, since layout-card is not a card in itself, it does not have an ha-card element. This means you cannot style an entire layout-card, only the cards within it. In your case, you can style the gauges individually but not the entire grid at once.

However, you can circumvent this limitation by wrapping your layout-card within a mod-card (check the card-mod docs) and you can then style your layout-card.

I think this is why I got confused. On the GitHub documentation for [custom:layout-card](https://github.com/thomasloven/lovelace-layout-card) it says " Please be aware that layout-card is itself a CARD"

Iā€™m still struggling with card_mod, but it might be outside of the scope of this forum. Just in case, this is what Iā€™ve tried:

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  grid-template-columns: 20% 20% 20% 20% 20%
  padding: 0px
  margin: 0px
  card_margin: 0px
card_mod:
  style: |
    ha-card {
      background-color: pink;
    }
cards:
      ...
      ...

I also tried instead of ha-card, I used

    layout-card {
      background-color: red;
    }

Neither worked :frowning:
Is there a good tutorial of how to use card-mod for beginners? Thanks again!

I donā€™t think you understood what I wrote. What youā€™re attempting wonā€™t work. As I said, you have to wrap your layout-card within a mod-card to apply styling to it:

type: custom:mod-card
card_mod:
  style: |
    ha-card {
      background-color: pink;
    }
card:
  type: custom:layout-card
  #rest of your layout-card code goes here
1 Like

AH ha!
You were correct, I wasnā€™t understanding what you wrote! Yes, that worked. Iā€™ll have to read more on the custom:mod-card
Thanks a lot!!!

Glad you got it to work! Happy experimenting!

Thanks again. I have to find the docs on custom:mod-card. I know where the card mod 3 is, but Iā€™ll continue to search for mod-card.

Getting a bit off-topic here, but the mod-card is a part of card-mod, so itā€™s in the card-mod docs.

Hi, i have a strange problem with the heights of some cards. i am usning layout-card in grid mode and give all cards a specific grid-area. But in this example the heights of the cards are not identical (vertical stack is much larger even so there are not that much entities inside the card). How can i reszie all cards to one level?!

Finally got masonry working with grid layout. Itā€™s currently an ugly js loop that sets the grid-row-end to a span of the height in pixels of each grid item, where I use 1px auto repeating rows, but hey it works.

Will shortly add newest (cleanup) commits/screenshots to github.com/tbrasser/config

1 Like

Iā€™m looking forward to see it.

How can I get the weather card on the bottom of this layout to take up both columns?

square: false
type: grid
title: Living Room
cards:
  - type: light
    entity: light.living_room_lights
  - type: media-control
    entity: media_player.living_room_tv
  - type: vertical-stack
    cards:
      - type: weather-forecast
        entity: weather.openweathermap
columns: 2
view_layout:
  grid-area: Living

  - title: Google
    path: google
    icon: mdi:google
    layout:
      margin: 0
      gridrows: auto
      grid-template-columns: repeat(4, 1fr) 0
      grid-template-rows: 0 repeat(2, fit-content(100%)) 0fr
      grid-template-areas: |
        "sidebar  .           .       .       ."
        "sidebar  Master      Living  Office  ."
        "sidebar  Kitchen     Rachel  Guest   ."
        "sidebar  footer      footer  footer  ."
    type: custom:grid-layout

Is layout_card broken?

Iā€™m getting into more and more trouble with the grid layout, so I thought letā€™s visit the basics and do a simple testā€¦

views:
  - type: custom:grid-layout
    title: test2
    path: test2
    icon: mdi:home-assistant
    layout:
      grid-template-columns: 1fr
      grid-template-rows: 2fr 2fr 4fr 4fr
      margin: 0
      padding: 0
      card_margin: 0
    cards:
      - type: markdown
        view_layout:
          grid-row: 1
        content: blok1
      - type: markdown
        view_layout:
          grid-row: 2
        content: blok2
      - type: markdown
        view_layout:
          grid-row: 3
        content: blok3
      - type: markdown
        view_layout:
          grid-row: 4
        content: blok4

I would expect an single column, 4 row, entire screen spanning result, but to my amazement itā€™s notā€¦

when al row elements are equal, wheter itā€™s fr or % it defaults to 4 small rows at the top (tried minmax (0,1fr) too). Only when the rows are different the change, but still not using the whole viewport.
Iā€™m missing somethingā€¦but what?

Have you tried setting grid-template-columns value to 100%?

I think if there is room on the screen, column width defaults to the standard HA column width (max. 500px from memory) if no precise value is given.

EDIT: or do you mean filling the screen vertically? Sorry, no idea about that one.

Thanks!. But indeed itā€™s in respect to the vertical. By the way, where can I find more info on the default column widt of HA, I did not know this. Maybe there is a similar restraint to be found. Regratabbly Iā€™m not a CSS wiz, I think maybe I need to spend some time going through the whole tree but that will take a week or more Iā€™m afraid.

try:

layout:
  height: calc(100vh - var(--header-height))
  grid-auto-flow: column dense

are you using a panel view? Optionally you can put in a mod card and force the height to 100%, or put it in a vertical stack.

Hi,

I will go crazy :slight_smile:

what I want is to adjust cards width %20 and %80 respectively. Currently the are sharing whole row 50%50%. (Mushroom template and timer bar card)

I even tried chatgpt but could not do it. Can anyone please help?

type: custom:stack-in-card
card_mod:
  style: |
    ha-card {
      --ha-card-border-width: 0px;
mode: vertical
cards:
  - type: grid
    square: false
    columns: 2
    cards:
      - type: custom:mushroom-template-card
        primary: '{{ state_attr(''switch.zone_1'', ''friendly_name'') }}'
        icon: mdi:sprinkler
        multiline_secondary: true
        entity: switch.zone_1
        tap_action:
          action: more-info
        card_mod:
          style: |
            ha-card {
              --icon-size: 32px;
              height: 48px !important;
            }
      - type: custom:timer-bar-card
        entities:
          - timer.zone_1_timer
        layout: hide_name
        text_width: 50px
        bar_foreground: '#fa572d'
        sync_issues: ignore
        extend_paper_buttons_row:
          position: right
          buttons:
            - icon: mdi:play
              state_styles:
                active:
                  button:
                    color: green
              entity: timer.zone_1_timer
              layout: icon
              tap_action:
                action: call-service
                service: timer.start
                service_data:
                  entity_id: timer.zone_1_timer
        card_mod:
          style: |
            ha-card {
              height: 48px;
              display: flex;
              align-items: center;
            }

            state-badge {
              height: var(--icon-size);
              width: var(--icon-size);
              margin-right: 16px;
            }