Set lightDOM style

https://stackoverflow.com/questions/59431342/web-components-extend-native-elements-style#

by Danny Engelman

HTML

<h3>Set light DOM style of Customized Built-in Element - <a href="https://stackoverflow.com/questions/59431342/web-components-extend-native-elements-style#">StackOverflow question</a></h3>

<style>
  /* (1) set style with global CSS */
  button {
    border: 2px solid black;
    padding: .5em;
  }

  [is="fancy-button"]:hover {
    /* color not applied because the (3) #id selector has higher Specificity */
    color: blue;
    /* background not applied because the (2) style has higher Specificity */
    /* but !important forces CSS */
    background: green !important;
    border-color: gold;
  }
</style>

<!-- !! Customized Built-In Elements !! -->
<button is="fancy-button" color="white">Hello Button #1</button>
<button is="fancy-button" color="gold">Hello Button #2</button>
<button>Hello Button #3</button>

<script>
  document.addEventListener('click', evt => alert(`clicked:` + evt.target.id));

  class FancyButton extends HTMLButtonElement {
    constructor() {
      super();
    }
    connectedCallback() {
      // (2) set style on element
      this.style.background = 'red';

      // (3) set style with scoped CSS using unique id value
      // (since there is no shadowDOM STYLE could be injected anywhere in the page)
      this.id = 'id' + Math.random() * 1e18; // 'id'+ because css selector can't be a number
      let stylerules = `#${this.id}{color:${this.getAttribute('color')}}`;
      this.appendChild(document.createElement('STYLE')).innerHTML = stylerules;
    }
  }

  customElements.define('fancy-button', FancyButton, { extends: 'button' });
</script>

CSS

body {
  font-family: arial;
}