<!--
Here the presentational syle is added
by the user, like any other html element.
-->
<todo-list>
  <todo-li>I have to do something...</todo-li>
  <todo-li>But i don't remember what.</todo-li>
  <todo-li>I don't care</todo-li>
</todo-list>

<todo-list class="Ugly">
  <todo-li>I have to do something...</todo-li>
  <todo-li>But i don't remember what.</todo-li>
  <todo-li>I don't care.</todo-li>
</todo-list>

<todo-list class="Beautiful">
  <todo-li>I have to do something...</todo-li>
  <todo-li>But i don't remember what.</todo-li>
  <todo-li>I don't care.</todo-li>
</todo-list> 
.Beautiful {
  border-radius: 10px;
  background-color: white;
  font-family: Arial;
  max-width: 300px;
  box-shadow: 0px 20px 30px rgba(0, 0, 0, 0.2);
}

.Beautiful todo-li {
  padding: 8px 16px 8px 8px;
  cursor: pointer;
}

.Beautiful todo-li:hover {
  color: orangered;
}


.Ugly {
  background-color: tomato;
  color: #fff;
  border-radius: 10px;
}

.Ugly todo-li {
  padding: 8px 16px 8px 8px;
  cursor: pointer;
}


todo-list + todo-list {
  margin-left: 30px;
}
/*
 * This web component is just a basic example.
 * It doesn't has accessibility things and the js code
 * is not optimized. 
 */
class TodoList extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: "open" });
  }


  connectedCallback() {
    this.setAttribute('role','listbox')
    
    const template = `
      <style>
        :host {
          display: block;
          overflow-x: hidden;
          overflow-y: auto;
        }
      </style>
      <slot>
        <p>
          Yeah! Nothing to do.
        </p>
      </slot>
    `;

    // this.shadow.innerHTML = template; // ShadowDOM
    this.shadow.innerHTML = template;
  }
}

window.customElements.define("todo-list", TodoList);



/*
 * This web component is just a basic example.
 * It doesn't has accessibility things and the js code
 * is not optimized. 
 */
class TodoLi extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: "open" });
  }


  connectedCallback() {
    this.setAttribute('role','option')
    const template = `
      <style>
        :host {
          display: flex;
        }

        label {
          display: contents;
          cursor: inherit;
        }

        input {
          margin-right: 8px;
        }
      </style>
      <input id="input" type="checkbox" />
      <label for="input">
        <slot></slot>
      </label>
    `;

    // this.shadow.innerHTML = template; // ShadowDOM
    this.shadow.innerHTML = template;
  }
}

window.customElements.define("todo-li", TodoLi);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.