iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
Modern Web

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

web component 組件庫實做建議-CSS篇

  • 分享至 

  • xImage
  •  

先說聲抱歉,本篇和下一篇都是以實做"VanillaJS"版本的web component組件庫為前提。大部分的web component編輯指引都建議使用lit-element之類的函式庫建立組件庫,現在還在使用VanillaJS來建立web component的組件庫幾乎只能說是一種浪漫了?

現代UI組件庫的需求

現代的UI用組件庫不管是跨框架的(bootstrap,tailwindcss,),還是單一框架的(antd.js,mui.js,element-ui),幾乎都有以下二個主要需求。

  1. 跨組件能共用某些CSS設定。
  2. CSS設定本身能有一定的客製化。(tailwindcss也可以算是能客製化啦...)

解法1-CSS變數

CSS變數是滿足上面的二個主要需求的最簡單寫法,因為CSS變數是會自動繼承到所有的子節點。也能讓Shadow DOM裡的節點使用

注意事項

CSS變數都會搭配使用var(),但在使用時建議設定fallback value,畢竟使用者不一定會想設定CSS變數。

.primary-text {
    color: var(--primary-color, #00a0e9);
}

缺點

關鍵或是常用的參數設定CSS變數還可以(比方說--primary-color),如果要大量客製化,參數的設定會讓人頭皮發麻。

解法2-CSSStyleSheet

CSSStyleSheet這個物件是用來讓javascript可以生成CSS的樣式表。在Shadow DOM中使用的話,有以下幾個方便的地方。

  1. 每個Shadow DOM可以掛許多個sheet,就像是把CSS模組化了一樣。(但CSS還是會互相污染就是了)
  2. 如果讓sheet在web component以外建立,當sheet的規則有變動時,也會連帶影響Shadow DOM

這個物件意外的很早就在各個瀏覧器中實做完成了,連古老的IE9都能使用(有些語法比較不一樣就是了),我是直到學習web component時才知道有這玩意的存在。

在web component裡使用的方法

HTML

<body>
    <my-div></my-div>
    <button id="btn1">style1</button>
    <button id="btn2">style2</button>
</body>

javascript

const sheet1 = new CSSStyleSheet();
sheet1.replaceSync('div { width: 100px; height: 100px; border: 1px solid black }');
const sheet2 = new CSSStyleSheet();
class MyDiv extends HTMLElement {
    constructor() {
        super();
        const shadow = this.attachShadow({mode: 'open'});
        const div1 = document.createElement('div');
        div1.className = 'div1';
        shadow.appendChild(div1);
        const div2 = document.createElement('div');
        div2.className = 'div2';
        shadow.appendChild(div2);
        // 可以附加多個sheet
        shadow.adoptedStyleSheets = [sheet1, sheet2];
    }
}
// customElements.define('my-div', MyDiv)
window.customElements.define('my-div', MyDiv)
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
btn1.addEventListener('click', () => {
    // 增加規則,Shadow DOM內的節點也會被影響
    sheet2.insertRule('.div1 { background-color: aqua; }');
})
btn2.addEventListener('click', () => {
    sheet2.insertRule('.div2 { background-color: red; }');
})

CSSStyleSheet的常用語法

因為和web component沒有直接關係,請直接參考MDN的說明,下面只會列出和web component比較有關的語法

  1. shadow.styleSheets:列出shadow DOM內使用的CSSStyle的列表。

  2. shadow.styleSheets[index].cssRules:列出shadow DOM內使用的某一個CSSStyle內含有的所有CSS規則。

  3. shadow.styleSheets[index].replace(ruleText):把shadow DOM內某一個CSSStyle內含有的所有CSS規則用新的CSS規則全部更換

  4. shadow.styleSheets[index].insertRule(ruleText):把shadow DOM內某一個CSSStyle新增CSS規則。

  5. shadow.styleSheets[index].deleteRule(index):把shadow DOM內某一個CSSStyle的某一條規則刪除。


上一篇
web component 的實做- 實做組件庫或大量使用web component的建議
下一篇
web component 組件庫實做建議-大型複合組件
系列文
web component - 次世代網頁技術的重要拼圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言