原文链接: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插件里开始实施,并打算推广开来。

你有什么好的想法可以让跨生态跨项目跨技术栈的组件复用更加惬意,可以交流交流。

Scoped CSS规范草案的更多相关文章

  1. Atitit.css 规范 bem  项目中 CSS 的组织和管理

    Atitit.css 规范 bem  项目中 CSS 的组织和管理 1. 什么是BEM?1 1.1. 块(Block)2 1.2. 元素(Element)2 1.3. BEM树(和DOM树类似).3 ...

  2. 前端CSS规范整理_转载、、、

    一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用U ...

  3. 瞬间从IT屌丝变大神——CSS规范

    CSS规范主要包括以下内容: CSS Reset用YUI的CSS Reset. CSS采用CSSReset+common.css+app.css的形式. app.css采用分工制,一个前端工程师负责一 ...

  4. [转]前端CSS规范整理

    一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core  通用 ...

  5. 新手不得不注意HTML CSS 规范

    作为一名新进的程序菜鸟,根本不知道从哪里开始学起好,前辈都说HTML CSS 规范是一个十分需要注意的点,要我记下,特地转来保存一下,大家相互学习 //总论 本规范既然一个开发规范,也是一个脚本语言参 ...

  6. 前端CSS规范大全

    一.文件规范 1.文件均归档至约定的目录中(具体要求以豆瓣的CSS规范为例进行讲解): 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用 ...

  7. Web前端开发中的各种CSS规范

    Reference: http://yusi123.com/2866.html 一.文件规范 1.文件均归档至约定的目录中(具体要求以豆瓣的CSS规范为例进行讲解): 所有的CSS分为两大类:通用类和 ...

  8. 前端开发规范:命名规范、html 规范、css 规范、js 规范

    上周小组的培训内容是代码可读性艺术,主要分享如何命名.如何优化代码排版,如何写好的注释.我们都知道写出优雅的代码是成为大牛的必经之路. 下面感谢一位前端开发小伙伴总结的前端开发规范,通过学习相关开发规 ...

  9. Vue中scoped css和css module比较

    scoped css 官方文档 scoped css可以直接在能跑起来的vue项目中使用. 使用方法: <style scoped> h1 { color: #f00; } </st ...

随机推荐

  1. Hadoop的安装与设置(1)

    在Ubuntu下安装与设置Hadoop的主要过程. 1. 创建Hadoop用户 创建一个用户,用户名为hadoop,在home下创建该用户的主目录,就不详细介绍了. 2. 安装Java环境 下载Lin ...

  2. 跟着老男孩教育学Python开发【第二篇】:Python基本数据类型

    运算符 设定:a=10,b=20 . 算数运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 基本数据类型 1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**3 ...

  3. CSS命名规范——BEM思想(非常赞的规范)

    人们问我最多的问题之一是在CSS类名中“--”和“__”是什么意思?它们的出现是源于BEM和Nicolas Gallagher... BEM的意思就是块(block).元素(element).修饰符( ...

  4. C#执行异步操作的几种方式比较和总结

    C#执行异步操作的几种方式比较和总结 0x00 引言 之前写程序的时候在遇到一些比较花时间的操作例如HTTP请求时,总是会new一个Thread处理.对XxxxxAsync()之类的方法也没去了解过, ...

  5. 如何在高并发分布式系统中生成全局唯一Id

    月整理出来,有兴趣的园友可以关注下我的博客. 分享原由,最近公司用到,并且在找最合适的方案,希望大家多参与讨论和提出新方案.我和我的小伙伴们也讨论了这个主题,我受益匪浅啊…… 博文示例: 1.     ...

  6. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  7. Sass用法指南

    写在前面的话:随着CSS文件越来越大,内容越来越复杂,对其进行很好的维护将变的很困难.这时CSS预处理器就能够帮上大忙了,它们往往拥有变量.嵌套.继承等许多CSS不具备的特性.有很多CSS预处理器,这 ...

  8. 警告: [unchecked] 对作为原始类型IScheme的成员的write(TProt ocol,T)的调用未经过检查

    jdk 从8 改成了7 就好了! 或者, 修改源码, 每个响应的地方加上 surppressingWarnings xxx , 或者使用 请使用 -Xlint:unchecked 重新编译. 参照 h ...

  9. TCP三次握手的正确使用姿势

    背景 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 问题 有时候聊天的过程中,我的网络或者她的网络可能会不好,视频就会卡住,听不到对方的声 ...

  10. 大三作品:不需要售货员的超市? Easy-Shopping超市导购系统

    本来么,逛超市是一件很爽的事情,拉上父母孩子,推个大推车,一边聊一边买,然后开开心心的回家去. 可到了旺季,逛超市可就麻烦了,买东西人挤人,到结算的地方人山人海,一刷卡,我去,怎么这个卫生纸这么贵!这 ...