The Shadow DOM protects your components from style conflicts. The same protection also makes it hard for users to modify the inner style for their own needs. In this lesson we go over 3 ways to define API for a controlled manipulation of encapsulated styles.
<style> custom-element { --text-color: purple; // Define a variable for the color } div.text { color: red !important; text-decoration: underline; font-size: 36px; } </style> <template> <style> .text { color: var(--text-color, blue); // set 'blue' as default value text-decoration: overline; font-size: 28px; } </style> <div class="text"> In the Shadow </div> </template> <script> const template = document.querySelector('template'); class CustomElement extends HTMLElement { constructor() { super(); this.attachShadow({mode: "open"}); this.shadowRoot.appendChild(template.content.cloneNode(true)); } // allow to use javascript to change the style changeStyles(styles) { const textElement = this.shadowRoot.querySelector('.text'); Object.keys(styles).forEach(styleKey => { textElement.style[styleKey] = styles[styleKey]; }) } // listen for the attributes changes, here only listening 'color', 'text-decoration' static get observedAttributes() { return ['color', 'text-decoration']; } // Once the attribute changes, apply the style attributeChangedCallback(attribute, oldValue, newValue) { this.changeStyles({[attribute]: newValue}); } } window.customElements.define('custom-element', CustomElement); </script> <custom-element></custom-element> <div class="text">Outside the shadow</div>
<iframe height="240" src="https://embed.plnkr.co/H0Lhfb8pAUKcybeY2gIa/" style="width: 100%; height: 500px;" width="320"></iframe>