iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Modern Web

web component - 次世代網頁技術的重要拼圖系列 第 12

[Day11] web component 的使用技巧-css

  • 分享至 

  • xImage
  •  

因為Shadow DOM把內部的DOM和外部的DOM分開了。所以CSS選擇器沒辦法從外部正常的使用在Shadow DOM的內部節點上。也因此,CSS的使用一直以來都是件麻煩的事情

比較正常的做法

把CSS寫入web component之中

在所有設定Shadow DOM CSS的方法中,最簡單也最常用的方法就是把CSS用style元素包起來後放入web component之中。但這種方式只能設定固定的CSS,會受限於客製化。

Web API中有一個名稱為"CSSStyleSheet"的物件,可以更系統化的寫入CSS,通常是用來設計library。

使用CSS 的屬性

Shadow DOM的限制只有選擇器無法使用。但CSS還是有些不用選擇器就能做出部分客製化的方法。

使用 inherit

inherit可以繼承父節點的參數。Shadow DOM內部的節點也可以繼承到web component根節點的參數。

使用 css 變數

如果說有什麽CSS 的設計可以讓全CSSOM都能使用,那就是CSS變數了。就算在Shadow DOM以外的部分設定CSS 變數,Shadow DOM內部的節點還是能使用CSS 變數。

使用 :host

本偽類只能在Shadow DOM內使用,使用起來就像是Shadow DOM 的':root'

HTML 屬性 + inline Style

直接把CSS寫入web compoent之中只適合不會變動的CSS,而使用inherit、CSS變數之類的方法能客製化的地方也很有限,如果需要動畫之類的即時效果,還是使用 web component 的屬性,再用監聽的屬性的方法來動態修改 inline style。

例子

HTML

<body>
    <main>
        <my-com id="my-com" content-color="yellow">
            <div id="slot">click</div>
        </my-com>
    </main>
</body>

CSS

#slot {
    color: blue;
}
body {
    color: purple;
    --card-content-color: red;
}

Javascript

class MyComponent extends HTMLElement {
    root = null
    style = `
        .card-title {
            color: inherit;
        }
        .card-content {
            color: var(--card-content-color, inherit)
        }
    `
    constructor() {
        super();
        this.render = this.render.bind(this);
        this.root = this.attachShadow({mode: 'open'});
        this.root.appendChild(this.render())
    }
    static get observedAttributes() {
        return ['content-color'];
    }
    attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'content-color') {
            this.root.getElementById('card-content2').style.color = newValue;
        }
    }
    render() {
        const template = document.createElement('template');
        //直接把固定的css寫入style元素之中
        template.innerHTML = `
            <style>${this.style}</style>
            <div class='card'>
                <h2 id='card-title' class='card-title'>title</h2>
                <div id='card-content' class='card-content'>content</div>
                <div id='card-content2' class='card-content2'>content2</div>
                <slot id='card-slot'></slot>
            </div>
        `;
        return template.content;
        //因為有寫inherit,'title'字體顏色為purple
        //因為有使用CSS變數,'content'字體顏色為red
        //因為有使用inline style,'content2'字體顏色為yellow
        //會同時使用web cpmponent 和slot的設定,'click'字體顏色為blue
    }
}
customElements.define('my-com', MyComponent);

上一篇
[Day10] web component的使用技巧-事件
下一篇
[Day12] web component 的歷史-那些己經廢除或不穩定的部分
系列文
web component - 次世代網頁技術的重要拼圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言