thomasloven / lovelace-card-mod

🔹 Add CSS styles to (almost) any lovelace card
MIT License
1.13k stars 168 forks source link

position: sticky doesn't work #380

Open AINER opened 3 months ago

AINER commented 3 months ago

My Home Assistant version: 2024.6.3

With one of the latest Home Assistant updates, the position: sticky property stopped working in some cases.

It works if you use it on a card that is in a grid.

type: grid
square: false
columns: 1
cards:
  - type: custom:stack-in-card
    mode: horizontal
    card_mod:
      style:
        .: |
          :host {
            position: sticky !important;
            z-index: 3 !important;
            top: -20px !important;
          }
          ha-card {
            transition: none !important;
            border-radius: 0px;
            background: var(--primary-background-color);
            box-shadow: 0px 0px 6px 0px  var(--primary-background-color) !important;
            height: 80px;
            margin: -8px -12px;
            padding: 8px 12px;
          }
    cards:
      - type: custom:mushroom-title-card
        title: Комнаты
        title_tap_action:
          action: navigate
          navigation_path: rooms
        card_mod:
          style:
            .: |
              ha-card {
                transition: none !important;
                --primary-text-color: rgb(var(--rgb-grey));  
                --title-font-size: 16px;
                --card-secondary-color: rgb(var(--rgb-grey)); 
                --subtitle-font-size: 14px;
                margin: 7px 0px -18px 0px;
              }
      - type: custom:mushroom-title-card
        subtitle: 4 из 9
        title_tap_action:
          action: navigate
          navigation_path: rooms
        card_mod:
          style:
            .: |
              ha-card {
                transition: none !important;
                --primary-text-color: rgb(var(--rgb-grey));  
                --title-font-size: 16px;
                --card-secondary-color: rgb(var(--rgb-grey)); 
                --subtitle-font-size: 14px;
                text-align: end;
                margin: 8px 0px -4px 0px;
              }
  - type: grid
    square: false
    columns: 2
    cards:
      - type: custom:stack-in-card
        card_mod:
          style: |
            ha-card {
              transition: none !important;

              height: 176px !important;
            }
        cards:
          - type: custom:layout-card
            layout_type: custom:grid-layout
            layout:
              grid-template-columns: auto auto
              margin: '-4px -4px 0px -4px;'
            cards:
              - type: custom:mushroom-template-card
                entity: input_text.gostinaia
                tap_action:
                  action: more-info
                icon: hue:room-living
                primary: Гостиная
                layout: horizontal
                badge_icon: null
                card_mod:
                  style:
                    mushroom-state-info$: |
                      .primary {
                        transition: none !important;

                        font-size: 14px !important;
                        position: relative;
                        overflow: visible !important;

                        top: -50px;
                        left: -132px;
                      }
                      .secondary {
                        transition: none !important;

                        position: relative;
                        overflow: visible !important;

                        top: -62px;
                        left: -180px;
                      }
                    mushroom-shape-icon$: |
                      .shape {
                        transition: none !important;

                        position: relative;

                        left: -30px;
                        top: 75px;

                        --icon-color: rgb(253, 64, 112) !important;
                        --shape-color: rgba(254, 64, 112, 0.2) !important;

                        #--icon-symbol-size: 90px;
                      }
                    .: |
                      ha-card {
                        transition: none !important;

                        background: none;
                        box-shadow: none;
                        --badge-icon-size: 1em;
                        --badge-size: 1.5em;
                        width: 100px !important;
                      }
                      :host {
                        --mush-icon-size: 120px;
                      }
              - type: custom:stack-in-card
                card_mod:
                  style:
                    .: |
                      ha-card {
                        transition: none !important;

                        box-shadow: none;
                      }
                cards:
                  - type: custom:mushroom-light-card
                    entity: light.lights_gostinaia
                    icon: mdi:lightbulb
                    primary_info: none
                    secondary_info: none
                    card_mod:
                      style:
                        .: |
                          ha-card {
                            transition: none !important;

                            padding-bottom: 0px !important;
                            --icon-border-radius: 12px;
                            align-items: flex-end;
                          }
                  - type: custom:mushroom-media-player-card
                    entity: media_player.gostinaia_tv
                    icon: mdi:motion-play-outline
                    primary_info: none
                    secondary_info: none
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          transition: none !important;

                          padding-bottom: 0px !important;
                          --icon-border-radius: 12px;
                          align-items: flex-end;

                          --rgb-state-media-player: 0, 188, 212;
                        }
                  - type: custom:mushroom-template-card
                    primary: []
                    icon_color: []
                    icon: []
                    secondary: []
                    card_mod:
                      style: |
                        ha-card {
                          transition: none !important;

                          padding-bottom: 0px !important;
                          --icon-border-radius: 12px;
                          align-items: flex-end;
                        }

But it doesn't work for stack-in-card, which is located in the main dashboard space

type: custom:stack-in-card
mode: vertical
card_mod:
  style:
    .: |
      :host {
        position: sticky !important;
        z-index: 3 !important;
        bottom: -20px !important;
      }
      ha-card {
        transition: none !important;
        box-shadow: 0px 0px 12px 0px var(--primary-background-color) !important;
        background: var(--primary-background-color);
        padding: 0px 0px 0px 0px;
        margin: 0px -8px 0px;
        border-radius: 0px;
        height: 126px;
      }
cards:
  - type: custom:mushroom-chips-card
    card_mod:
      style: |
        ha-card {
          transition: none !important;
          margin: 10px -10px -16px 1px !important;
          box-shadow: inset 0px 0px 12px 10px var(--primary-background-color) !important;
        }
        ha-card > .chip-container {
          flex-wrap: nowrap;
          overflow-x: auto;

          overscroll-behavior-x: contain;
          scroll-snap-type: x mandatory;
          scroll-snap-align: start;
        }

        ha-card > .chip-container > * {
          flex-shrink: 0;
        }
    chips:
      - type: template
        card_mod:
          style: |
            ha-card {
              transition: none !important;
              background: none  !important;
              min-width: 0px !important;
              width: 5px !important;
            }
      - type: template
        entity: weather.gismeteo
        content: |-
          {{ states('sensor.current_weather') }}
          {{ states('sensor.gismeteo_apparent_temperature') | round(0) }} °C
        icon: |-
          {% if is_state('weather.gismeteo', 'sunny') %}
          mdi:weather-sunny
          {% elif is_state('weather.gismeteo', 'partlycloudy') %}
          mdi:weather-partly-cloudy
          {% elif is_state('weather.gismeteo', 'cloudy') %}
          mdi:weather-cloudy
          {% elif is_state('weather.gismeteo', 'rainy') %}
          mdi:weather-rainy
          {% elif is_state('weather.gismeteo', 'partly-rainy') %}
          mdi:weather-partly-rainy
          {% elif is_state('weather.gismeteo', 'pouring') %}
          mdi:weather-pouring
          {% elif is_state('weather.gismeteo', 'fog') %}
          mdi:weather-fog
          {% elif is_state('weather.gismeteo', 'hail') %}
          mdi:weather-hail
          {% elif is_state('weather.gismeteo', 'hazy') %}
          mdi:weather-hazy
          {% elif is_state('weather.gismeteo', 'lightning') %}
          mdi:weather-lightning
          {% elif is_state('weather.gismeteo', 'lightning-rainy') %}
          mdi:weather-lightning-rainy
          {% elif is_state('weather.gismeteo', 'partly-lightning') %}
          mdi:weather-partly-lightning
          {% elif is_state('weather.gismeteo', 'snowy') %}
          mdi:weather-snowy
          {% elif is_state('weather.gismeteo', 'snowy-heavy') %}
          mdi:weather-snowy-heavy
          {% elif is_state('weather.gismeteo', 'snowy-rainy') %}
          mdi:weather-snowy-rainy
          {% elif is_state('weather.gismeteo', 'partly-snowy') %}
          mdi:weather-partly-snowy
          {% elif is_state('weather.gismeteo', 'partly-snowy-rainy') %}
          mdi:weather-partly-snowy-rainy
          {% elif is_state('weather.gismeteo', 'clear-night') %}
          mdi:weather-night
          {% elif is_state('weather.gismeteo', 'night-partly-cloudy') %}
          mdi:weather-night-partly-cloudy
          {% endif %}
        icon_color: >-
          {% if is_state('weather.gismeteo', 'sunny') %} #FFF900 {% elif
          is_state('weather.gismeteo', 'partlycloudy') %} #B3B6B7 {% elif
          is_state('weather.gismeteo', 'cloudy') %} #626567 {% elif
          is_state('weather.gismeteo', 'rainy') %} blue {% elif
          is_state('weather.gismeteo', 'partly-rainy') %} #4E4DD8 {% elif
          is_state('weather.gismeteo', 'pouring') %} #2E9AFE {% elif
          is_state('weather.gismeteo', 'fog') %} #C0C0C0 {% elif
          is_state('weather.gismeteo', 'hail') %} white {% elif
          is_state('weather.gismeteo', 'hazy') %} grey {% elif
          is_state('weather.gismeteo', 'lightning') %} #D9D401 {% elif
          is_state('weather.gismeteo', 'lightning-rainy') %} #D9D401 {% elif
          is_state('weather.gismeteo', 'partly-lightning') %} #D9D401 {% elif
          is_state('weather.gismeteo', 'snowy') %} grey {% elif
          is_state('weather.gismeteo', 'snowy-heavy') %} f5f5f5 {% elif
          is_state('weather.gismeteo', 'snowy-rainy') %} f5f5f5 {% elif
          is_state('weather.gismeteo', 'partly-snowy') %} f5f5f5 {% elif
          is_state('weather.gismeteo', 'partly-snowy-rainy') %} f5f5f5 {% elif
          is_state('weather.gismeteo', 'clear-night') %} #FFF900 {% elif
          is_state('weather.gismeteo', 'night-partly-cloudy') %} #B3B6B7 {%
          endif %}
        card_mod:
          style: |
            ha-card {
              transition: none !important;

              margin: 2px;
              margin-bottom: 10px;
              padding: 1px 6px 1px 2px;
            }
            .content {
              white-space: pre-wrap;
            }
Guizmos commented 3 months ago

It's doesn't work for me with stack-in-card AND grid. Before update Home Assistant version: 2024.6.3 everything work fine.. Do you have any solution ?

ASNNetworks commented 2 months ago

Seems in 2024.7 this is completely busted too.

AINER commented 2 months ago

Yes, now position: sticky doesn't work in grid

Guizmos commented 2 months ago

Great, suddenly my personalized menu no longer has any interest (especially with its blur effect)... I'm disgusted Thank you for your answers anyway

PS: I tried replacing 'sticky' with 'fixed' but I don't have a great result at the moment

danwooller commented 2 months ago

Changing to fixed puts the sticky back, but there's no width control

Guizmos commented 2 months ago

And is it an HA bug or is it a voluntary modification?

giovanni247000 commented 2 months ago

nothing new ?

jimz011 commented 1 month ago

Did anyone find a fix for this (other than using position: fixed)?

Fixed doesn't behave the same as sticky, I've tried so many things now and asked everywhere on the forums and official HA channels, but no one seems to have an answer (or no one even answers at all).

AINER commented 1 month ago

@thomasloven , if I rightly understand, developers of HA have changed root element. And now :host refers to ha-card, but we need to use hui-card.

jimz011 commented 2 weeks ago

@AINER did you find anything in the meantime? I am really baffled that no one has an answer to this and on the HA forums and discord they don't even react to this question at all. As in, it is completely ignored.

AINER commented 2 weeks ago

@jimz011 Nope. To solve this problem, it appears that the add-on logic needs to be changed to use CSS styles with the hui-card element. Then this will work. But this element cannot be used now. Only Thomas can help here. Or someone of the TS developers can fork the project and try to fix it in their version of the add-on.

image

jimz011 commented 2 weeks ago

Actually, I think I have found somewhat of a solution (it would require some adjustments on your part). It seems that if you put the cards in a layout-card instead of a vertical or horizontal-stack that the sticky part simply works again.

So instead of doing:

- type: vertical-stack
  cards:
    - type: markdown
      card_mod:
        style: |
          :host {
            position: sticky;
            top: 0;
            z-index: 1;
          }
      content: NOT STICKY

You do this:

- type: custom:layout-card
  cards:
    - type: markdown
      card_mod:
        style: |
          :host {
            position: sticky;
            top: 0;
            z-index: 1;
          }
      content: IS STICKY

I hope this helps someone!

Guizmos commented 2 weeks ago

Actually, I think I have found somewhat of a solution (it would require some adjustments on your part). It seems that if you put the cards in a layout-card instead of a vertical or horizontal-stack that the sticky part simply works again.

So instead of doing:


- type: vertical-stack

  cards:

    - type: markdown

      card_mod:

        style: |

          :host {

            position: sticky;

            top: 0;

            z-index: 1;

          }

      content: NOT STICKY

You do this:


- type: custom:layout-card

  cards:

    - type: markdown

      card_mod:

        style: |

          :host {

            position: sticky;

            top: 0;

            z-index: 1;

          }

      content: IS STICKY

I hope this helps someone!

This doesn't work for me.

Core: 2024.9.2 Superviser: 2024.09.1 Operating System: 13.1

jimz011 commented 2 weeks ago

Hm, that is weird. I have the same HA version and I just tried it on a second HA setup and it also works there. I tried multiple view setups (masonry, grid, panel, sections) it all seem to work there.

Could you perhaps make a new dashboard (storage), create a new card and paste the following code to try?

type: custom:layout-card
cards:
  - type: entities
    entities:
      - light.office
    card_mod:
      style: |
        :host {
          position: sticky;
          top: 0;
          z-index: 10;
        }
  - type: custom:layout-card
    view_layout:
      grid-area: main
    layout_type: masonry
    cards:
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: markdown
        content: test
      - type: grid
        cards:
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office
          - type: button
            entity: light.office

I know it is a lot of useless code, but that way at least you can easily check if it works or not (just change the light entity to something you actually have).

image

When scrolling down the top card should stay at the top (note that the behaviour might be different if you use themes and/or hide the header via themes. So for testing purposes I would always advise to use no modifications at all of temporarily disable them. Also make sure to clear cache (or try an incognito window) after saving your project). For me it worked without a refresh, but your situation might be different.

Let me know how it goes!

Guizmos commented 2 weeks ago

ok it works from a new Dashboard with your code.

However, it doesn't seem to work if I replace type:entities with type:custom:stack-in-card 😭

jimz011 commented 2 weeks ago

That shouldn't have worked either way as stack-in-card can't be styled with card-mod (or at least it isn't supposed to do that). What you could try is wrapping it in a mod-card.

type: custom:mod-card
card_mod:
  style: |
    :host {
      position: sticky;
      top: 0;
      z-index: 1;
    }
card:
  type: custom:stack-in-card
  cards: []

I have not tested this, but I think this should work for you @Guizmos

ASNNetworks commented 6 days ago

That shouldn't have worked either way as stack-in-card can't be styled with card-mod (or at least it isn't supposed to do that). What you could try is wrapping it in a mod-card.

type: custom:mod-card
card_mod:
  style: |
    :host {
      position: sticky;
      top: 0;
      z-index: 1;
    }
card:
  type: custom:stack-in-card
  cards: []

I have not tested this, but I think this should work for you @Guizmos

This doesn't work, in fact: this is my base setup already. I have my own menubar inside a vertical-stack. In order to use card-mod I had to use mod-card already. So your suggestion, is already how my setup is, which loses its sticky with HA 2024.9.

type: custom:mod-card
card_mod:
  style: |
    ha-card {
      --ha-card-background: var(--ch-background) !important;
      background: var(--ch-background) !important;
      border-radius: 0px !important;
      --ha-card-border-radius: 0px !important;
    }            
    .card-content {
      padding: 0;
    }
    :host {
      z-index: 7;
      position: sticky !important;
      position: -webkit-sticky !important;
      bottom: 0;
      border-radius: 0px !important;
      --ha-card-border-radius: 0px !important;                
    }
card:
  type: vertical-stack
  cards:

Nesting this entire code inside a layout-card as you suggested also doesn't work btw.

Edit: I switched to fixed instead of sticky variable and used width: 100vw in the card-mod variables. Works great too. Added some gap-cards using layout-cards with my header and footer cards, since it works slightly differently this way, but outcome is the same visually.