Web Components series - custom component style settings

Posted by morleypotter on Tue, 15 Feb 2022 11:40:02 +0100

preface

Through the previous study, we have a certain understanding of the relevant concepts and knowledge points of custom components. Today, let's learn several methods to set styles for custom elements and their sub elements.

Add styles directly to custom labels

index.html:

<style>
    my-card{
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
</style>
<my-card></my-card>
<script src="./index.js"></script>

index.js:

class MyCard extends HTMLElement {
    constructor() {
        super();
        this.shadow = this.attachShadow({ mode: "open" });
    }
}

window.customElements.define("my-card", MyCard);

Result style takes effect:

It should be noted that the custom element inherited from HTMLElement has style Display defaults to inline.

From the above results, it can be inferred that:

  1. Add a class to the user-defined element, and then set the style through the class name to take effect;
  2. Adding inline styles to custom elements can take effect;
  3. Add a style to this in the custom element constructor to take effect.

Style the child elements inside the custom element

Set in the main DOM by class name

Add the following styles to the style tag:

<style>
    my-card {
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
    .card-header {
        padding: 10px;
        font-weight: bold;
        background-color: yellow;
    }
</style>
<my-card></my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});

            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }
    window.customElements.define("my-card", MyCard);
</script>

Result: not effective.

From the previous study, we know that the custom element is actually a Shadow DOM, which is isolated from the main dom. Therefore, the style in the main DOM does not affect the Shadow DOM.

Use JS to add style label to Shadow DOM

There are two scenarios: using JS in the main DOM and using JS in the Custom Elements constructor.

The first method: use JS in the main DOM to add a style label to the Shadow DOM:

<style>
    my-card {
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
</style>
<my-card>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});

            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }
    window.customElements.define("my-card", MyCard);
    // Add style label to Shadow DOM
    let styleEle = document.createElement("style");
    styleEle.textContent = `
        .card-header{
            padding:10px;
            background-color: yellow;
            font-size: 16px;
            font-weight: bold;
        }
    `;
    document.querySelector("my-card").shadowRoot.appendChild(styleEle);
</script>

The effect is as follows:

The second method: use JS to add the style tag in the Custom Elements constructor:

<style>
    my-card {
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
</style>
<my-card>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});
            let styleEle = document.createElement("style");
            styleEle.textContent = `
                .card-header{
                    padding:10px;
                    background-color: yellow;
                    font-size: 16px;
                    font-weight: bold;
                }
            `;
            this.shadow.appendChild(styleEle);


            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }
    window.customElements.define("my-card", MyCard);
</script>

The effect is as follows:

In terms of the above two methods, the second one is more in line with the characteristics of componentization. When using the first method, it should be noted that if the code adding the style tag is placed before defining Custom Elements, an error will be reported (the custom element cannot be found).

Importing CSS files

Here, JS is used to create the link tag, and then CSS files are introduced to set styles for the child elements inside the custom element. The code is as follows:

<style>
    my-card {
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
</style>
<my-card>
</my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});
            let linkEle = document.createElement("link");
            linkEle.rel = "stylesheet";
            linkEle.href = "./my_card.css";
            this.shadow.appendChild(linkEle);


            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }
    window.customElements.define("my-card", MyCard);
</script>

my_card.css code is as follows:

.card-header{
    padding:10px;
    background-color: yellow;
    font-size: 16px;
    font-weight: bold;
}

The effect is as follows:

Of course, here you can also use JS in the main DOM to introduce CSS files into the Shadow DOM. However, this does not conform to the characteristics of componentization, so it is omitted.

Concluding remarks

The above is a summary of the basic methods of styling custom elements and their child elements.

~

~End of this article, thank you for reading!

~

Learn interesting knowledge, make interesting friends and shape interesting souls!

Hello, I'm Programming samadhi Hermit Wang, my official account is " Programming samadhi "Welcome to pay attention and hope you can give us more advice!

Topics: Javascript