Custom Header template showcase and discussion

This thread is for showcasing interesting uses for and discussion of the template feature of Custom Header.

Since the template feature can render things like button & header text as HTML, you can do some interesting (but, entirely unintended) things.

This is an undocumented and mostly unsupported feature.

I’d like to keep the main thread for Custom Header clear of these discussions, giant screenshots, and huge codeblocks. This is now the place for such things. Thanks for understanding!

Examples:

Clock w/ Weather by @iantrich

Weather Marquee by @ludeeus

Vertical scroller by @mayker

4 Likes

wow, this split header is very nice! cool feature indeed.

And whats more, it opens up space for a cool marquee which we could template with the latest news, or alerts, or what have you. I could imagine it to show the notifications it now sends out, or even show conditional icons based on these alerts. Or, well, options galore.

Might be a nice feature request for 2020 :wink: Marquee support in split mode.

one small error in the log:

/local/lovelace/resources/custom-header.js?v=1.1.5:576:26048 Uncaught TypeError: Cannot read property 'split_mode' of undefined

though I can’t see anything resembling an issue…

You know you can do that now?

<marquee>{{["marquee are really useless now in almost 2020","Number of updates in HACS: " ~ (state_attr('sensor.hacs', 'repositories') | count),"But I guess it has it's uses still"] | join(" - ")}}</marquee>
9 Likes

Yes! Now that truly is awesome! :sunglasses:
Guess we will soon have a contest on the coolest use for that;-)

My entry:

{% set alerts = namespace(active=[], color="var(--google-red-500)") %}
{% set temperature = namespace(inside="18",  outside=state_attr('weather.home', 'temperature'), color="var(--google-blue-500)", symbol="°C") %}

{% if states('sensor.weatheralerts') | float != 0 %}
{% for alert in state_attr('sensor.weatheralerts', 'alerts') %}
{% set alerts.active = alerts.active + [alert['title']] %}
{% endfor %}
{% else %}
{% set alerts.active = alerts.active + ['No active alerts'] %}
{% endif %}

<marquee>
<span style='color: {{ temperature.color }}'>
    Inside temperature: {{ temperature.inside }}{{ temperature.symbol }}
    Outside temperature: {{ temperature.outside }}{{ temperature.symbol }}
</span>
<span style='color: {{ alerts.color }}; margin-left: 10px;'>
    Alerts: {{ alerts.active | join('  -  ')}}
</span>
</marquee>

alerts from the custom weatheralerts integration

5 Likes

Too Long; Didn’t Read

1 Like

Horizontal scrolling is so 2019…

custom_header:
  header_text: >-
    <style>
    #flipper {color:#999;}
    #flip {height:24px;overflow:hidden;}
    #flip > div > div {color:#fff;height:24px;margin-bottom:24px;display:inline-block;}
    #flip div:first-child {animation: show 10s linear infinite;}
    @keyframes show {
    0% {margin-top:-144px;}
    5% {margin-top:-96px;}
    33% {margin-top:-96px;}
    38% {margin-top:-48px;}
    66% {margin-top:-48px;}
    76% {margin-top:0px;}
    100% {margin-top:0px;}}
    #flipper p {position:fixed;color:#999; }
    </style>
    <div id=flipper><div id=flip><div><div>
    {{states('sensor.trash_day')}}</div></div><div><div>
    {{states('sensor.weather_daily_summary')}}</div></div><div><div>
    {{states('sensor.weather_hourly_summary')}}</div></div><div><div>
    {{states('sensor.trash_day')}}</div></div><div><div>
12 Likes

O boy, this will be a major challenge for the holidays :wink: using the vertical marquee here with local weather, so cool!

feature request: instead of this being the header-text, could you add a filler variable to be displayed in the header, next to the header-text? Id really love it to show the name of the instance, and then the marquee…

Maybe this could be solved by changing the marquee template to have a fixed spot for the instance name (which now default to the lovelace title) ? dont think the title is available as a builtin variable yet ? https://maykar.github.io/custom-header/#templates/builtin

Since the title is just static text I don’t think I’ll add it as a variable. You could make a stationary div next to the scroller with the text that you want in it, but I’m not about to start taking requests to write custom header templates :slight_smile: that would get out of hand quickly.

Can it be done the other way round?

i.e. Menu in the header, marquee in the footer.

I’m not sure I completely understand what you’re looking for, but split mode puts the buttons and header text in one and tabs in the other and can be flipped by making footer mode true. I don’t think I’ll make it so you can mix and match elements around.

I mean use split mode, keep the views menu up top and have the marquee at the bottom.

new to this div’ing so not sure why it is above instead of next to the marquee…

header_text: >-
  <style>
  #flipper{color:#999;}
  #flip {height:24px;overflow:hidden;}
  #flip > div > div {color:#fff;height:24px;margin-bottom:24px;display:inline-block;}
  #flip div:first-child {animation: show 10s linear infinite;}
  @keyframes show {
  0% {margin-top:-144px;}
  5% {margin-top:-96px;}
  33% {margin-top:-96px;}
  38% {margin-top:-48px;}
  66% {margin-top:-48px;}
  76% {margin-top:0px;}
  100% {margin-top:0px;}}
  #flipper p {position:fixed;color:#999; }
  </style>
  Ha Rpi4: 
  <div id=flipper><div id=flip><div><div>
  {{states('sensor.dark_sky_daily_summary')}}</div></div><div><div>
  {{states('sensor.br_symbol')}}</div></div><div><div>
  {{states('sensor.dark_sky_hourly_summary')}}</div></div><div><div>
  {{states('sensor.dark_sky_summary')}}</div></div><div><div>

also, the bottom sensor template (‘Helder’ in the marquee) only is displayed very shortly as you can see, is there an error in the code that causes that, or should it be there longer…

now see the long text is displayed on top of itself on my mobile device… have to find a way to change that yet…

still, very nice this is possible at all.

The first element and last element should be the same, that’s what gives it the illusion of looping. This is kind of an accidental feature of Custom Header and I don’t really want to start doing “how to code in HTML and CSS”, but…

Replace Ha Rpi4: with this <div style='float: left'>Ha Rpi4:&nbsp;&nbsp;</div>

If you start adding more than 3 elements you’ll need to edit the keyframes. A tip for this would be using multiples of 48px for the margins in the keyframes.

thanks!, that helped.

sure, appreciated. It would be a great idea though to create a separate header in the community on best practices and examples for Html and CSS, especially since so many custom cards start relying on it.

Don’t know if we can do this as ‘ordinary’ members, but otherwise I would certainly invite you to do so as one of the main dev’s !

I would say that I am much closer to an ordinary member of this community than a dev. I only really started coding about a year and a half ago when I picked up HA for the first time. Though I’ve learned a bit during that time, thanks mainly to the other developers in the community, I’m probably the last person anyone should go to for best practices. :slight_smile:

Hi I have copied your code and it comes up with this.

This is my code.

exceptions:
    - conditions:
        user: cameron
      config:
        header_text: >-
              <style>
              #flipper {color:#999;}
              #flip {height:24px;overflow:hidden;}
              #flip > div > div {color:#fff;height:24px;margin-bottom:24px;display:inline-block;}
              #flip div:first-child {animation: show 10s linear infinite;}
              @keyframes show {
              0% {margin-top:-144px;}
              5% {margin-top:-96px;}
              33% {margin-top:-96px;}
              38% {margin-top:-48px;}
              66% {margin-top:-48px;}
              76% {margin-top:0px;}
              100% {margin-top:0px;}}
              #flipper p {position:fixed;color:#999; }
              </style>
              <div id=flipper><div id=flip><div><div>
              {{states('sensor.cal_home_event_event')}}</div></div><div><div>
              {{states('sensor.dark_sky_daily_summary')}}</div></div><div><div>
              {{states('sensor.dark_sky_hourly_summary')}}</div></div><div><div>
              {{states('sensor.cal_home_event_event')}}</div></div><div><div>
        button_text:
            # menu: 'M'
            # The next example is using templates. See templates page for more info.
            options: >-
                      {{ hours12 }}:{{ minutesLZ }} {{ AMPM }} - <ha-icon icon='{{states('sensor.weather_icon')}}' style='padding-bottom: 3px';></ha-icon>
                      {{states.sensor.garden_temp.state }}°

        chevrons: true
        split_mode: true
        shadow: true
        footer_mode: false
        hide_help: true
        hide_config: true
        hide_unused: true
        background_color: '#292929'
        all_tabs_color: white
        show_tabs: '0 to 20,22'
        hide_tabs: '19,21'

The button text options works fine without the Header Text.

Mind sharing your whole config so I can see what’s outside the exception?

Mainly looking for config options that are using double quotes, see the last important note

a ok, cool.

I made an exception config for the iPhone in the meantime, using @ludeeus horizontal marquee, which works fine in itself.
It does show the odd ‘n’ after each line and header though, don’t know how ro get rid of them. Since I already use the >- multiline indicator, I would have hoped this to be sufficient blocking the new lines? Maybe that is something in the footer itself, because I almost literally copied @ludeeus entry, and his screen movie clearly shows its working alright in the header.

This is my exception:

  - conditions:
      user_agent: iPhone
    config:
      footer_mode: true
      header_text: >-
        Ha Rpi4:
        {% set alerts = namespace(active=[], color="var(--google-red-500)") %}
        {% set temperature = namespace(inside=states('sensor.temperatuur_living'), outside=states('sensor.temp_current'), color="var(--primary-text-color)", symbol="°C") %}

        {% if states('sensor.weatheralerts') | float != 0 %}
        {% for alert in state_attr('sensor.weatheralerts', 'alerts') %}
        {% set alerts.active = alerts.active + [alert['title']] %}
        {% endfor %}
        {% else %}
        {% set alerts.active = alerts.active + ['No active alerts'] %}
        {% endif %}

        <marquee>
        <span style='color: {{ temperature.color }}'>
            Inside temperature: {{ temperature.inside }}{{ temperature.symbol }}
            Outside temperature: {{ temperature.outside }}{{ temperature.symbol }}
        </span>
        <span style='color: {{ alerts.color }}; margin-left: 10px;'>
            Alerts: {{ alerts.active | join('  -  ')}}
        </span>

        <span style='color: {{ temperature.color }}'>
        {{states('sensor.dark_sky_summary')}}
          Daily -  {{states('sensor.dark_sky_daily_summary')}}
          Hourly - {{states('sensor.dark_sky_hourly_summary')}}
        </span>
        </marquee>

      menu_hide: true
#      voice_hide: false
      options_hide: true

          header_text: >-
            Ha Rpi4:  
            {% set alerts = namespace(active=[], color="var(--google-red-500)") %}
            {% set temperature = namespace(inside=states('sensor.temperatuur_living'), outside=states('sensor.temp_current'), color="var(--primary-text-color)", symbol="°C") %}
            {% if states('sensor.weatheralerts') | float != 0 %}
            {% for alert in state_attr('sensor.weatheralerts', 'alerts') %}
            {% set alerts.active = alerts.active + [alert['title']] %}
            {% endfor %}
            {% else %}
            {% set alerts.active = alerts.active + ['No active alerts'] %}
            {% endif %}
            <marquee>
            <span style='color: {{ temperature.color }}'>
            Inside temperature: {{ temperature.inside }}{{ temperature.symbol }}
            Outside temperature: {{ temperature.outside }}{{ temperature.symbol }}
            </span>
            <span style='color: {{ alerts.color }}; margin-left: 10px;'>
            Alerts: {{ alerts.active | join('  -  ')}}
            </span>
            <span style='color: {{ temperature.color }}'>
            {{states('sensor.dark_sky_summary')}}
            Daily -  {{states('sensor.dark_sky_daily_summary')}}
            Hourly - {{states('sensor.dark_sky_hourly_summary')}}
            </span>
            </marquee>