Scoped CSS規範草案

来源:http://www.cnblogs.com/iamzhanglei/archive/2016/12/26/6222692.html
-Advertisement-
Play Games

原文鏈接: "https://github.com/AlloyTeam/AlloyTouch/wiki/Scoped CSS" 寫在前面 問:什麼是Scoped CSS規範? Scoped CSS規範是Web組件產生不污染其他組件,也不被其他組件污染的CSS規範。 面對組件化的普及,組件的復用很普遍 ...


原文鏈接:https://github.com/AlloyTeam/AlloyTouch/wiki/Scoped-CSS

寫在前面

問:什麼是Scoped CSS規範?

Scoped CSS規範是Web組件產生不污染其他組件,也不被其他組件污染的CSS規範。

面對組件化的普及,組件的復用很普遍的需求,然而CSS相互污染是經常遇見的問題,建立規範讓開發者放心使用各種組件,甚至跨生態的組件是很有必要的一件事情。

目前業界的一些方案

方案一:
如果用webpack的話,可以參考css-loader的這個功能:

一段hash + 組件名,這個可能兼顧了辨識度 + 命名污染的問題。

方案二:

用webpack和scss,less寫成模塊化css就可以一定程度避免CSS污染,不能完全避免

方案三:樣式規範上,使用與組件同名的嵌套命名空間

如果只用自己的生態可以這麼搞,但是有的時候會引入第三方生態,第三方和自己的命名空間一樣還是很有可能,比如scroller插件,社區里也有很多scroller插件loading uplader插件等等。

現有方案的局限性

這裡還是會有污染的情況,因為:

  • 模塊化的粒度是大於等於組件化粒度,意思就是一個模塊可能有多個組件
  • 非less和sass項目下的組件怎麼保證
  • 難以保證不污染第三方組件
  • 難以保證不被第三方組件污染
  • 同名組件的問題
  • 組件在第三方項目使用的問題
  • 組件自身生態閉環的問題

所以得出:

用意念或者規範約定不然註入程式自動化避免衝突

好處:

  • 能保證不污染別的組件並且不被被的組件污染可以更放心的復用
  • Scoped CSS規範是運行時產生唯一id~~ 永遠不會css碰撞
  • 返回的這個id那個指定給組件的頂層div就行,實施簡單

如果把這個過程放在構建過程就是工程問題。但是組件單獨抽離出來給第三方用,其實就是組件本身的問題。總之要保證:

  • 不污染第三方的項目或組件
  • 不被第三組件或項目污染(由於是層疊樣式,這個無法完全保證)

Scoped CSS代碼

;(function () {

    function scoper(css) {
        var id = generateID();
        var prefix = "#" + id;
        css = css.replace(/\/\*[\s\S]*?\*\//g, '');
        var re = new RegExp("([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)", "g");
        css = css.replace(re, function(g0, g1, g2) {

            if (g1.match(/^\s*(@media|@keyframes|to|from|@font-face)/)) {
                return g1 + g2;
            }

            if (g1.match(/:scope/)) {
                g1 = g1.replace(/([^\s]*):scope/, function(h0, h1) {
                    if (h1 === "") {
                        return "> *";
                    } else {
                        return "> " + h1;
                    }
                });
            }

            g1 = g1.replace(/^(\s*)/, "$1" + prefix + " ");

            return g1 + g2;
        });

        addStyle(css,id+"-style");
        return id;
    }

    function generateID() {

        var id =  ("scoped"+ Math.random()).replace("0.","");
        if(document.getElementById(id)){
            return generateID();
        }else {
            return id;
        }
    }

    var isIE = (function () {

        var undef,
            v = 3,
            div = document.createElement('div'),
            all = div.getElementsByTagName('i');

        while (
            div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
                all[0]
            );

        return v > 4 ? v : undef;

    }());

    function addStyle(cssText, id) {
        var d = document,
            someThingStyles = d.createElement('style');
        d.getElementsByTagName('head')[0].appendChild(someThingStyles);
        someThingStyles.setAttribute('type', 'text/css');
        someThingStyles.setAttribute('id', id);
        if (isIE) {
            someThingStyles.styleSheet.cssText = cssText;
        } else {
            someThingStyles.textContent = cssText;
        }
    }


    window.scoper = scoper;
})();

Scoped CSS實施

var id = scoper("h1 {\
               color:red;\
            /*color: #0079ff;*/\
                }\
        \
                /*  h2 {\
                color:green\
                }*/");

scoper返回的id,在組件的JS裡面賦給包裹的DOM便可以。這裡詳細說下生成id的過程:

function generateID() {
    var id =  ("scoped"+ Math.random()).replace("0.","");
    if(document.getElementById(id)){
        return generateID();
    }else {
        return id;
    }
}

通過Math.random得到隨機數並經過處理,然後通過document.getElementById去查詢頁面上有沒有同名ID,有的話則繼續重新生成,沒有的話就使用當前id。這裡需要特別註意的是,比如一些彈出層插件,display hide的時候有的組件是直接從body裡面移除,所以這就帶來了CSS碰撞的可能性,所以這裡Scoped CSS 規範強行約定:後插入的HTML,一定要經過scoper過程重新生成唯一id。
最後,Scoped CSS規範已經在AlloyTouch插件里開始實施,並打算推廣開來。

你有什麼好的想法可以讓跨生態跨項目跨技術棧的組件復用更加愜意,可以交流交流。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 標題 : <h1> - <h6> 2. 分割線 : <hr> 3. 加粗: <strong> 4. 斜體: <em> <i> 5. 段落 : <p> 6. 換行 : <br/> 7. 超鏈接: <a> href 屬性指定鏈接的地址 target ( 目標 ):_self ( 當前頁面打開 ) ...
  • 最近使用 "GitHub Pages" + "Jekyll" 搭建了 "個人博客" ,作為一名重度音樂患者,博客裡面可以不配圖,但是不能不配音樂啊。 遂在博客裡面引入了 網易雲模塊 ,這裡要感謝網易雲的分享機制,對開發者非常友好: 1.每首歌曲都支持生成外鏈播放器,且可以自定義顯示尺寸: 2.網易雲 ...
  • 說到浮動之前,先說一下CSS中margin屬性的兩種特殊現象 1, 外邊距的合併現象: 如果兩個div上下排序,給上面一個div設置margin-bottom,給下麵一個div設置margin-top,那麼兩個margin會發生合併現象,合併以後的值較大的那個。 對於這種現象一般不用處理。 2,ma ...
  • 1. 為什麼會有BFC和IFC 首先要先瞭解兩個概念:Box和formatting context; Box:CSS渲染的時候是以Box作為渲染的基本單位。Box的類型由元素的類型和display屬性決定,box的類型分為block-level box 和inline-level box(不包括cs ...
  • 一個字元串數組,{,a,b,1,110,111,13,2,23,22,23442,2645,345,34567,34,3487,5643,64545454,56457,7654564} 寫一個函數,返回結果為{1,2,34,5643,64545454,56457,7654564} 規律,數字判斷,如 ...
  • 1. returnDetail.$mount('#returnDetail'); 不用el 直接可以綁定數據到頁面的id上 作用區域不能交疊多個vue 實體 否則後面的vue 實體會失效。 2. vue created 運行在讀取data 之後, 綁定到數據之前, 如果不想顯示 {{}} 就可以在頁 ...
  • 1.audio自動播放 1 <audio src='xxx.mp3' autoplay></audio> 上面是audio標簽autoplay屬性是自動播放,但是在安卓部分瀏覽器和ios的safari是不會自動播放。在微信,安卓和ios大部分機子都可以知道播放。測試iphone5和iphone6s在 ...
  • 這是我前端生涯第一次和後臺對接,其經歷真是苦不堪言,多次絕處逢生,柳暗花明,可就是遲遲見不到那條村子。當然,最後我還是完成了這次對接。下麵來聊一聊我這白痴一般的經歷。 序章 話說天下大勢,分久必合,合久必分。2016年,程式員的角色已經有了很大的分化,後端、前端、移動端、演算法各領功能變數名稱家輩出,他們都是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...