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

Same. Any ideas?

Actually:

2.2.0 IS BREAKING

Make card editors work again wen using view_layout which has replaced layout for cards.

Itā€™s also now column_widths instead of column_width.

Unfortunately the developer decided to replace the component with something completely different that is completely incompatible with the old one.
And he did this by keeping the same name, making it impossible to downgrade to a functional version with HACS (can only downgrade to one of the last 5 versions - and he managed to release more than that).

Instead of keeping the old one and publishing a new component with whatever new features he wanted, he chose to break all layouts done by everyone that ever used this component until now.

I have spent the last few hours removing this broken component and replacing with default ā€œgridā€ and ā€œvertical-stackā€/ā€œhorizontal-stackā€. At least these will work and I donā€™t need to learn new parameters every time the developer decides to break everything again.

trust is hard to get and easy to loseā€¦ especially when doing such moves.

Hi, I hope anyone can help me, I am trying to set margins on the columns, which I now achieve by setting the margins on each card or stack manually.

With reading around a bit I found that I can use this:

        - type: custom:mod-card
          style: |
            layout-card {
              --masonry-view-card-margin: 7px;
            }
          card:

This works absolutely fine and exactly what I needed. However it only does this on larger screens. When the aspect ratio drops to a certain level this setting gets overridden by whatever the original settings are.

I have tried setting !important but this did not help. Can anyone help me?

Not, that I would in any way back what youā€™re saying, it is in most things your opinion and youā€™re entitled as such.

But the quoted part is definitively not true:
You can always change the number of versions that is shown, so you can downgrade every time, to every old version that is still listed at Github.
Go to Integrations > HACS > Configure and change the number of releases to showā€¦ :wink:

Maybe it would have helped, if you had read the release notes and asked before you did this stunt of updating and deleting. Just sayingā€¦ :wink:

1 Like

Thanks, I will check that. Itā€™s an workaround since it would be required for every update (or new install) from now on to do this extra steps.

Anyway, itā€™s my opinion and trust lost canā€™t be gained back easily. I wonā€™t learn again a new syntax just to see it changed again with complete disregard to anyone else that built things on top.

Hi @thomasloven Iā€™ve been trying to get one specific card working with type: 'custom:grid-layout' without success.
It is the BOM Weather Card by DavidFW1960
I have asked him, he requested I ask you as well.

His card shows up without any changes to itā€™s config, but when adding:

view_layout:
   grid-area: ***

it breaks.
Curiously, it shows up and in the correct grid location while in Lovelace edit mode, but once exiting edit mode it disappears.

Other cards, including type: 'custom:weather-card' work just fine.

Is there anything special a card need in itā€™s source code to make it work correctly in grid layout mode?

My .yaml:

title: BOM Test
views:
  - title: Home
    path: home
    type: 'custom:grid-layout'
    layout:
      grid-template-columns: 10% 80% 10%
      grid-template-rows: auto
      grid-template-areas: |
        ". bom ."
    badges: []
    cards:
      - type: 'custom:bom-weather-card'
        view_layout:
          grid-area: bom
        entity_current_conditions: sensor.noble_park_icon_descriptor_0
        entity_temperature: sensor.moorabbin_airport_temp
        entity_forecast_high_temp_1: sensor.noble_park_temp_max_1
        etc... etc........

Hi,
I have divided my dashboard to header, footer and mid section. Now Iā€™m trying to add a picture to the mid section to work as background. All is working well, except there is a visible gap between the picture and edge of the footer (on the bottom) and header (on the top) section. No matter what I do I canā€™t get rid of that gap. Is there a way how to stretch the picture from header to footer?

Here is the portion of the code:

- panel: false
  path: office
  badges: []
  title: Office
  type: custom:grid-layout
  layout:
    grid-template-columns: 955px
    grid-template-rows: 91px 415px 96px
    grid-template-areas: |
      "header"
      "main"
      "footer"
  cards:  
    - type: picture-elements            #Top Header Section
      image: /local/lovelace/images/banner_top.png
      view_layout:
        grid-area: header
      style: |
        ha-card {
          background: rgba(42, 46, 48, 1)
          position: fixed
          margin-bottom: 0px
          padding-bottom: 0px
          }
      elements:
        - type: state-label
        - type: state-label
        - type: custom:text-element          
        - type: state-label
    - type: picture-elements                 # Middle Section
      image: /local/lovelace/images/background1.jpg
      view_layout:
        grid-area: main
      elements:  
        - type: 'custom:layout-card'
          style:
            bottom: -50%
            left: 50%
            margin-top: -15px
          layout_type: custom:grid-layout
          #view_layout:
          #  grid-area: main
          layout:
            grid-template-rows: 15px 130px 130px 130px 20px
            grid-template-columns: 118px 118px 118px 118px 118px 118px 118px 118px
            grid-gap: 0px 0px
          cards:
            - name: QNAP NAS
            - name: ProxmoxVE
              ...
    - type: picture-elements      #Bottom Footer Section

Maybe there is other way how to achieve this?
Thanks

1 Like

@marrossko
Iā€™m no expert at this, but it might help to use percentages instead of pixels for your grid-template-columns: and grid-template-rows: values?
That would ensure youā€™re using 100% of the space.

layout:
    grid-template-columns: 100%
    grid-template-rows: 33% 66% 33%

trying to nest a layout within a layoutā€¦has anyone done this and can provide an example?

Hello,

Iā€™m looking to have a layout with variable column size. My understanding is that grid layout is the right choice for this. I manage to have something that looks like this:

Is it possible to avoid the blank spaces (marked as X in screenshot) between cards? Apologies if this is obvious but Iā€™m looking at the documentation (A Complete Guide to Grid | CSS-Tricks) and itā€™s not obvious to me. Can anyone point me in the right direction?

For reference, the code that Iā€™m using is quite minimal:

type: custom:grid-layout
title: Grid layout
layout:
  grid-template-columns: 24% 23% 31% 22%
  grid-template-areas: |
    "c11 c12 c13 c14"
    "c21 c22 c23 c24"
cards:

To place the cards I use (where cxx is c11, c12, etc):

view_layout:
  grid-area: cxx

@thomasloven , need some help if you canā€¦

I am trying to figure out how to make my Dashboard 100% in width. I am new to Home Assistant and am asking for help with the Custom Layout Card or other alternatives.

Below is an image of my Dashboard that I setup rather quickly. I am primarily going to use it on a tablet, but would like it to auto adjust if I use it on y phone landscape or portrait. The Yellow separator lines / squiggles :slight_smile: represent the 3 Vertical Stacks I am currently using.

Any alternaltives?

Ultimately, when you resize the screen or turn portrait, I would like to see the bulbs first, followed by the Sensors, followed by the Plugs.

Is there a way to use layout-break in grid mode? Meaning you start with say 25% 50% 25% but then on a new row you go 33% 33% 33%

Hello guys,

Hopefully you can help me.
I am doing a new dashboard using the grid-layout, but I have some differences between what I see on my browser (PC) and on my iOS App.

Thie is the draft view seen from Firefox:

Thie is the draft view seen from iOS App:

I donā€™t understand why I have that big space between the first and the second card.

Here you can find my code:
title: Home 
views: 

  - title: Home
    path: home
    icon: 'mdi:home-roof'
    panel: false
    type: custom:grid-layout
    layout:
      grid-template-columns: 40% 40% 20%
      grid-template-rows: 100%
      grid-template-areas: |
        "overview . ."
        "navbar scene ."
        "test . ."
      mediaquery:
        "(max-width: 700px)":
          grid-template-columns: 100%
          grid-template-areas: |
            "overview"
            "navbar"
            "scene"
            "test"
        "(max-width: 1700px)":
          grid-template-columns: 50% 50%
          grid-template-areas: |
            "overview ."
            "navbar scene"
            "test ."
    badges: []
    cards:

### OVERVIEW          
      - type: vertical-stack
        view_layout:
          grid-area: overview
        cards:
          - type: markdown
            content: |
              # Home

            style:
              .: |
                ha-card {
                  --ha-card-background: none !important;
                  box-shadow: none !important;
                  height: 20px;
                }
              ha-markdown:
                $: |
                  h1 {
                    font-size: 20px;
                    font-weight: bold;
                    font-family: Helvetica;
                    letter-spacing: '-0.01em';
                  }
            
          - type: markdown
            content: |                                
              # La temperatura in casa ĆØ {{ states('sensor.daikin_sala_inside_temperature') | round(1) }}Ā°, mentre fuori ci sono {{states('sensor.openweathermap_temperature') | round(1) }}Ā°.
                
              {% if is_state('binary_sensor.stato_asciugatrice', 'on') %}# Asciugatrice accesa. {% else %} {% endif %} 

              {% if is_state('group.sensori_porta', 'on') %}# Il lucernaio e lo scurone sono aperti. {% elif is_state('binary_sensor.lucernaio_studio_contact', 'on') %}# Il lucernaio in studio ĆØ aperto. {% elif is_state('binary_sensor.scurone_sala_contact', 'on') %}# Lo scurone in sala ĆØ aperto. {% else %} {% endif %}
            style:
              .: |
                ha-card {
                  --ha-card-background: none !important;
                  box-shadow: none !important;
                  height: min(25vw, 100px);
                }
              ha-markdown:
                $: |
                  h1 {
                    font-size: 15px;
                    font-weight: bold;
                    font-family: Helvetica;
                    letter-spacing: '-0.01em';
                  }

### NAVBAR                         
      - type: vertical-stack
        view_layout:
          grid-area: navbar
        cards:
          - type: horizontal-stack
            cards:
              - type: 'custom:button-card' 
                icon: 'mdi:home-roof' # Change this to the icon you want to display
                show_icon: true
                show_name: false # Change to "true" if you need to show the Button name
                styles:
                  card:
                    - width: 60px
                    - height: 60px
                    - margin: 10px
                    - border-radius: 15px
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                        ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                        : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                        ]]]
                    - background-color: var(--primary-background-color)
                  icon:
                    - color: var(--paper-item-icon-active-color)
                state:
                  - value: 'on'
                    styles:
                      card:
                        - box-shadow: |
                            [[[ return states['sun.sun'].state == 'below_horizon'
                              ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                              : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                            ]]]
                      icon:
                        - color: var(--paper-item-icon-active-color)
                tap_action:
                  action: toggle
                  haptic: light
              - type: 'custom:button-card' 
                icon: 'mdi:floor-plan' # Change this to the icon you want to display
                show_icon: true
                show_name: false # Change to "true" if you need to show the Button name
                styles:
                  card:
                    - width: 60px
                    - height: 60px
                    - margin: 10px
                    - border-radius: 15px
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                        ? '-5px -5px 10px rgba(50, 50, 50, .2), 6px 6px 10px rgba(0, 0, 0, .08)'
                        : '-5px -5px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                        ]]]
                    - background-color: var(--primary-background-color)
                  icon:
                    - color: var(--primary-text-color)
                state:
                  - value: 'on'
                    styles:
                      card:
                        - box-shadow: |
                            [[[ return states['sun.sun'].state == 'below_horizon'
                              ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                              : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                            ]]]
                      icon:
                        - color: var(--paper-item-icon-active-color)
                tap_action:
                  action: navigate
                  navigation_path: /ndr-ui/rooms
                  haptic: light
              - type: 'custom:button-card' 
                icon: 'mdi:youtube-tv' # Change this to the icon you want to display
                show_icon: true
                show_name: false # Change to "true" if you need to show the Button name
                styles:
                  card:
                    - width: 60px
                    - height: 60px
                    - margin: 10px
                    - border-radius: 15px
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                        ? '-5px -5px 10px rgba(50, 50, 50, .2), 6px 6px 10px rgba(0, 0, 0, .08)'
                        : '-5px -5px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                        ]]]
                    - background-color: var(--primary-background-color)
                  icon:
                    - color: var(--primary-text-color)
                state:
                  - value: 'on'
                    styles:
                      card:
                        - box-shadow: |
                            [[[ return states['sun.sun'].state == 'below_horizon'
                              ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                              : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                            ]]]
                      icon:
                        - color: var(--paper-item-icon-active-color)
                tap_action:
                  action: navigate
                  navigation_path: /ndr-ui/media
                  haptic: light
              - type: 'custom:button-card'
                icon: 'mdi:server' # Change this to the icon you want to display
                show_icon: true
                show_name: false # Change to "true" if you need to show the Button name
                styles:
                  card:
                    - width: 60px
                    - height: 60px
                    - margin: 10px
                    - border-radius: 15px
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                        ? '-5px -5px 10px rgba(50, 50, 50, .2), 6px 6px 10px rgba(0, 0, 0, .08)'
                        : '-5px -5px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                        ]]]
                    - background-color: var(--primary-background-color)
                  icon:
                    - color: var(--primary-text-color)
                state:
                  - value: 'on'
                    styles:
                      card:
                        - box-shadow: |
                            [[[ return states['sun.sun'].state == 'below_horizon'
                              ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                              : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                            ]]]
                      icon:
                        - color: var(--paper-item-icon-active-color)
                tap_action:
                  action: navigate
                  navigation_path: /ndr-ui/sistema
                  haptic: light
                
### SCENE
      - type: horizontal-stack
        view_layout:
          grid-area: scene
        cards:
          - type: 'custom:button-card' 
            entity: sensor.pc # Change this to the entity you want to control
            icon: 'mdi:microsoft-windows'
            name: PC
            show_icon: true
            show_name: false # Change to "true" if you need to show the Button name
            styles:
              card:
                - width: 60px
                - height: 60px
                - margin: 10px
                - border-radius: 15px
                - box-shadow: |
                    [[[ return states['sun.sun'].state == 'below_horizon'
                      ? '-5px -5px 8px rgba(50, 50, 50, .2), 5px 5px 8px rgba(0, 0, 0, .08)'
                      : '-4px -4px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                    ]]]
                - background-color: var(--primary-background-color)
              icon:
                - color: var(--primary-text-color)
            state:
              - value: 'Online'
                styles:
                  card:
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                          ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                          : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                        ]]]
                  icon:
                    - color: var(--paper-item-icon-active-color)
            tap_action:
              action: call-service
              haptic: light
              service: switch.turn_on
              service_data:
                entity_id: switch.pc_studio

          - type: 'custom:button-card' 
            entity: script.casa_uscita # Change this to the entity you want to control
            icon: 'mdi:door-closed-lock'
            name: Esco
            show_icon: true
            show_name: false # Change to "true" if you need to show the Button name
            styles:
              card:
                - width: 60px
                - height: 60px
                - margin: 10px
                - border-radius: 15px
                - box-shadow: |
                    [[[ return states['sun.sun'].state == 'below_horizon'
                      ? '-5px -5px 8px rgba(50, 50, 50, .2), 5px 5px 8px rgba(0, 0, 0, .08)'
                      : '-4px -4px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                    ]]]
                - background-color: var(--primary-background-color)
              icon:
                - color: var(--primary-text-color)
            state:
              - value: 'Online'
                styles:
                  card:
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                          ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                          : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                        ]]]
                  icon:
                    - color: var(--paper-item-icon-active-color)
            tap_action:
              action: call-service
              service: script.uscita_casa
              haptic: light

          - type: 'custom:button-card' 
            entity: switch.cancello # Change this to the entity you want to control
            icon: 'mdi:gate'
            name: Cancello
            show_icon: true
            show_name: false # Change to "true" if you need to show the Button name
            styles:
              card:
                - width: 60px
                - height: 60px
                - margin: 10px
                - border-radius: 15px
                - box-shadow: |
                    [[[ return states['sun.sun'].state == 'below_horizon'
                      ? '-5px -5px 8px rgba(50, 50, 50, .2), 5px 5px 8px rgba(0, 0, 0, .08)'
                      : '-4px -4px 8px rgba(255, 255, 255, .5), 5px 5px 8px rgba(0, 0, 0, .03)';
                    ]]]
                - background-color: var(--primary-background-color)
              icon:
                - color: var(--primary-text-color)
            state:
              - value: 'Online'
                styles:
                  card:
                    - box-shadow: |
                        [[[ return states['sun.sun'].state == 'below_horizon'
                          ? 'inset -3px -3px 5px rgba(50, 50, 50, .5), inset 3px 3px 5px rgba(0, 0, 0, .3)'
                          : 'inset -3px -3px 5px rgba(255, 255, 255, .65), inset 3px 3px 5px rgba(0, 0, 0, .035)';
                        ]]]
                  icon:
                    - color: var(--paper-item-icon-active-color)
            tap_action:
              action: toggle
              haptic: light

Hello guys,

I try to center my grid vertically in order to create an aesthtically correct dashboard that will be displayed on a touch screen hanging on the wall in my living room.
Iā€™m asking for your help to know if itā€™s possible to do this to apply style to the ā€œgrid-layoutā€ element like I try with my browser inspector :

If you canā€™t see the picture, I put style attribute to the grid-layout element to center the grid in the middle of the page:

<grid-layout style="display: flex; justify-content: center; align-items: center">
#shadow-root (open)
...
</grid-layout>

I already try to use javascript and css but I didnā€™t succeed.

Thanks in advance for your help,
Damien

If you want to apply CSS style defintions you should use card-mod. The CSS in HA is not easy to work with, thatā€™s why a custom_component like card-mod eases the way to do so. :slight_smile:

Find it here:

@paddy0174
Thanks for your answer.

I also try to use card-mod but Iā€™m not sure how to use it to put my grid-layout element in the middle of my dashboard.
If I follow this way, I need to create a custom:mod-card where I put my existing grid, thatā€™s it ?

Ah thatā€™s what youā€™re after. Then `layout-cardĀ“ is enough. :wink:

Just use the vertical-layout and set the max_columns to 1. No need for CSS or anything else. :wink:

Here:

If you want to span this one column over the full width, use panel mode from HA views, see here:

Hey,

I tried this option but did not get the desired result.
In the end, I went to the layout-card javascript file to make my modification.

Thank you for your help.

Good itā€™s working for you, but I would never ever mess with files coming from a custom-card. :wink: This will be nightmare to track and modify changes or updatesā€¦

As I said above, this is nothing unusual, there are people out there that solved this. :slight_smile: So your use case is covered by the card, you just didnā€™t found the right way.

Good luck, I hope it works out for you! :slight_smile:

Iā€™ve just started trying to use Layout-card and Iā€™m having whatā€™s hopefully a simple problem - I canā€™t seem to get layout-break to work.

Hereā€™s my code:

  - title: Soil Moisture
    path: soil-moisture
    theme: ios-dark-mode
    type: custom:horizontal-layout
    cards:
      - type: gauge
        entity: sensor.bamboo_sensor_humidity
        name: Bamboo
        min: 0
        max: 100
      - type: custom:layout-break
      - type: gauge
        entity: sensor.corten_planter_e_humidity
        name: Corten Planter E
        min: 0
        max: 100
      - type: gauge
        entity: sensor.corten_planter_n_humidity
        name: Corten Planter N
        min: 0
        max: 100
      - type: custom:layout-break
      - type: gauge
        entity: sensor.corten_planter_sw_humidity
        name: Herbs S
        min: 0
        max: 100
      - type: gauge
        entity: sensor.herbs_sw_humidity
        name: Herbs SW
        min: 0
        max: 100
      - type: gauge
        entity: sensor.herbs_nw_humidity
        name: Herbs NW
        min: 0
        max: 100

Iā€™m trying to get a display with three rows: one item in the first row, two items in the second and three in the third.

In other words, a layout like this:

 Bamboo
 Corten Planter E        Corten Planter N
 Herbs S                 Herbs SW                  Herbs NW

(Not sure how to get rid of the blue on Bamboo)

Instead I get this:

And it edit view:

Itā€™s like the layout-break lines arenā€™t doing anything.

Any insights will be appreciated. Thanks!