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

Hopefully someone can help me make sense of this. I have a layout with header, (potential) subheader, main, and some footer cards. While header and footer will adapt to screensize/width, my main area for some reason seems to want to align only with the box shown in the screenshot. Not sure what I am missing here, can anyone point me in the right direction with this code:

title: home
path: home
icon: mdi:home
theme: ios-dark-mode-blue-red
background: "var(--background-image)"
type: custom:grid-layout
layout:
  margin: -0.5vh 1vh 0vh
  card_margin: 0px 0px 0px 0px
  grid-template-columns: auto
  grid-template-rows: 17vh 2vh 61vh 2vh 9vh 9vh
  grid-template-areas: |
    "header"
    "subheader"
    "main"
    "footer_title"
    "footer"
    "menu"
cards:
  - type: custom:button-card # HEADER
    view_layout:
      grid-area: header
    template: header
    variables:
      view: home
  - type: custom:layout-card # MAIN
    view_layout:
      grid-area: main
    layout_type: custom:vertical-layout
    layout:
      height: 61vh
      margin: 0vh 0vh 0vh 0vh
      padding: 0vh 0.4vh
    cards:
#################MAIN AREA######################################
      - type: vertical-stack
        cards:
        - type: custom:button-card
          template: room_card
          variables:
            room_card_name: Schlafzimmer
            room_card_icon: mdi:bed-king-outline
            room_card_temp: sensor.bedroom_echo_temperature
            entity_1: light.bedroom
            entity_1_icon: mdi:bed-outline
            entity_2: light.desklamp
            entity_2_icon: mdi:desk-lamp 
            entity_3: light.bathroom
            entity_3_icon: mdi:shower-head 
            media_player: media_player.40_tcl_roku_tv
            climate: climate.living_room
            popup_id: '#remote_bedroom'
            climate_popup: '#climate_bedroom'

Hi, maybe a new version available too soon. HA Core 2024.3, is not yet available.

The beta is actually available :wink:

I am having issues with the card_margin option inside a grid layout. It is not having an effect and if I am placing a grid inside a grid, the margins add up.

Tried card_margin: 0px 0px 0px 0px, card_margin: 0px 0px 0px 0px !important, card_margin: 0…

check this:

and this:

Im having some struggle aligning my cards for my tablet that is 1920*1200px.


How do I move the card up into the gap?

Are my card settings ok or should I change something? Im very new to this card…
im using layout card with these settings:

margin: 0px
padding: 0px
grid-template-columns: 300px 245px 245px 245px 190px
grid-template-rows: auto
grid-template-areas: |
ā€œrow1-1 row1-2 row1-3 row1-4 row1-5ā€
ā€œrow2-1 row2-2 row2-3 row2-4 row2-5ā€
ā€œrow3-1 row3-2 row3-3 row3-4 row3-5ā€
ā€œrow4-1 row4-2 row4-3 row4-4 row4-5ā€
ā€œrow5-1 row5-2 row5-3 row5-4 row5-5ā€

Hey there,

is it possible to set the zoom of a card content
like with (this works, but its for every screensize):

card_mod:
  style: |
    ha-card {
      zoom: 120%;
    }

but depending on the mediaquery?
At the moment i have:

type: custom:grid-layout
    layout:
      max_cols: 3
      height: calc(100vh)
      mediaquery:
        '(max-width: 500px)':
          grid-template-columns: 100%
          grid-template-rows: auto
        '(max-width: 1200px)':
          grid-template-columns: 50% 50%
          grid-template-rows: 33.3% 33.3% 33.3%
        '(max-width: 2200px)':
          grid-template-columns: 33.3% 33.3% 33.3%
          grid-template-rows: 45% 45%

But some card-contents are too small (fonts, icons…) when showing the dashboard on a big screen (the third option above).

regards
Stephan

You should use ā€œstretchā€ instead of ā€œzoomā€

Stretch, can be used with either ( justify-self: / justify-items: )
Stretch can also be used with (aling-items / align-self:)

And Yes this will also be in All screensize ( but it should fill 100% , of i.e a cell ) , and not 120% of a predefined card-width

A Complete Guide to CSS Grid | CSS-Tricks - CSS-Tricks.
CSS reference - CSS: Cascading Style Sheets | MDN. (choose properties)

And this ( Move/resize by ā€œdragging the vertical delimiterā€ ( code | result )

W3Schools Tryit Editor.

Hello @boheme61 ,

thanks for the help. But I didn’t found any information how to use ā€œstretchā€ in ha-card…(I’m not so good in CSS)

Can you give me a short example how to use it in my case?

regards

Stephan

By using Card-mod !

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

And the Search Box in this Forum can also be used to search in the whole Forum, or in a Specific Topic, like i.e above

Search results for 'justify-content; stretch' - Home Assistant Community.

Beside, Various cards have various options, as as all custom:-cards are build by individuals, they are build different, and behave different. ( Some dev’s of custom cards specify width in (px), in the card.js, some with ā€œmaxā€ etc. etc. )

If you have a use.case ! , with a specific card, i suggest you ask/search either in a Topic for that card, or in some of the big card-mod Topics

But as you mention specifics, within a card (fonts, icons etc) , you will have to read and test alot, upon your big-tv screen, Fonts / Pics are often specified in px.

But to be honest, i have no ā€œissuesā€ with the scaling on various devices
from Mobile(Max 900px), to laptop (1366x768 ), to TV (1920x1080 )

And you haven’t ā€œshovedā€ anything, or mentioned how your Browser is connected to your big-tv ( You do know you can specify i.e resolution , and in some case i.e text-size.( on the device/connection)
But again if you build ā€œadaptiveā€ there should not be any problems, as i have experienced

I got this pretty weird issue that when I use the layout card in horizontal mode (nested in a gridded button card, the button stack vertically.

See as follows

My corresponding code for the custom field is:

          time:
            card:
              type: custom:layout-card
              layout_type: horizontal
              layout:
                card_margin: 0
                margin: 0
                padding: 0
                max_width: 168px
              cards:
              - type: custom:button-card
                icon: ios:arrow-down
                triggers_update: input_number.climate_duration
                tap_action:
                  action: call-service
                  service: input_number.decrement
                  service_data:
                    entity_id: input_number.climate_duration
                styles:
                  card:
                  - height: 42px
                  - width: 42px
              - type: custom:button-card
                icon: ios:arrow-down
                triggers_update: input_number.climate_duration
                tap_action:
                  action: call-service
                  service: input_number.decrement
                  service_data:
                    entity_id: input_number.climate_duration
                styles:
                  card:
                  - height: 42px
                  - width: 42px

With the styles:

      - type: custom:button-card
        tap_action:
          action: toggle
        styles:
          grid:
            - grid-template-rows: 1fr 1fr 1fr 1fr
            - grid-template-columns: 1fr min-content min-content min-content
            - grid-template-areas: "'i t1 m s' 'l t2 m s' 'n t3 m s' 'time t4 m s'"
          card:
            - background-color: rgba(var(--ios-systemgray3),0.7);
            - border-radius: var(--border-radius);
            - padding: 10px;
          custom_fields:
            m:
              - justify-self: end
              - align-content: start
            s:
              - justify-self: end
              - padding-left: 12px
            t1:
              - justify-self: end
              - padding-right: 12px
              - font-size: "12px"
            t2:
              - justify-self: end
              - padding-right: 12px
              - font-size: "12px"
            t3:
              - justify-self: end
              - padding-right: 12px
              - font-size: "12px"
            t4:
              - justify-self: end
              - padding-right: 12px
              - font-size: "12px"
            time:
              - font-size: "12px"
              - justify-self: start

Any chance someone can point out what I’m doing wrong here? I mean, even if some style is messed up the last thing I would expect using horizontal mode is anything stacking vertically.

Try grid layout and define the columns

     - type: custom:layout-card
       layout_type: custom:grid-layout
       layout:
          grid-template-columns: 1fr 1fr
       cards:
          - type:

I have been trying for a while to make my 3 columns custom sizes.
I’ve tried with the dashboard layout set to Panel, masonry(layout-card) and grid(layout-card).

I’ve tried with the card in the dashboard being custom:masonry-layout and custom:grid-layout

I’ve tried setting the grid-template-columns to pixels, percents and fr. Whatever I do all 3 columns continue to be the exact same size as each other. I don’t understand what I’m doing wrong.

Here is the code I have currently, hoping someone can help me.:

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  width: 1250
  max_cols: 3
layout_options:
  grid-template-columns: 350px 450px 450px
  grid-template-rows: auto
  grid-template-areas: |
    "left middle right"
cards:
  - type: vertical-stack
    cards:
      - square: false
        type: grid
        cards:
          - type: vertical-stack
            view_layout:
              grid-area: left
            cards:
              - type: entity
                entity: sensor.sun_next_dawn
                name: Next Dawn
              - type: entity
                entity: sensor.sun_next_dusk
                name: Next Dusk
          - type: vertical-stack
            view_layout:
              grid-area: middle
            cards:
              - show_state: true
                show_name: true
                camera_view: live
                type: picture-entity
                entity: camera.front_porch_camera
                image: >-
                  http://192.168.0.0/ISAPI/Streaming/channels/101/picture?snapShotImageType=JPEG
                name: Front Porch Camera
                camera_image: camera.front_porch_camera
              - show_state: true
                show_name: true
                camera_view: live
                type: picture-entity
                entity: camera.north_yard_camera
                image: >-
                  http://192.168.0.0/ISAPI/Streaming/channels/201/picture?snapShotImageType=JPEG
                name: North Yard Camera
                camera_image: camera.north_yard_camera
          - type: vertical-stack
            view_layout:
              grid-area: right
            cards:
              - show_state: true
                show_name: true
                camera_view: live
                type: picture-entity
                entity: camera.back_yard_camera
                image: >-
                  http://192.168.0.0/ISAPI/Streaming/channels/401/picture?snapShotImageType=JPEG
                name: Back Yard Camera
                camera_image: camera.back_yard_camera
              - show_state: true
                show_name: true
                camera_view: live
                type: picture-entity
                entity: camera.south_yard_camera
                image: >-
                  http://192.168.0.0/ISAPI/Streaming/channels/301/picture?snapShotImageType=JPEG
                name: South Yard Camera
                camera_image: camera.south_yard_camera
        columns: 3

EDIT: I also tried this layout without the initial vertical stack and without the initial grid card. Nothing I do changes it from 3 equal columns

EDIT: also tried no vertical stack or grid, just the grid layout-card with 3 entity cards in it, marked with the proper grid areas. Still either had 3 equal columns or just 1 column. I don’t get it.

For the life of me I can’t seem to change the color of the background on the custom layout card that contains the other cards within it. Feels like I’m missing something very simple but I’ve spent hours with no luck. Anyone have any idea what I’m doing wrong? Excuse the poor mark-up, I’m working off a laptop.

  - title: test
    type: custom:horizontal-layout
    cards:
      - type: custom:layout-card
        layout_type: custom:masonry-layout
        layout:
          width: 150
          max_cols: 2
        cards:
          - type: custom:stack-in-card
            cards:
              - type: custom:mushroom-template-card
                primary: Main Gym Door
                secondary: |-
                  {% if is_state('binary_sensor.main_gym_door','on') %}
                    Door Open
                  {% elif is_state('lock.main_gym','unlocked') %}
                    Unlocked
                  {% else %}
                    Locked
                  {% endif%}
                icon: |-
                  {% if is_state('binary_sensor.main_gym_door','on') %}
                    mdi:door-open
                  {% elif is_state('lock.main_gym','unlocked') %}
                    mdi:lock-open
                  {% else %}
                    mdi:lock
                  {% endif%}
                icon_color: >-
                  {% if is_state('lock.main_gym','locked') and
                  is_state('binary_sensor.main_gym_door','off') %}
                    red
                  {% elif is_state('binary_sensor.main_gym_door','on') %}
                    yellow
                  {% else %}
                    green
                  {% endif%}
                badge_icon: >-
                  {% set battery_level = (states('sensor.main_gym_battery') |
                  int / 10) | round(0) | int * 10 %} {% if battery_level == 100
                  %} mdi:battery {% elif battery_level > 0 %} mdi:battery-{{
                  battery_level }} {% else %} mdi:battery-alert-variant-outline
                  {% endif %}
                badge_color: >-
                  {% set battery_level = states('sensor.main_gym_battery') | int
                  %}

                  {% if battery_level > 90 %} green

                  {% elif battery_level > 60 %} light-green

                  {% elif battery_level > 50 %} lime

                  {% elif battery_level > 40 %} yellow

                  {% elif battery_level > 30 %} amber

                  {% elif battery_level > 20 %} orange

                  {% elif battery_level > 10 %} deep-orange

                  {% else %} red

                  {% endif %}
                tap_action:
                  action: more-info
                entity: sensor.main_gym_battery
                layout: vertical
              - type: custom:mushroom-lock-card
                entity: lock.main_gym
                name: Main Gym Door
                primary_info: none
                secondary_info: none
                icon_type: none
            card_mod:
              style: |
                ha-card {
                  {% if is_state('lock.main_gym','locked') and
                  is_state('binary_sensor.main_gym_door', 'off') %}
                    background: rgba(145,2,2,0.5);
                  {% elif is_state('binary_sensor.main_gym_door', 'on') %}
                    background: rgba(130,130,0,0.5);
                  {% else %}
                    background: rgba(2,61,2,0.5);
                  {% endif %}
                }
          - type: custom:stack-in-card
            cards:
              - type: custom:mushroom-template-card
                primary: Main Front Door
                secondary: |-
                  {% if is_state('binary_sensor.main_front_door_door','on') %}
                    Door Open
                  {% elif is_state('lock.main_front_door','unlocked') %}
                    Unlocked
                  {% else %}
                    Locked
                  {% endif%}
                icon: |-
                  {% if is_state('binary_sensor.main_front_door_door','on') %}
                    mdi:door-open
                  {% elif is_state('lock.main_front_door','unlocked') %}
                    mdi:lock-open
                  {% else %}
                    mdi:lock
                  {% endif%}
                icon_color: >-
                  {% if is_state('lock.main_front_door','locked') and
                  is_state('binary_sensor.main_front_door_door','off') %}
                    red
                  {% elif is_state('binary_sensor.main_front_door_door','on') %}
                    yellow
                  {% else %}
                    green
                  {% endif%}
                badge_icon: >-
                  {% set battery_level =
                  (states('sensor.main_front_door_battery') | int / 10) |
                  round(0) | int * 10 %} {% if battery_level == 100 %}
                  mdi:battery {% elif battery_level > 0 %} mdi:battery-{{
                  battery_level }} {% else %} mdi:battery-alert-variant-outline
                  {% endif %}
                badge_color: >-
                  {% set battery_level =
                  states('sensor.main_front_door_battery') | int %}

                  {% if battery_level > 90 %} green

                  {% elif battery_level > 60 %} light-green

                  {% elif battery_level > 50 %} lime

                  {% elif battery_level > 40 %} yellow

                  {% elif battery_level > 30 %} amber

                  {% elif battery_level > 20 %} orange

                  {% elif battery_level > 10 %} deep-orange

                  {% else %} red

                  {% endif %}
                tap_action:
                  action: more-info
                entity: sensor.main_front_door_battery
                layout: vertical
              - type: custom:mushroom-lock-card
                entity: lock.main_front_door
                name: Main Front Door
                primary_info: none
                secondary_info: none
                icon_type: none
            card_mod:
              style: |
                ha-card {
                  {% if is_state('lock.main_front_door','locked') and
                  is_state('binary_sensor.main_front_door_door', 'off') %}
                    background: rgba(145,2,2,0.5);
                  {% elif is_state('binary_sensor.main_front_door_door', 'on') %}
                    background: rgba(130,130,0,0.5);
                  {% else %}
                    background: rgba(2,61,2,0.5);
                  {% endif %}
                }
          - type: custom:stack-in-card
            cards:
              - type: custom:mushroom-template-card
                primary: Main Hot Tub Door
                secondary: >-
                  {% if
                  is_state('binary_sensor.main_basement_to_hot_tub_door','on')
                  %}
                    Door Open
                  {% elif is_state('lock.main_basement_to_hot_tub','unlocked')
                  %}
                    Unlocked
                  {% else %}
                    Locked
                  {% endif%}
                icon: >-
                  {% if
                  is_state('binary_sensor.main_basement_to_hot_tub_door','on')
                  %}
                    mdi:door-open
                  {% elif is_state('lock.main_basement_to_hot_tub','unlocked')
                  %}
                    mdi:lock-open
                  {% else %}
                    mdi:lock
                  {% endif%}
                icon_color: >-
                  {% if is_state('lock.main_basement_to_hot_tub','locked') and
                  is_state('binary_sensor.main_basement_to_hot_tub_door','off')
                  %}
                    red
                  {% elif
                  is_state('binary_sensor.main_basement_to_hot_tub_door','on')
                  %}
                    yellow
                  {% else %}
                    green
                  {% endif%}
                badge_icon: >-
                  {% set battery_level =
                  (states('sensor.main_basement_to_hot_tub_battery') | int / 10)
                  | round(0) | int * 10 %} {% if battery_level == 100 %}
                  mdi:battery {% elif battery_level > 0 %} mdi:battery-{{
                  battery_level }} {% else %} mdi:battery-alert-variant-outline
                  {% endif %}
                badge_color: >-
                  {% set battery_level =
                  states('sensor.main_basement_to_hot_tub_battery') | int %}

                  {% if battery_level > 90 %} green

                  {% elif battery_level > 60 %} light-green

                  {% elif battery_level > 50 %} lime

                  {% elif battery_level > 40 %} yellow

                  {% elif battery_level > 30 %} amber

                  {% elif battery_level > 20 %} orange

                  {% elif battery_level > 10 %} deep-orange

                  {% else %} red

                  {% endif %}
                tap_action:
                  action: more-info
                entity: sensor.main_basement_to_hot_tub_battery
                layout: vertical
              - type: custom:mushroom-lock-card
                entity: lock.main_basement_to_hot_tub
                name: Main Hot Tub Door
                primary_info: none
                secondary_info: none
                icon_type: none
            card_mod:
              style: |
                ha-card {
                  {% if is_state('lock.main_basement_to_hot_tub','locked') and
                  is_state('binary_sensor.main_basement_to_hot_tub_door', 'off') %}
                    background: rgba(145,2,2,0.5);
                  {% elif is_state('binary_sensor.main_basement_to_hot_tub_door', 'on') %}
                    background: rgba(130,130,0,0.5);
                  {% else %}
                    background: rgba(2,61,2,0.5);
                  {% endif %}
                }
    card_mod:
      style: |
        ha-card {
          background-color: rgba(0,0,0,0.85);
        }

Multiple rows / colums can be done like:

grid-row-start: auto 
grid-row-end: span 2

grid-column-start: auto
grid-column-end: span 2

on the view options per grid item

I used a grid layout and was able to get what i was looking for.

Hello guys,

Do you know how to remove this difference from other cards using the grid layout-card?

image

margin: 0
grid-template-columns: 85% 1fr
grid-template-areas: |
  "left right"
mediaquery:
  "(max-width: 600px)":
    grid-template-columns: 80% 1fr
    grid-template-areas: |
      "left right"

Thank you a lot for your help :laughing:

Use the margin: setting like this margin: -10px 0px 0px 0px

margin: -10px 0px 0px 0px
grid-template-columns: 85% 1fr
grid-template-areas: |
  "left right"
mediaquery:
  "(max-width: 600px)":
    grid-template-columns: 80% 1fr
    grid-template-areas: |
      "left right"
1 Like

As an FYI to everyone using this: With the new 2024.06 update, layout-card dashboards break if they are using the break-card. The dashboard will all just be in one column instead of multiple.

Github issue is already present for this: Layout-break doesn't cause a column break in HA 2024.6 Ā· Issue #291 Ā· thomasloven/lovelace-layout-card Ā· GitHub

I want to document the fix here. Editing the yaml configuration of the dashboard, changing this:

type: custom:vertical-layout

to this:

type: custom:layout-card
layout_type: custom:vertical-layout

The caveat with this fix is that the dashboard will no longer be editable in the GUI, just in YAML. But it should provide you with a quick fix until a fix is merged or you build an alternative dashboard (e.g. with vertical stacks).

3 Likes

I will wait for the Fix.
Or is there another card that does the same.

1 Like