šŸ”¹ Layout-card - Take control of where your cards end up

Fist and for all, many thanks for bringing and everybody supporting custom:grid-layout.

I have arrived at the point, where I want to tweak the position of the items withing a grid area. As suggested in the documentation, I started reading up on CSS Grid. Here, I noticed the justify-self and align-self properties. These let the each item decide ā€œfor themselvesā€ where it should be placed withing the grid area.

justify-self Aligns a grid item inside a cell along the inline (row) axis. This value applies to the content inside a single grid item.

align-self Aligns a grid item inside a cell along the block (column) axis. This value applies to the content inside a single grid item.

I’ve made many attempts at CSS selectors using mod_card, but just can’t figure how to specify properties for the custom:grid-layout items / children / areas (or whatever the correct terminology is).

I reduced my example to the basic lovelace page shown below.

views:
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      height: calc(100vh - 56px) # assuming a header
      place-items: center center
      grid-template-columns: 1fr
      grid-template-rows: repeat(3, 1fr)
      grid-template-areas: |
        "a"
        "b"
        "footer"
    cards:
      - type: markdown
        content: "area a"
        view_layout:
          grid-area: a
      - type: markdown
        content: "area b"
        view_layout:
          grid-area: b
      - type: markdown
        content: "area footer"
        view_layout:
          grid-area: footer
        card_mod:
          style: |
            ha-card {
              background: red;
            }

Here, I want to e.g. place the footer at the vertical and horizontal end of its grid area.

In comparison, button-card has a styles field that let you specify CSS properties for its grid items, as in:

views:
  - type: custom:button-card
    name: "area n"
    state_display: "area s"
    label: "area l"
    show_label: true
    show_state: true
    styles:
      card:
        - border: none
        - padding: 0
      grid:
        - padding: 0
        - height: calc(100vh - 56px)
        - grid-template-columns: 1fr
        - grid-template-rows: repeat(3, 1fr)
        - grid-template-areas: |
            "n"
            "s"
            "l"
      name:
        - justify-self: start # horizontal
        - align-self: start # vertical
      state:
        - justify-self: center
        - align-self: center
      label:
        - justify-self: end
        - align-self: end
        - background: red

Is a similar approach possible with custom:grid-layout? Is there a CSS selector that I just missed?

Thanks for your time and consideration,
/coert

Nearly there. Apply the styling to :host which applies to the markdown card itself, which is the host of the ha-card where card-mod is applied.

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  height: calc(100vh - 56px)
  place-items: center center
  grid-template-columns: 1fr
  grid-template-rows: repeat(3, 1fr)
  grid-template-areas: |
    "a"
    "b"
    "footer"
cards:
  - type: markdown
    content: area a
    view_layout:
      grid-area: a
  - type: markdown
    content: area b
    view_layout:
      grid-area: b
  - type: markdown
    content: area footer
    view_layout:
      grid-area: footer
    card_mod:
      style: |
        :host {
          justify-self: flex-end;
          align-self: end;
        }
        ha-card {
          background: red;
        }

Brilliant, can’t believe I missed that. (I get a feeling that sometimes the network caching causes me miss things.)

Brings me to a follow-up, that is my real-life scenario:

How would it work when footer itself was a custom:grid-layout, as in

views:
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      height: calc(100vh - 56px) # assuming a header
      place-items: center center
      grid-template-columns: 1fr
      grid-template-rows: repeat(3, 1fr)
      grid-template-areas: |
        "a"
        "b"
        "footer"
    cards:
      - type: markdown
        content: "area a"
        view_layout:
          grid-area: a

      - type: markdown
        content: "area b"
        view_layout:
          grid-area: b

      - type: custom:layout-card
        layout_type: custom:grid-layout
        view_layout:
          grid-area: footer
        layout_options:
          place-items: center stretch
          place-content: end end
          padding: 0
          margin: 0vw
          grid-gap: 2vw
          grid-template-columns: repeat(2, 1fr)
          grid-template-rows: min-content
        card_mod:
          style: |
            :host {
              justify-self: flex-end;
              align-self: end;
              background: red;
            }
        cards:
          - type: markdown
            content: "footer1"
          - type: markdown
            content: "footer2"

Here, there is no hui-card or ha-card in the DOM structure.

layout-card                  ⇐ the top level layout-card
 ↳ $ 
   ↳ grid-layout
     ↳ $
        ↳ #root              ⇐ this appears to be the top of the CSS grid
           ↳  layout-card    ⇐ apply justify-self here?
             ↳ $ 
               ↳ grid-layout 
                  ↳ $
                    ↳  #root"

That means the :host selector doesn’t work. I also tried the place-content.

thanks
/Coert

Easiest here is to use custom:mod-card

type: custom:layout-card
layout_type: custom:grid-layout
layout:
  height: calc(100vh - 56px)
  place-items: center center
  grid-template-columns: 1fr
  grid-template-rows: repeat(3, 1fr)
  grid-template-areas: |
    "a"
    "b"
    "footer"
cards:
  - type: markdown
    content: area a
    view_layout:
      grid-area: a
  - type: markdown
    content: area b
    view_layout:
      grid-area: b
  - type: custom:mod-card
    card:
      type: custom:layout-card
      layout_type: custom:grid-layout
      view_layout:
        grid-area: footer
      layout_options:
        place-items: center stretch
        place-content: end end
        padding: 0
        margin: 0vw
        grid-gap: 2vw
        grid-template-columns: repeat(2, 1fr)
        grid-template-rows: min-content
      cards:
        - type: markdown
          content: footer1
        - type: markdown
          content: footer2
    card_mod:
      style: |
        :host {
          justify-self: flex-end;
          align-self: end;
          background: red;
        }

You could also theme card-mod-view and then use yaml selectors to traverse each DOM tree via shadowRoot selectors, but this gets tricky and is hard to maintain.

Best would be for custom:layout-card to apply card-mod to itself. Perhaps in future but I am not sure that would happen too quickly.

A final thought is that in a Sections dashboard, card_mod v4 can now support sections grids and stack cards. As they all use flex layout you could probably get what you need with a sections dashboard and card_mod. I might see what I can replicate.

I had a play and posted an example in card_mod thread.

1 Like

Thanks for your help.
This makes a great difference to me.

/Coert

1 Like