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

Hi,

Yep the property ā€œalign-content: stretchā€ seems to have fixed mine too, thanks soo much for the help.

If I ever find another way will update u.

Thanks

The problem with using grid area is that everything has to be defined manually. Obviously this can be done, but if you wish to add one more button or media_player etc you have to re-configure all of your areas and media queries to match. Fine if youā€™ve got three buttons, slightly different if we are talking about 40 cards.

This way any card can be added and no other changes have to be made and it will just work, at any resolution.

For fixed cells, you can certainly create a fixed, ā€˜predictableā€™ area that will remain there until there are not suitable columns left. If you would like a fixed area to the left, add a fixed column/row number to your view_layout on that card:

bentogridtest2-ezgif.com-video-to-gif-converter

1 Like

This is awesome!!

I canā€™t tell you how grateful I am for this. Itā€™s incredibly well thought out. I downloaded your entire dashboard and replaced the individual button cards with your card mods.
With your help, Iā€™ve already made quite a bit of progress. However, I still have the problem that the bottom row is not visible, both on the labtop and on the tablet (Galaxy TabA7 with 2000x1200px), as can be seen in the screenshot (donā€™t be surprised why some are missing on the left, I just made them black, they are still there).
But I really would love to have 5 rows

And here is what one of the cards look like:

type: custom:button-card
icon: mdi:spotify
aspect_ratio: 1/1
tap_action:
  action: call-service
  service: media_player.select_source
  target:
    entity_id: media_player.android_fernseher_192_168_0_95
  data:
    source: Spotify
styles:
  card:
    - border-radius: 24px
    - background-color: var(--green)
  icon:
    - color: var(--black)
card_mod:
  style: |
    :host {
      height: 100% !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      position: unset !important;
      display: grid !important;
      }

1 Like

looking good!

One quick question - are you planning on using kiosk mode (aka no top or side nav bars)?

The issue is using an 8x5 grid on a 16:9 device.

Two ways to solve and get 5 rows:

  1. Play with padding on the sides of the grid to decrease size of all cells.
  2. Switch to using 9 columns.

Adding padding to each side with 8 cols:

Moving to 9 cols with a slight padding increase:

The main adjustments to play with are the min vw for columns and padding:

layout:
  place-items: stretch stretch
  height: 1fr
  min-height: 1fr
  margin: 0
  card_margin: 0
  padding: 18px 45px
  grid-template-columns: repeat(auto-fit, minmax(max(110px, 9vw), 2fr))
  grid-gap: 10px
  grid-auto-rows: 1fr
  grid-auto-flow: row dense

Let me know!

Iā€™m having trouble with the layout cards when trying to build a dash for a 800x1280 android tablet running the companion app.
No matter what Iā€™ve tried, I canā€™t get a 4th or 5th column to render, I just get any additional cards stacked below column 1 on the tabletā€¦ and usually in my desktop browser, too.
What Iā€™m trying to do is have one very narrow left column for navigation (to hopefully other views Iā€™ve built to be useful on this device), two columns worth of items relevant to the bedroom, and then a column or two of some general status stuff.

views:
  - title: Home
    type: custom:horizontal-layout
    layout_type: grid
    layout:
      max_cols: 5
      column_widths: 6.2% 32.5% 3fr 1fr 1fr
    badges: []
    cards:
      - square: true
        type: grid
        cards:
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:bed-king-outline
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:bunk-bed-outline
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:cctv
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:garage-lock
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:washing-machine
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:countertop-outline
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:hot-tub
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:yoga
          - show_name: true
            show_icon: true
            type: button
            tap_action:
              action: toggle
            icon: mdi:lightbulb-multiple
        columns: 1
      - type: vertical-stack
        cards:
          - type: horizontal-stack
            cards:
              - features:
                  - type: light-brightness
                  - type: light-color-temp
                type: tile
                entity: light.master_bedroom_left_nightstand_lamp
                show_entity_picture: false
                vertical: false
                name: ' '
                hide_state: true
              - features:
                  - type: light-brightness
                  - type: light-color-temp
                type: tile
                entity: light.master_bedroom_right_nightstand_lamp
                vertical: false
                name: ' '
                hide_state: true
          - type: vertical-stack
            cards:
              - type: vertical-stack
                cards:
                  - show_name: true
                    show_icon: false
                    type: button
                    tap_action:
                      action: call-service
                      service: switch.turn_on
                      data: {}
                      target:
                        entity_id: switch.master_bedroom_heated_blanket_master_preheat
                    entity: switch.master_bedroom_heated_blanket_master_preheat
                    icon: mdi:bed-king-outline
                    name: Preheat Whole Bed
                    icon_height: 30px
                    show_state: false
                    hold_action:
                      action: none
                  - type: horizontal-stack
                    cards:
                      - square: false
                        type: grid
                        cards:
                          - show_name: true
                            show_icon: true
                            type: button
                            tap_action:
                              action: toggle
                            entity: >-
                              switch.master_bedroom_heated_blanket_left_side_preheat
                            icon: ''
                            name: Preheat
                          - square: true
                            type: grid
                            cards:
                              - show_name: false
                                show_icon: true
                                type: button
                                tap_action:
                                  action: call-service
                                  service: select.select_previous
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                  data:
                                    cycle: false
                                icon: mdi:minus-circle-outline
                                hold_action:
                                  action: call-service
                                  service: select.select_first
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                  data: {}
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                    state_not: unknown
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                    state_not: unavailable
                                card:
                                  show_name: false
                                  show_icon: false
                                  show_state: true
                                  type: glance
                                  entities:
                                    - entity: >-
                                        select.master_bedroom_heated_blanket_left_side_heat_level
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                    state: unknown
                                card:
                                  show_name: false
                                  show_icon: true
                                  type: button
                                  tap_action:
                                    action: none
                                  entity: >-
                                    select.master_bedroom_heated_blanket_left_side_heat_level
                                  hold_action:
                                    action: more-info
                                  icon: mdi:alert
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                    state: unavailable
                                card:
                                  show_name: false
                                  show_icon: true
                                  type: button
                                  tap_action:
                                    action: none
                                  entity: >-
                                    select.master_bedroom_heated_blanket_left_side_heat_level
                                  hold_action:
                                    action: more-info
                                  icon: mdi:alert
                              - show_name: false
                                show_icon: true
                                type: button
                                tap_action:
                                  action: call-service
                                  service: select.select_next
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                  data:
                                    cycle: false
                                icon: mdi:plus-circle-outline
                                hold_action:
                                  action: call-service
                                  service: select.select_last
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_left_side_heat_level
                                  data: {}
                            columns: 3
                          - show_name: false
                            show_icon: true
                            type: button
                            tap_action:
                              action: call-service
                              service: switch.turn_off
                              data: {}
                              target:
                                entity_id: >-
                                  switch.master_bedroom_heated_blanket_left_side_power
                            entity: >-
                              switch.master_bedroom_heated_blanket_left_side_power
                            icon: mdi:radiator
                            show_state: false
                            hold_action:
                              action: call-service
                              service: script.heated_blanket_power_on
                              data:
                                heat_level_input: >-
                                  select.master_bedroom_heated_blanket_left_side_heat_level
                              target: {}
                        columns: 1
                      - square: false
                        type: grid
                        cards:
                          - show_name: true
                            show_icon: true
                            type: button
                            tap_action:
                              action: toggle
                            entity: >-
                              switch.master_bedroom_heated_blanket_right_side_preheat
                            icon: ''
                            name: Preheat
                          - square: true
                            type: grid
                            cards:
                              - show_name: false
                                show_icon: true
                                type: button
                                tap_action:
                                  action: call-service
                                  service: select.select_previous
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                  data:
                                    cycle: false
                                icon: mdi:minus-circle-outline
                                hold_action:
                                  action: call-service
                                  service: select.select_first
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                  data: {}
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                    state_not: unknown
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                    state_not: unavailable
                                card:
                                  show_name: false
                                  show_icon: false
                                  show_state: true
                                  type: glance
                                  entities:
                                    - entity: >-
                                        select.master_bedroom_heated_blanket_right_side_heat_level
                                      tap_action:
                                        action: call-service
                                        service: script.heated_blanket_power_on
                                        data:
                                          heat_level_input: >-
                                            select.master_bedroom_heated_blanket_right_side_heat_level
                                      hold_action:
                                        action: more-info
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                    state: unknown
                                card:
                                  show_name: false
                                  show_icon: true
                                  type: button
                                  tap_action:
                                    action: none
                                  entity: >-
                                    select.master_bedroom_heated_blanket_right_side_heat_level
                                  hold_action:
                                    action: more-info
                                  icon: mdi:alert
                              - type: conditional
                                conditions:
                                  - entity: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                    state: unavailable
                                card:
                                  show_name: false
                                  show_icon: true
                                  type: button
                                  tap_action:
                                    action: none
                                  entity: >-
                                    select.master_bedroom_heated_blanket_right_side_heat_level
                                  hold_action:
                                    action: more-info
                                  icon: mdi:alert
                              - show_name: false
                                show_icon: true
                                type: button
                                tap_action:
                                  action: call-service
                                  service: select.select_next
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                  data:
                                    cycle: false
                                icon: mdi:plus-circle-outline
                                hold_action:
                                  action: call-service
                                  service: select.select_last
                                  target:
                                    entity_id: >-
                                      select.master_bedroom_heated_blanket_right_side_heat_level
                                  data: {}
                            columns: 3
                          - show_name: false
                            show_icon: true
                            type: button
                            tap_action:
                              action: call-service
                              service: switch.turn_off
                              data: {}
                              target:
                                entity_id: >-
                                  switch.master_bedroom_heated_blanket_right_side_power
                            entity: >-
                              switch.master_bedroom_heated_blanket_right_side_power
                            icon: mdi:radiator
                            show_state: false
                            hold_action:
                              action: call-service
                              service: script.heated_blanket_power_on
                              data:
                                heat_level_input: >-
                                  select.master_bedroom_heated_blanket_right_side_heat_level
                              target: {}
                        columns: 1
                  - show_name: true
                    show_icon: false
                    type: button
                    tap_action:
                      action: call-service
                      service: switch.turn_off
                      data: {}
                      target:
                        entity_id: switch.master_bedroom_heated_blanket_master_power
                    entity: switch.master_bedroom_heated_blanket_master_power
                    name: Turn Blanket Off
                    icon: mdi:power-off
                    hold_action:
                      action: none
      - type: vertical-stack
        cards:
          - show_name: false
            show_icon: true
            type: button
            tap_action:
              action: navigate
              navigation_path: /lovelace/masterbedroomtv
            icon: mdi:television
            entity: media_player.sharp_aquos_lc_60le857u
            hold_action:
              action: call-service
              service: media_player.turn_off
              target:
                device_id: a574982bf082ef513d608a48fca1d39d
                entity_id: media_player.sharp_aquos_lc_60le857u
              data: {}
          - type: horizontal-stack
            cards:
              - show_name: true
                show_icon: true
                type: button
                tap_action:
                  action: toggle
                icon: mdi:microsoft-xbox
              - show_name: true
                show_icon: true
                type: button
                tap_action:
                  action: toggle
                icon: mdi:nintendo-switch
              - show_name: true
                show_icon: true
                type: button
                tap_action:
                  action: toggle
                icon: mdi:sony-playstation
          - type: media-control
            entity: media_player.apple_tv_master_bedroom
      - type: vertical-stack
        cards:
          - type: history-graph
            entities:
              - sun.sun

I also tried the grid layout, but all I could achieve was either everything in one full-width column in order, or everything just on top of each other. No config example because I already gave up.

Any thoughts on what Iā€™m doing wrong with the horizontal view?

remove any columns:* on your cards and then try this as your layout:

type: custom:grid-layout
layout:
  height: 1fr
  min-height: 1fr
  margin: 0
  card_margin: 0
  padding: 0
  grid-template-columns: 6.2% 32.5% repeat(auto-fit, minmax(50px, 1fr)
  grid-auto-rows: 1fr
  grid-auto-flow: column

Thanks! That did it!

1 Like

thanks! After the layout and the cards, I will also work a bit with color palettes and hopefully make it a little nicer. Since I spent the last day working on the designs and functions of each card, I also realized that I will need more of then. Thatā€™s why Iā€™m clearly going with point 2 and taking 8 columns :slight_smile: Iā€™m really confident that it could be pretty cool and more or less unique. Thanks again for your help and of course I will keep you updated

1 Like

Hi, is it possible to align the cards in a horizontal-card to the left?

So the 9 columns worked really well. It now fits perfectly on my tablet. Iā€™ve also made a lot of progress and am currently working on the cards. I would like to display some cards, such as the volume buttons, new light button cards, etc., with condition cards only when music is playing, for example. This makes the whole dashboard more lively/organic and there is also more space for more buttons. However, as you have already shown above, some cards should be fixed, otherwise the condition cards would create too much chaos and also to allow better orientationā€¦ I just donā€™t quite understand what you meant. Can you perhaps show me using the following card as an example?

type: custom:button-card
icon: hue:logo
aspect_ratio: 1/1
show_name: false
entity: light.hue
tap_action:
  action: toggle
hold_action:
  action: more-info
styles:
  card:
    - border-radius: 24px
    - background-color: |
        [[[
          if (states['light.hue'].state == 'on') return 'var(--yellow)';
          return 'var(--red)';
        ]]]
  icon:
    - color: var(--black)
card_mod:
  style: |
    :host {
      height: 100% !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      position: unset !important;
      display: grid !important;
      }

PS: Iā€™m attaching you a screenshot of the current progress

Thanks again!

1 Like

Looking good!

To ā€˜fixā€™ cards, you can use the below on any card that you want to position exactly:

view_layout:
  grid-column: 1 / 3
  grid-row: 3 / 6

If this was added, the card would start in the first column and span 3 columns (1 / 3).
The card would start in row 3 and span 3 rows (3 / 6).

So if you wanted your hue card to always remain in the position in your screenshot you could use the following (you donā€™t need to specify spans as you are only taking up one cell in your grid):

view_layout:
  grid-column: 3
  grid-row: 2
Full Button-Card Code
type: custom:button-card
view_layout:
  grid-column: 3
  grid-row: 2
icon: hue:logo
aspect_ratio: 1/1
show_name: false
entity: light.hue
tap_action:
  action: toggle
hold_action:
  action: more-info
styles:
  card:
    - border-radius: 24px
    - background-color: |
        [[[
          if (states['light.hue'].state == 'on') return 'var(--yellow)';
          return 'var(--red)';
        ]]]
  icon:
    - color: var(--black)
card_mod:
  style: |
    :host {
      height: 100% !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      position: unset !important;
      display: grid !important;
      }
1 Like

and again we are one step closer to the goal :slight_smile: I will use it directly this evening. Thank you

1 Like

on a type: panel view I am look go for a way to conditionally show a card in a stack, and hoped to use layout card option visibility GitHub - thomasloven/lovelace-layout-card: šŸ”¹ Get more control over the placement of lovelace cards.

however, no matter what I try, any card is simply displayed, as if no mediaquery is set at allā€¦

even a direct c&p of the example (even upped the px count to be sure it hides on my mobile phone) shows on my desktop or mobile no matter what

- type: markdown
  content: |
    This is only shown on screens more than 1200 px wide
  view_layout:
    show:
      mediaquery: "(min-width: 1200px)"

is this no longer functional? Or should extra config options be set first for this to be functional?

Thisnis the beginning of that panel, and as you can see Ive added the markdown inside the stack. the conditional below it, using the same pixel cut, works perfectly:

title: Cameras buiten
path: cameras_buiten
type: panel
icon: cli:home-video-outline
cards:

  - type: vertical-stack
    cards:

      - type: markdown #this shows always, no matter what
        content: |
          This is only shown on screens more than 1200 px wide
        view_layout:
          show:
            mediaquery: "(min-width: 1200px)"

      - type: conditional # this actually works....
        conditions:
          - condition: screen
            media_query: '(min-width: 1200px)'
        card:
          type: grid
etcetc

I also tried it with that markdown only, to rule out it was caused by the vertical-stack, but still does not work:

title: Cameras buiten
path: cameras_buiten
type: panel
icon: cli:home-video-outline
cards:

  - type: markdown
    content: |
      This is only shown on screens more than 1200 px wide
    view_layout:
      show:
        mediaquery: "(min-width: 1200px)"

please have a look, thx

Iā€™m not seeing you declare the layout card anywhere.

Media queries donā€™t work with the core dashboard view settings you are using there I donā€™t think. They only work within a custom layout, either used at the view level, or as a card.

youā€™re right, I didnā€™t.
Tbh, I figured it would be a system variable of sorts after having the card installed, just like we can use custom: gap-card anywhere without anything further

now doing this:

title: Cameras buiten
path: cameras_buiten
type: custom:grid-layout #panel
layout:
  margin: 0px
icon: cli:home-video-outline
cards:

#   - type: vertical-stack
#     cards:

#       - type: conditional
#         conditions:
#           - condition: screen
#             media_query: '(min-width: 1200px)'
#         card:
  - type: grid
    view_layout:
      show:
        mediaquery: "(min-width: 1200px)"
    columns: 2
    square: false
    cards: &outside_cameras
    etc etc

  - type: vertical-stack
    view_layout:
      show:
        mediaquery: "(max-width: 1200px)"
#           type: grid
#           columns: 1
#           square: false
    cards: *outside_cameras

and that works fine. @basbrus helped me out in Discord, thx again.
in another view, I can eve do this now, and set the mediaquery on a conditional

  - type: conditional
    <<: &min_width
      view_layout:
        show:
          mediaquery: "(min-width: 1200px)"
    conditions: &privacy_off
      - condition: state
        entity: switch.inside_wifi_cameras_privacy_mode
        state: 'off'
#       - condition: screen
#         media_query: '(min-width: 1200px)'
    card:
      type: grid
      columns: 2
      square: false
      cards: &inside_wifi_cameras

aware we can also do that with core conditional, but then we need yet another container card around thatā€¦

Hi
How can I make a part of a grid to have scroll and other part no scroll wich fit the size of the screen ?
At the moment, height: 100% not work as excepted. Also, do overflow: hidden continue to show a scrollbar. Maybe itā€™s CSS class parent but I donā€™t how how to do.

Hello
I am trying to vertically center a card within the 2nd row of a fixed-height layout-card grid (in the below example my row height is 400px and the entity card should be centered on 200px). Reading the CSS docs it looks like I need to use ā€˜align-self: centerā€™ but I cannot get this to work.

  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: auto
      grid-template-rows: 400px 400px
      grid-template-areas: |
        "a1"
        "a2"
    cards:
      - type: custom:mushroom-entity-card
        entity: person.administrator
        style: "ha-card { align-self: center; }"
        view_layout:
          grid-area: a2

Hi @aldersp Iā€™m trying to do something similar, also with no success at all.

Iā€™ve got a basic layout that will eventually look like a top-down view of my car.

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  grid-template-areas: |
    "boot carrl carfl hood"
    "boot carrr carfr hood"

No matter how hard I try, I canā€™t get any custom buttons in grid-area boot (or hood) to show across two rows.
image

Hi @jfitzellā€¦ I worked out the solution to my problemā€¦ it may help you as well. The key was to use place-self or place-items with two parameters. The first being start/center/end for v-alignment and the second being left/center/right/stretch for h-alignment.

  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      #
      # Use the next place-items for grid settings (all cells) or place-self
      # in view_layout of card section (see below) for individual cell layout.
      # Wrap in vertical-stack or horizontal-stack to group multiple cards within cell.
      #
      #place-items: center stretch
      #
      # Use -ve margins to use full column width
      margin: 0 -4px 0 -4px
      grid-template-columns: auto
      grid-template-rows: 400px 400px
      grid-template-areas: |
        "a1"
        "a2"
    cards:
      - type: custom:mushroom-entity-card
        entity: person.administrator
        view_layout:
          grid-area: a2
          place-self: center stretch