How to make a picture element card fits the screen?

Hi everyone:

I’d trying to make my picture element card fits the screen in respect to aspect ratio. My picture element card is 4:3, at the moment it always fills the width and give a scroll bar for height. Is there a way to make it fits the screen by looking at height first and calculate the needed width?
Below is the code, at the moment I have to give hard-coded max-width and max-height, but it’s far from perfect:

type: picture-elements
image: /local/floorplan/transparent.png?version=F00CBEDA34B4711C8F5B7C8057BAB745
elements: !include_dir_merge_list floor-plan/
card_mod:
  style: |
    ha-card {
      max-width: 1200px;
      max-height: 900px;
      margin: auto;
    }

The PE is inside a vertical stack and dashboard has panel mode.

Many thanks in advance!

Try this:

    type: picture-elements
    image: /local/floorplan/transparent.png?version=F00CBEDA34B4711C8F5B7C8057BAB745
    elements: !include_dir_merge_list floor-plan/
    card_mod:
      style:
        hui-image:
          $: |
            #image {
              aspect-ratio: 4/3;
              object-fit: contain;
              vertical-align: middle;
              height: 900px; # perhaps this needs to be somehow fine-tuned to fit height oof your screen
            }
1 Like

Thanks! Unfortunately doesn’t work for me:

  1. With height reach the limit, the width keeps increasing and the picture is clipped by height
  2. All elements on PE also moves irrespect of the relative location on picture…

Are you sure that exactly the card itself is 4:3, not a display?

Below a proposal in case you have a 4:3 display.
Assume your display 1600x1200 (4:3).
4:3 = 1.33333.
Try using an image with another dimension: width should be bigger than 1600px (let it be 2000px, it will be downsized to fit in the “view area”), height should be smaller than 2000/1.333=1500 (since a “view area” has a different aspect ratio).

Of course they will since positions are set dependently on a card’s dimensions.
You should FIRST set a background image (and thus set a card’s dimension), then allocate elements.
Google “picture elements small tutorial” → 1st post → read about positioning, might be useful.

Hi thanks for your reply!
The image I used is rendered floor3d and it is 4:3 ratio so I can fit the whole house.
The issue is, on all devices, it prioritise the width, hence for wide screen there is a scroll bar for the height.
I don’t know if it’s because the way how panel layout/vertical stack work. I’m hoping there is a way to make height 100% and width to be calc based on height.
Alternatively I could set fixed size based on media query, not sure if I can query for usable height of the screen though.

Forgot to mention: the picture for the PE card is just a placeholder, and I then use picture elements to overlay floor plan and lights. So applying css on img only affect the transparent.png i guess

Try resizing the width as wax suggested. Add blank transparent horizontal marking if needed in Photoshop.

Try again:

type: picture-elements
image: /local/attic.png
elements:
  - type: icon
    icoon: mdi:lightbulb
card_mod:
  style:
    hui-image:
      $: |
        #image {
          aspect-ratio: 4/3;
          object-fit: contain;
          vertical-align: middle;
          height: 95vh;
        }

height: 95vh relates to % of vertical size of the viewing window in browser. If set to 100vh will take whole height, but as HA has its own tab bar at top it already its some pixel. That’s why I use 95vh. To be precise you should use 100vh - Xpx, where x is size of top+ bottom borders in pixels you want to exclude.

I’ve been working on this and have it somewhat working using a 1 column grid card with card-mod from HACS. Home Assistant scales based on width. This code will scale based on height if the ratio of height to width goes below a preset ratio. I had to account for menu bars and display on a phone screen also, so there are 3 different ratios. The only problem to still solve, is that when Home Assistant scales based on width, it does not scale the icons. When this code scales based on height, it DOES scale the icons. You might not notice unless you are scaling to an extreme degree.


path: default_view
title: House
panel: true
badges: []
cards:
  - type: grid
    square: false
    columns: 1
    cards:
      - type: picture-elements
        image: /local/FloorPlans-SitePlan_NoNBackground.png
        card_mod:
          style: >

            ha-card {
              transform-origin: top left;
            }


            /* Wide screens:  Top bar (58px) & sidebar (260px) visible 
                Adjust 0.79 ratio to a value appropriate for you picture file */

            @media (min-width: 870px) {
              ha-card {
                --verticalscalefactor: calc((100vh - 58px) / (100vw - 260px) / 0.79);
              }
            }


            /* Narrow screens OR sidebar collapsed: no 260px sidebar */

            @media (max-width: 869px) {
              ha-card {
                --verticalscalefactor: calc((100vh - 58px) / 100vw / 0.79);
              }
            }


            /* iPhone (or small touch device) in LANDSCAPE */

            @media (pointer: coarse) and (hover: none) and (orientation:
            landscape) {
              ha-card {
                --verticalscalefactor: calc((100vh - 165px) / (100vw - 354px) / 0.75);
              }
            }


            /* Apply the scale using whatever factor is in effect */

            ha-card {
              transform: scale(min(1, var(--verticalscalefactor)));
            }
        elements:
          - type: state-icon
            entity: sensor.lpg_100lb_tank_1_level
            title: LPG Tank 1 Level
            tap_action:
              action: toggle
            style:
              top: 49%
              left: 89.7%
              transform: translate(-50%, -50%) scale(.75, .75)
          - type: state-label
            entity: sensor.lpg_100lb_tank_1_level
            title: LPG Tank 1 Level
            style:
              top: 49%
              left: 95.5%
              font-size: 11px
              transform: translate(-50%, -50%)