[Web Component] Allow External Styling of a Web Component's Shadow DOM

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>

上一篇:webpack之给目录起别名


下一篇:android – AppCompat ActionBar主题微调器下拉列表