Skip to content

View Backgrounds

UIX can display a full-screen camera stream, video, or image as a background behind your Home Assistant dashboard views and config panels. The background is controlled entirely through CSS variables set in your theme and supports Jinja2 templates, so you can switch sources per view without any custom code.

How it works

The ha-drawer styling patch also controls the view background, which allows the feature to work in dashboard views and config panels. Variables must be set on :host inside the uix-drawer theme key so they are readable via getComputedStyle(ha-drawer). Because ha-drawer persists across navigation, the background element is reused when navigating between views with the same / video / image — no teardown/recreate cycle.

CSS variables

Variable Description
--uix-view-background-camera-entity Camera entity ID — UIX renders a muted ha-camera-stream which manages all stream connection and any authentication.
--uix-view-background-image-entity Any entity with entity_picture — UIX manages any URL authentication and renders a cover-sized background image
--uix-view-background-video Plain video URL — UIX renders a <video autoplay muted loop playsinline>
--uix-view-background-image Plain image URL — UIX renders a cover-sized CSS background-image
--uix-view-background Full CSS background shorthand value — applied directly to the background div; user is responsible for url(), sizing, positioning, etc.
--uix-view-background-cover view (default) or full — controls viewport coverage (see below)
--uix-camera-position Camera background position keyword — center (default), top, bottom, left, right, top-left, top-right, bottom-left, bottom-right
📷 --uix-camera-zoom Scale factor — values greater than 1 zoom in, less than 1 zoom out.
📷 --uix-camera-pan-x Horizontal shift. Accepts any CSS length or percentage. Positive values move the stream right (showing more of the left side of the camera).
📷 --uix-camera-pan-y Vertical shift. Accepts any CSS length or percentage. Positive values move the stream down (showing more of the top of the camera).

📷 The camera CSS zoom and pan CSS variables can be set either on :host inside uix-drawer or inside uix-view-background. See camera positioning and camera zoom and pan.

Priority order: camera-entityimage-entityvideoimagebackground. All five slots can be active simultaneously as independent layers.

Tip

You don't need to include url() around any of the camera entity, image entity, video or image CSS variables to use view backgrounds. url() will be added if and when required. You DO need to provide if you are using --uix-view-background.

Coverage modes

The --uix-view-background-cover variable controls how much of the viewport the background fills.

Value Description
view (default) Background fills only the content area — offset below the top bar (--header-height) and to the right of the sidebar. The offset adjusts automatically when the sidebar is resized or toggled. NOTE: For any config panels like developer tools which have double header height, the view will not compensate beyond --header-height.
full Background fills the entire viewport, sitting behind the top bar and sidebar.

Basic examples

Camera stream background

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      --uix-view-background-cover: view;
    }
  uix-view-background: |
    :host { opacity: 0.7; }

Video background

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-video: /local/background.mp4;
      --uix-view-background-cover: full;
    }
  uix-view-background: |
    :host { opacity: 0.5; }

Image background

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-image: /local/background.jpg;
      --uix-view-background-cover: view;
    }

Background shorthand

Use --uix-view-background when you need the full CSS background shorthand — gradients, multiple images, url() with sizing and positioning all in one value. You are responsible for the complete value.

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background: url('/local/background.jpg') center / cover no-repeat;
      --uix-view-background-cover: full;
    }

Gradients work equally well:

  uix-drawer: |
    :host {
      --uix-view-background: linear-gradient(135deg, #0d1b2a 0%, #1b263b 100%);
    }

Switching per view with templates

As the uix-drawer style supports Jinja2 templates and the panel template variable reflects the current view, you can switch the background source automatically:

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      {%- if panel.viewUrlPath == 'garage' -%}
      --uix-view-background-camera-entity: camera.garage
      {%- elif panel.viewUrlPath == 'driveway' -%}
      --uix-view-background-camera-entity: camera.driveway
      {%- endif -%};
      --uix-view-background-cover: view;
    }

See Templates for full template variable documentation.

Use template debug to check variables

To check what panel variables are available for your template, you can use a template in your theme with UIX debug and a CSS comment. Look for UIX: Template updated in your Browser console and drill down to variables and then panel.

uix-drawer: |
  {# uix.debug #}
  {{ '/* testing */' }}

Styling the background with uix-view-background

UIX styling for the view background is available using the theme variables uix-view-background. This lets you style the background content using the uix-view-background theme key — exactly like any other UIX theme target.

Common uses include opacity, grayscale, blur, and brightness:

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
    }
  uix-view-background: |
    :host {
      opacity: 0.6;
      filter: grayscale(30%) blur(2px);
    }

If you wish to adjust position or other attributes of the view background you can adjust the host container display parameters and also the displayed element. The displayed element will be per the table below.

Type Element
Camera entity ha-camera-stream
Entity image div.uix-bg-image
Video video
Image div.uix-bg-image
Background shorthand div.uix-bg-image

Camera positioning

Camera backgrounds are centred by default — the stream fills the container and any aspect-ratio overflow is clipped symmetrically on all sides. Use --uix-camera-position to change where the stream is anchored when it overflows:

Value Description
center (default) Centred horizontally and vertically
top Anchored to the top edge
bottom Anchored to the bottom edge
left Anchored to the left edge
right Anchored to the right edge
top-left Anchored to the top-left corner
top-right Anchored to the top-right corner
bottom-left Anchored to the bottom-left corner
bottom-right Anchored to the bottom-right corner
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      --uix-camera-position: top;
    }

Camera zoom and pan

UIX injects a default transform rule into every camera background so that you can zoom and pan the stream by setting CSS custom properties. The variables can be set in uix-drawer (alongside --uix-view-background-camera-entity, for convenience) or in uix-view-background (for more targeted control). When set in both places the uix-drawer value takes precedence.

Variable Default Description
--uix-camera-zoom 1 Scale factor — values greater than 1 zoom in, less than 1 zoom out.
--uix-camera-pan-x 0% Horizontal shift. Accepts any CSS length or percentage. Positive values move the stream right (showing more of the left side of the camera).
--uix-camera-pan-y 0% Vertical shift. Accepts any CSS length or percentage. Positive values move the stream down (showing more of the top of the camera).

Centering: --uix-camera-position: center; ensures zooming always scales from the centre of the stream — so the camera stays centred at every zoom level. The pan variables shift from that centred position in screen space, independently of the current zoom level (10% pan is always a 10% screen-space shift).

Everything in one place (position + zoom + camera entity in uix-drawer):

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      --uix-camera-position: center;
      --uix-camera-zoom: 1.5;
      --uix-camera-pan-x: -10%;
    }

Zoom in and centre on the upper-left quadrant:

At 2× zoom, the stream is twice the size of the container. To bring the upper-left quadrant's centre into view, shift right and down by 50% of the container dimensions:

  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      --uix-camera-zoom: 2;
      --uix-camera-pan-x: 50%;
      --uix-camera-pan-y: 50%;
    }

Per-view zoom with templates:

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      {%- if panel.viewUrlPath == 'living-room' -%}
      --uix-camera-zoom: 1.8;
      --uix-camera-pan-x: -15%;
      {%- endif %}
    }

Responsive zoom with media queries:

CSS variables set inside a @media block apply only when that query matches, so you can zoom in on large screens while leaving the camera at natural size on smaller screens:

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      /* No zoom on small / mobile screens */
      --uix-camera-zoom: 1;
    }
    /* Zoom in on large screens (≥ 1280 px wide) */
    @media (min-width: 1280px) {
      :host {
        --uix-camera-zoom: 1.4;
        --uix-camera-pan-y: -5%;
      }
    }

You can combine this with --uix-camera-position for screens of different proportions:

  uix-drawer: |
    :host {
      --uix-view-background-camera-entity: camera.garden;
      /* Portrait / mobile: show the top of the feed */
      --uix-camera-position: top;
    }

    /* Landscape / desktop: centre the feed and zoom in slightly */
    @media (min-aspect-ratio: 16/9) {
      :host {
        --uix-camera-position: center;
        --uix-camera-zoom: 1.3;
      }
    }

Customising image background CSS properties

Both entity image and plain image backgrounds render as a <div class="uix-bg-image">. The div defaults to background-size: cover; background-position: center; background-repeat: no-repeat. You can override any of these properties — or add new ones — via the .uix-bg-image selector:

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-image: /local/background.png;
    }
  uix-view-background: |
    :host { opacity: 0.8; }

    /* Tile the image instead of stretching it to cover */
    .uix-bg-image {
      background-size: 300px 300px !important;
      background-repeat: repeat !important;
      background-position: top left !important;
    }

Making top app bar and sidebar transparent

You can use UIX styling on uix-top-app-bar-fixed to make the top app bar and sidebar transparent. Further config panels may have their own toolbars which you may also need to style via uix-config.

Example as shared by @ngocjohn on Home Assistant Community Forum.

  uix-top-app-bar-fixed: |
    :host {
      --mdc-top-app-bar-fixed-box-shadow: none;
      --sidebar-background-color: #ffffff00;
      --app-header-background-color: #ffffff00;
      --app-header-backdrop-filter: blur(2em);
      --app-header-border-bottom: none;
    }

Loading spinner

While the media is loading UIX shows a CSS-only animated spinner centred on the background container. The spinner fades out automatically once the media is ready (camera stream starts playing, video can play, or image has loaded).

The spinner can be customised via uix-view-background — it uses the class .uix-spinner (the track ring) and the pseudo-element .uix-spinner::after (the animated arc).

my-theme:
  uix-theme: my-theme
  uix-drawer: |
    :host {
      --uix-view-background-image: /local/background.jpg;
    }
  uix-view-background: |
    :host { opacity: 0.7; }

    /* Make the spinner larger */
    .uix-spinner::after {
      width: 120px;
      height: 120px;
    }

    /* Change spinner colour to match your theme */
    .uix-spinner::after {
      border-color: rgba(0, 128, 255, 0.2);
      border-top-color: rgba(0, 128, 255, 0.9);
    }

Tab visibility recovery

Browsers suspend WebRTC/HLS streams and video playback when a tab is in the background for a long time. UIX automatically recreates camera stream and video elements when you return to the tab, recovering the stream or playback without any manual intervention.

Static image backgrounds are not affected.