Search code examples
htmlweb-componentlit-elementlit-htmllit

lit: how to apply style to nested template?


There is a lit element container-element which has has nested lit elements gmail-item.

How do you apply styles to nested elements so that the last gmail-item has border-none?

Currently, the styling li:last-of-type doesn't propegate to nested lit elements which contain li.

      @container-element
  
      li:last-of-type {
        border-bottom: none;
      }

      <gmail-item></gmail-item>
      <gmail-item></gmail-item>
      <gmail-item></gmail-item>
      <gmail-item></gmail-item>
      <gmail-item></gmail-item>
@gmail-item

li {
 border-bottom: 1px solid black;
}


<li>I am gmail item</li>

edit:

tried the following.

      <style>
        gmail-item::slotted(li) {
          border: 1px solid orange;
        }
        gmail-item li {
          border: 1px solid orange;
        }
        li {
          border: 1px solid orange;
        }
      </style>
      <gmail-item></gmail-item>
           ........

But unfortunately none of them apply styles to the li inside gmail-item.

I also tried adding createRendeRoot but this removed all styling inside gmail-item.

@gmail-item

createRenderRoot() {
return this;
}

Also tried setting li border-bottom to inherit.


Solution

  • Your best bet would be css variables. It is a standard and it is scoped.

    .container-1 {
      --my-status: grey;
    }
    
    .container-2 > gmail-item:first-child {
      --my-status: orange;
    }
    <script type="module">
    import {
      LitElement,
      html,
      css
    } from "https://unpkg.com/lit-element/lit-element.js?module";
    
    class MyContainer extends LitElement {
      static get styles() {
        return css`
          .wrapper {
            min-height: 100px;
            min-width: 50%;
            margin: 5em;
            padding: 10px;
            background-color: lightblue;
          }
        `;
      }
    
      render() {
        return html`
          <div class="wrapper">
            <slot></slot>
          </div>
        `;
      }
    }
    
    class GmailItem extends LitElement {
      static get styles() {
        return css`
          .status {
            margin: 1em;
            border: 2px solid white;
            background-color: var(--my-status, red);
          }
        `;
      }
    
      render() {
        return html`
          <div class="status">STATUS</div>
        `;
      }
    }
    
    customElements.define("my-container", MyContainer);
    customElements.define("gmail-item", GmailItem);
    </script>
    
    <my-container class="container-1">
      <gmail-item></gmail-item>
      <gmail-item></gmail-item>
    </my-container>
    
    <my-container class="container-2">
        <gmail-item></gmail-item>
        <gmail-item style="--my-status: magenta"></gmail-item>
    </my-container>