Skip to content
GitHubGoody edited this page Jun 14, 2022 · 42 revisions

Note: If you mix a non--yaml chunk with a -yaml chunk, substitute like this:

First section

  card-mod-root: |
    app-toolbar {
      display: none;
    }

Second section

  card-mod-root-yaml: |
    paper-tabs$: |
      .not-visible {
        display: none;
      }

Mixed

  card-mod-root-yaml: |
    paper-tabs$: |
      .not-visible {
        display: none;
      }
    .: |
      app-toolbar {
        display: none;
      }

Remove top part of header

no-top-header:
  card-mod-theme: no-top-header

  card-mod-root: |
    app-toolbar {
      display: none;
    }

With only one view

image

With multiple views

image

Remove the header fully

no-header:
  card-mod-theme: no-header

  card-mod-root: |
    app-header {
      display: none;
    }

Make header transparent and add background to everything

transparent-header:
  card-mod-theme: transparent-header
  card-mod-root: |
    ha-app-layout {
      background: url("https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTR-Hllcy5CR5U90nMlW8bZA_VM7w4VlP2lZg&usqp=CAU");
    }
    app-header {
      background: rgba(0,0,0,0.5) !important;
    }
    app-toolbar {
      background: none !important;
    }

image

Note: app-header and app-toolbar overlap, so if you make both of them transparent, things will look weird. Better to make one have no background. Note2: the --lovelace-background variable applies a background to the view, but the header is outside of the view, so you can't use that to get a background behind it - unless you also move it 🤔

Remove unused space when chevrons are not needed in header

tabs-to-edge:
  card-mod-theme: tabs-to-edge
  card-mod-root-yaml: |
    paper-tabs$: |
      .not-visible {
        display: none;
      }

image

Display battery level in background of entities with battery or battery_level attributes

battery-rows:
  card-mod-theme: battery-rows

  card-mod-row: |
    :host {
      display: block;
      {% set battery = state_attr(config.entity, 'battery') or state_attr(config.entity, 'battery_level') %}
      {% if battery %}
        background: linear-gradient(to right, rgba(0,255,0,0.5), {{battery}}%, white {{battery}}%);
      {% endif %}
    }

image

Put a custom secondary-info text in entities that have a battery

custom-secondary:
  card-mod-theme: custom-secondary
  card-mod-row-yaml: |
    hui-generic-entity-row$: |
      {% set battery = state_attr(config.entity, 'battery') or state_attr(config.entity, 'battery_level') %}
      {% if battery %}
        .info.text-content::after {
          content: "{{battery}}%";
          display: block;
          color: var(--secondary-text-color);
        }
      {% endif %}

image

.info.text-content will select only rows that don't already have a secondary-info row.

Make fans spin while on

fan-spinning:
  card-mod-theme: fan-spinning
  card-mod-card: |
    @keyframes spin {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(359deg);
      }
    }
    ha-icon[data-domain="fan"][data-state="on"] {
      animation: spin 4s infinite linear;
    }
  card-mod-row-yaml: |
    "*:first-child$": |
      @keyframes spin {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(359deg);
        }
      }
      state-badge {
        {% if config.entity.startswith('fan.') and is_state(config.entity, 'on') %}
          animation: spin 4s infinite linear;
        {% endif %}
      }

Force one column for cards

one-column:
  card-mod-theme: one-column
  card-mod-view: |
    "hui-masonry-view$#columns" {
      flex-direction: column !important;
      margin: 0 auto;
      max-width: 500px;
    }

Compact/Custom header

Card-mod themes can be used to replace much of the functionality that was previously available in the now defunct custom-header. Here are a few examples. Others are possible if you find the right CSS properties to change. Hopefully these examples serve as a starting point.

This example gets rid of the image menu button on the left that shows when viewing on mobile (you can still swipe from the left to open the sidebar), and the title text.

  card-mod-theme: "NAME_OF_YOUR_THEME_HERE"
  card-mod-root-yaml: |
    .: |
      ha-menu-button {
        display: none !important;
      }

In Custom Header, you would have done this like (before compact mode being default behavior in v.117 of Home Assistant)

custom_header:
  compact_mode: true
  config:
    menu_hide: true

This example changes the image overflow menu with a clock while keeping the menu functional (click on the time to open the menu). You must have the time and date integration enabled with sensor.time. In order to use position:absolute, you will have to start with a large value for width, such as 400px and then reduce it until you get it into the correct position on the right of the screen (example shown below is for date and time). If you have something short you'd like to use instead of the menu button, you can try using position:relative instead, which can correctly position it without the width parameter, but leaves you with a small box so only works for a small item like a clock with no date.

  card-mod-theme: "NAME_OF_YOUR_THEME_HERE"
  card-mod-root: |
    ha-button-menu::before {
    content: "{{states('sensor.time_formatted')}}";
    color: var(--text-primary-color);
    visibility: visible;
    position: absolute;
    font-size: 20px;
    width: 230px;
    top: 13px;
    right: 0px;

    }

    ha-menu-button {
      display: none !important;
    }


    ha-button-menu {
      color: transparent;
    }

In custom header, doing the same thing would have looked like this

        button_text:
          menu: 'menu'
          options: '{{ dayNameShort }}, {{ dayNum }} {{ monthNameShort }}       {{ hours24LZ }}:{{ minutesLZ }}'

If we want, we can also make the clock conditional to a specific user. In this example we will replace the overflow menu with a clock only for the 'kiosk' user. The template conditional statement {% if user == 'USERNAME' %}can be used to make conditional formatting for different elements of your theme specific to the logged in user.

  card-mod-theme: "NAME_OF_YOUR_THEME_HERE"
  card-mod-root-yaml: |
    .: |
      {% if user == 'kiosk' %}

      mwc-icon-button[slot="trigger"] > ha-svg-icon {
        display: none;
      }

      mwc-icon-button[slot="trigger"]::after {
        font-size: 22px;
        height: 20px; 
        width: 100px;
        margin-left: 0px;
        margin-right: 0px;
        content: "{{ states('sensor.time') }}";
        position: absolute;
        top: 14px;
        right: 0px;
      }
      {% endif %}

This conditional styling by user is similar to the custom header config

    - conditions:
        user: kiosk

This example does some changes that are applied specifically to all browsers in portrait orientation. It removes the overflow menu and chevrons.

  card-mod-theme: "NAME_OF_YOUR_THEME_HERE"
  card-mod-root-yaml: |
    .: |
      ha-menu-button {
        display: none !important;
      }

      @media (orientation: portrait) {
        a.menu-link[target="_blank"], ha-button-menu, [main-title] {
          display: none;
        }
        paper-icon-button[icon="paper-tabs:chevron-right"] {
          display: none;
        }
        paper-icon-button[icon="paper-tabs:chevron-left"] {
          display: none;
        }
      }

This would have been similar to (but not exactly the same as*) a custom header config of:

    - conditions:
        template: "{{ 'iPhone' in userAgent or 'iOS' in userAgent }}"
      config:
        menu_hide: true
        options_hide: true
        chevrons: false

*In custom header, this would check if when you loaded the page, you told the website that you're running on an iOS device. In card-mod, this just checks if your height is greater than your width (so it would trigger if you resized your desktop browser to portrait mode).

Combined header items

Below is an example of using many different of the custom header type features to create a header that is on the bottom of the screen with changes in colors and removing items like the title and some buttons. It might help you learn some stuff as well (but you should learn basic CSS too).
⚠️ This is advanced, make sure you fully understand it before modifying it. Also, this chunk is based off of a card-mod theme, and this chunk might not be regularly updated For some reason now it's more frequently updated? Maybe more people remind me in the card-mod thread than in the other thread. This supports uncommenting various items to do stuff like moving it to the bottom. Scream at @KTibow over there if you want more functionality.

compact-header:
  card-mod-theme: compact-header
  header-height: 48px
  card-mod-root-yaml: |
    paper-tabs$: |
      /* Uncomment this for header on the bottom. You're 1/3 there.
      #selectionBar {
        bottom: unset !important;
      }
      */
    .: |
      /* This moves the header up. */
      app-header {
        transform: translate3d(0px, -48px, 0px);
      }
      /* Let's change the background. */
      app-header, app-toolbar {
        background: var(--primary-background-color) !important;
        color: var(--primary-text-color) !important;
      }
      /* We're still going to need a way to see that we're in edit mode. */
      app-header.edit-mode {
        padding-bottom: calc(var(--ha-card-border-width, 2px) * 2);
        border-bottom: var(--ha-card-border-width, 2px) solid var(--primary-color);
      }
      /* This changes the color of the currently selected tab. */
      ha-tabs {
        --paper-tabs-selection-bar-color: var(--primary-color) !important;
      }
      paper-tab[aria-selected=true] {
        color: var(--primary-color) !important;
      }
      /* This hides the help button. */
      a.menu-link[target="_blank"] {
        display: none;
      }
      /* This makes the plus color the same as the background. */
      #add-view {
        color: var(--primary-background-color);
      }
      /* This hides the title. */
      [main-title] {
        display: none;
      }
      /* This hides the app-toolbar in edit mode. */
      app-toolbar.edit-mode {
        height: 0;
      }
      /* This moves the edit mode buttons back in. */
      app-toolbar.edit-mode > mwc-icon-button {
        position: absolute;
        left: 0;
        top: 0;
        z-index: 1;
      }
      app-toolbar.edit-mode > ha-button-menu {
        position: absolute;
        right: 0;
        top: 0;
        z-index: 1;
      }
      /* This adds a bit more padding, mainly for unused entities. */
      app-header.edit-mode > div {
        padding-left: 5px;
      }
      /* Uncomment this for header on the bottom. You're 2/3 there.
      app-header {
        top: calc(100vh - 60px) !important;
        bottom: 0 !important;
        transform: unset !important;
      }
      */
  
  /* Uncomment this to move the main content up to fill the gap left by the shifted header. You're 3/3 there.
  card-mod-view-yaml: |
          .: |
            hui-view {
              transform: translate3d(0px, -60px, 0px);
            }
            */

Other components that can replace some of custom header's functionality

Here are a few other things that can help recreate functionality from custom header.

First, version 0.117 of Home Assistant makes the compact header that made custom header famous default behavior. So if you haven't already, you should upgrade.

The hide_tabs functionality of Custom Header is now also standard in Home Assistant with the "visibility" tab in the tab editor (or if you use YAML).

If you want to hide the header or sidebar completely, the creator of Custom Header has a Kiosk Mode plugin as well.

If you'd like to remove the mic button from your header as was done with the voice_hide: true option in Custom Header, remove Almond from your list of configured integrations. Or if you use configuration.yaml, remove this line:

conversation: