Using Layout Card for a fixed layout on tablet

I’m trying to use a combination of layout-card, custom button card, atomic calendar, and clock-weather-card, kiosk mode (to hide the menu, but leave navigation at top) to make a display to use on my tablets, but am running into some issues getting everything to line up.

My end goal is to have the views at the top, then below that a row of “chip” like cards centered in the middle, then below that have 2 main columns (say 50/50). The left column will have a clock-weather-card at the top, and then atomic calendar revive filling up the rest of the display, and on the right 2 columns of “room cards” that are scaled to fill the height.

Kind of like this, (sorry my art skills suck)


-----------------------------------------------------------------------------
| NAVIGATION                                                                |
-----------------------------------------------------------------------------
|                                      CHIPS                                |
----------------------------------------------------------------------------|
|                                          |                 |              |
|        CLOCK/WEATHER                     |        ROOM 1   |   ROOM 2     |
-------------------------------------------|                 |              |
|                                          | -------------------------------|
|                                          |                 |              |
|                                          |      ROOM 3     |   ROOM 4     |
|          CALENDAR                        |                 |              |
|                                          | -------------------------------|
|                                          |                 |              |
|                                          |    ROOM 5       |     ROOM 6   | 
|                                          |                 |              |
|                                          | -------------------------------|
|                                          |                 |              |
|                                          |    ROOM 7       |     ROOM 8   | 
|                                          |                 |              |
|----------------------------------------------------------------------------

Currently I have

views:
  - title: Overview
    type: custom:grid-layout
    path: overview
    layout:
      grid-template-columns: 50vw 50vw
      grid-template-rows: min-content auto
      grid-template-areas: |
        "header-buttons header-buttons"
        "main-left main-right"
      height: calc(100vh - 60px)
      margin: 0px 0px 0px 0px
      card_margin: 0px 0px 0px 0px
      padding: 0px 0px 0px 0px
    cards:
      # CHIPS
      - type: custom:layout-card
        layout_type: custom:grid-layout
        view_layout:
          grid-area: header-buttons
        layout:
          grid-template-columns: auto
          grid-template-rows: auto
          height: 100%
          place-content: end center
        cards:
          - type: horizontal-stack
            cards:
              - type: "custom:button-card"
                template: chip_icon_label
                label: Label
                icon: "mdi:heart"
              - type: "custom:button-card"
                template: chip_icon_label
                label: Label
                icon: "mdi:heart"
              - type: "custom:button-card"
                template: chip_icon_label
                label: Label
                icon: "mdi:heart"
              - type: "custom:button-card"
                template: chip_icon_label
                label: Label
                icon: "mdi:heart"
              - type: "custom:button-card"
                template: chip_icon_label
                label: Label
                icon: "mdi:heart"
      # LEFT
      - type: custom:layout-card
        layout_type: custom:grid-layout
        view_layout:
          grid-area: main-left
        layout:
          grid-template-columns: auto
          grid-template-rows: min-content 1fr
          height: 100%
        cards:
          - type: custom:clock-weather-card
            entity: weather.accuweather_accuweather
            title: Home
          - type: "custom:atomic-calendar-revive"
            entities:
              - entity: calendar.test
                name: "Test"
      # RIGHT
      - type: custom:layout-card
        layout_type: custom:grid-layout
        view_layout:
          grid-area: main-right
        layout:
          grid-template-columns: 50% 50%
          grid-template-rows: auto
          height: 100%
        cards:
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps
          - type: "custom:button-card"
            name: Room
            icon: mdi:sofa-outline
            entity: switch.lamps

Which is close, but the atomic calendar isn’t limiting itself to the screen and is flying off the bottom of the screen.

Any help appreciated.

Have you tried constructing a grid with a vertical stack card, each level in the stack being either a horizontal stack or a grid card? Cards will scale themselves according to the number in each horizontal layer.

This approach has the added advantage that you can use panel mode in the dashboard because everything in enclosed in a single card.

This one uses several conditional cards, so that when there is no severe weather warning, for example, the media player expands to cover two-thirds of the screen. In the panel on the right, if there is anything in the calendar for tomorrow, it will replace the “chance of rain” card.

I haven’t tried that. I guess I could, I just don’t really understand what isn’t working with doing it this way. It should be a css grid with the outer most height 100vw-60px (for the bar). And if all of the internal grids use height 100% (relative to the outer one)… it should work, but something just isn’t and I can’t figure out why.

Seems like if I use button card it works, so there is something about atomic calendar revive that isn’t filling the container, but rather extending it,

Is there any possibility of sharing your code so others can try it out and learn from it? For the past month, I have been trying various methods. But I found side effects of your method of panel mode and stack cards. They display differently on various displays. To correct this, I have had to create a dashboard for each display so that each display is selected by which user account is logged into.

views:
  - title: Ground
    type: sidebar
    subview: false
    theme: grey_panels
    badges: []
    cards:
      - type: horizontal-stack
        cards:
          - type: vertical-stack
            cards:
              - type: tile
                entity: input_boolean.kitchen_lights
                name: Kitchen
                icon: mdi:led-strip-variant
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: '#becbf1'
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('input_boolean.kitchen_lights', 'on') %}
                      --ha-card-background: #364366;
                    {% endif %} 
                      }      
              - type: tile
                entity: light.study_spotlights
                icon: mdi:track-light
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: '#becbf1'
                tap_action:
                  action: toggle
                name: Study
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('light.study_spotlights', 'on') %}
                      --ha-card-background: #364366;
                    {% endif %} 
                      } 
              - type: tile
                entity: switch.living_room_socket_5
                name: TV
                icon: mdi:television
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: green
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('switch.living_room_socket_5', 'on') %}
                      --ha-card-background: #2f4e28;
                    {% endif %} 
                      }
              - type: tile
                entity: switch.study_socket_2
                name: Xbox
                icon: mdi:microsoft-xbox
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: green
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('switch.study_socket_2', 'on') %}
                      --ha-card-background: #2f4e28;
                    {% endif %} 
                      }
              - show_name: false
                show_icon: false
                type: button
                tap_action:
                  action: none
                theme: transparent_button
                hold_action:
                  action: none
          - type: vertical-stack
            cards:
              - type: tile
                entity: switch.all_living_room_lights
                icon: mdi:floor-lamp-torchiere-variant
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: '#becbf1'
                tap_action:
                  action: toggle
                name: Front
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('switch.all_living_room_lights', 'on') %}
                      --ha-card-background: #364366;
                    {% endif %} 
                      }
              - type: tile
                entity: light.bedroom_socket_3
                name: Bedroom
                icon: mdi:lamp
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: '#becbf1'
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('light.bedroom_socket_3', 'on') %}
                      --ha-card-background: #364366;
                    {% endif %} 
                      }
              - type: tile
                entity: switch.study_socket_3
                name: Acer
                icon: mdi:desktop-classic
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: green
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('switch.study_socket_3', 'on') %}
                      --ha-card-background: #2f4e28;
                    {% endif %} 
                      }
              - type: tile
                entity: light.study_socket_1
                name: Dell
                icon: mdi:desktop-tower
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: green
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('light.study_socket_1', 'on') %}
                      --ha-card-background: #2f4e28;
                    {% endif %} 
                      }
          - type: vertical-stack
            cards:
              - type: tile
                entity: alarm_control_panel.alarmo
                name: Alarm
                color: red
                card_mod:
                  style: |
                    ha-card { 
                      {% if not is_state('alarm_control_panel.alarmo', 'disarmed') %}
                      --ha-card-background: #6c1919;
                    {% endif %} 
                      } 
              - type: conditional
                conditions:
                  - condition: state
                    entity: binary_sensor.window_open
                    state: 'off'
                card:
                  type: tile
                  entity: binary_sensor.window_open
                  name: Windows
                  tap_action:
                    action: none
                  icon_tap_action:
                    action: none
              - type: conditional
                conditions:
                  - condition: state
                    entity: binary_sensor.window_open
                    state: 'on'
                card:
                  type: tile
                  entity: binary_sensor.window_open
                  name: Window
                  color: red
                  tap_action:
                    action: none
                  icon_tap_action:
                    action: none
                  card_mod:
                    style: |
                      ha-card { 
                        {% if is_state('binary_sensor.window_open', 'on') %}
                        --ha-card-background: #6c1919;
                      {% endif %} 
                        }
              - type: tile
                entity: climate.hallway
                name: Hallway
                state_content: current_temperature
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state_attr('climate.hallway', 'hvac_action', 'heating') %}
                      --ha-card-background: #6c5419;
                    {% endif %} 
                      }
              - type: tile
                color: orange
                hide_state: false
                state_content: current_temperature
                entity: climate.study
                name: Study
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state_attr('climate.study', 'hvac_action', 'heating') %}
                      --ha-card-background: #6c5419;
                    {% endif %} 
                      }
          - type: vertical-stack
            cards:
              - type: tile
                entity: input_boolean.away_mode
                name: Away
                color: red
                hide_state: true
                tap_action:
                  action: none
                icon_tap_action:
                  action: none
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('input_boolean.away_mode', 'on') %}
                      --ha-card-background: #6c1919;
                    {% endif %} 
                      }
              - type: conditional
                conditions:
                  - condition: state
                    entity: binary_sensor.door_open
                    state: 'off'
                card:
                  type: tile
                  entity: binary_sensor.door_open
                  name: Doors
                  tap_action:
                    action: none
                  icon_tap_action:
                    action: none
              - type: conditional
                conditions:
                  - condition: state
                    entity: binary_sensor.door_open
                    state: 'on'
                card:
                  type: tile
                  entity: binary_sensor.door_open
                  name: Door
                  color: red
                  tap_action:
                    action: none
                  icon_tap_action:
                    action: none
                  card_mod:
                    style: |
                      ha-card { 
                        {% if is_state('binary_sensor.door_open', 'on') %}
                        --ha-card-background: #6c1919;
                      {% endif %} 
                        }
              - type: tile
                color: orange
                hide_state: false
                entity: climate.living_room
                name: Front
                state_content: current_temperature
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state_attr('climate.living_room', 'hvac_action', 'heating') %}
                      --ha-card-background: #6c5419;
                    {% endif %} 
                      }
              - type: tile
                entity: input_boolean.heating_boost
                name: Boost
                icon: mdi:radiator
                vertical: false
                show_entity_picture: false
                hide_state: true
                color: orange
                tap_action:
                  action: toggle
                card_mod:
                  style: |
                    ha-card { 
                      {% if is_state('input_boolean.heating_boost', 'on') %}
                      --ha-card-background: #6c5419;
                    {% endif %} 
                      }
      - type: horizontal-stack
        cards:
          - type: custom:sonos-card
            sections:
              - player
              - media browser
              - groups
            entityId: media_player.bedroom
            widthPercentage: 100
            topFavorites:
              - ''
            hideBrowseMediaButton: false
            mediaBrowserShowTitleForThumbnailIcons: false
            hideGroupCurrentTrack: false
            dynamicVolumeSlider: false
            mediaBrowserItemsPerRow: 1
            heightPercentage: 58
            entities: []
          - type: conditional
            conditions:
              - condition: state
                entity: sensor.weather_alerts
                state_not: '0'
            card:
              type: markdown
              card_mod:
                style:
                  .: |
                    ha-card {
                      --mdc-icon-size: 40px;
                    }
                  ha-markdown:
                    $: |
                      td {
                        vertical-align: top;
                      }
              content: |
                {% if state_attr('sensor.weather_alerts','entries') != 0 %}
                  {% for item in state_attr('sensor.weather_alerts','entries') %}
                    {% for type, icon in [('rain', 'weather-pouring'), ('thunderstorms', 'weather-lightning-rainy'),
                                          ('wind', 'weather-windy'), ('snow', 'weather-snowy-heavy'), ('snow, ice', 'weather-snowy-heavy'), 
                                          ('lightning', 'weather-lightning'), ('ice', 'car-traction-control'),
                                          ('fog', 'weather-fog'), ('extreme heat', 'weather-sunny-alert'), ('thunderstorm', 'weather-lightning')] if type == item.summary | regex_findall_index('.*warning of (.*) affecting.*', ignorecase=True) %}
                      {% set color = item.summary.split(' ')[0] %}
                      {% set summary = item.summary | regex_findall_index('(.*) affecting South West England: (.*) valid from (.*) to (.*)', ignorecase=True) %}
                      {% set time_from = as_timestamp(strptime(summary[2], "%H%M %a %d %b")) | timestamp_custom("%H:%M %d/%m") %}
                      {% set time_to = as_timestamp(strptime(summary[3], "%H%M %a %d %b")) | timestamp_custom("%H:%M %d/%m") %}
                | | | |
                | --- | --- | --- |
                | <font color = {%- if 'Yellow' == color %}'gold'
                                {%- elif 'Amber' == color %}'darkorange'
                                {%- else %}'firebrick'
                                {%- endif %}><ha-icon icon={{ "'mdi:" + icon + "'" }}></ha-icon></font> | | **{{ summary[0] | title }}**<br />{{ time_from }} - {{ time_to }}<br />{{ summary[1] }} |
                    {% endfor %}
                  {% endfor %}
                {% endif %}
      - type: custom:vertical-stack-in-card
        cards:
          - show_current: true
            show_forecast: true
            type: weather-forecast
            entity: weather.tomorrow_io_albert_street_daily
            forecast_type: hourly
          - type: conditional
            conditions:
              - condition: state
                entity: input_text.calendar_event
                state: No reminders
            card:
              type: entity
              entity: sensor.chance_of_rain
              unit: '%'
          - type: conditional
            conditions:
              - condition: state
                entity: input_text.calendar_event
                state_not: No reminders
            card:
              show_name: false
              show_icon: false
              show_state: true
              type: glance
              entities:
                - entity: input_text.calendar_event
          - type: entities
            entities:
              - entity: binary_sensor.online
                name: Internet
          - graph: line
            type: sensor
            detail: 1
            entity: sensor.speedtest_download
            name: Download speed
          - type: glance
            show_name: false
            show_icon: false
            show_state: true
            entities:
              - entity: sensor.today
          - type: custom:simple-clock-card
            use_military: true
            hide_seconds: true
            bold_clock: false
            font_size: 5rem
            paddingLeft_size: 32px
            paddingRight_size: 32px
            paddingTop_size: 10px
            paddingBottom_size: 32px
            view_layout:
              position: sidebar
        view_layout:
          position: sidebar
1 Like

Thanks! Very impressive. I will enjoy learning from your detailed example :smile:

@Stiltjack - Thanks for sharing, I too have been struggling to make a dashboard that would flow well. I will be studying your example!