Scoped 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插件里开始实施,并打算推广开来。
你有什么好的想法可以让跨生态跨项目跨技术栈的组件复用更加惬意,可以交流交流。
Scoped CSS规范草案的更多相关文章
- Atitit.css 规范 bem 项目中 CSS 的组织和管理
Atitit.css 规范 bem 项目中 CSS 的组织和管理 1. 什么是BEM?1 1.1. 块(Block)2 1.2. 元素(Element)2 1.3. BEM树(和DOM树类似).3 ...
- 前端CSS规范整理_转载、、、
一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用U ...
- 瞬间从IT屌丝变大神——CSS规范
CSS规范主要包括以下内容: CSS Reset用YUI的CSS Reset. CSS采用CSSReset+common.css+app.css的形式. app.css采用分工制,一个前端工程师负责一 ...
- [转]前端CSS规范整理
一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用 ...
- 新手不得不注意HTML CSS 规范
作为一名新进的程序菜鸟,根本不知道从哪里开始学起好,前辈都说HTML CSS 规范是一个十分需要注意的点,要我记下,特地转来保存一下,大家相互学习 //总论 本规范既然一个开发规范,也是一个脚本语言参 ...
- 前端CSS规范大全
一.文件规范 1.文件均归档至约定的目录中(具体要求以豆瓣的CSS规范为例进行讲解): 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用 ...
- Web前端开发中的各种CSS规范
Reference: http://yusi123.com/2866.html 一.文件规范 1.文件均归档至约定的目录中(具体要求以豆瓣的CSS规范为例进行讲解): 所有的CSS分为两大类:通用类和 ...
- 前端开发规范:命名规范、html 规范、css 规范、js 规范
上周小组的培训内容是代码可读性艺术,主要分享如何命名.如何优化代码排版,如何写好的注释.我们都知道写出优雅的代码是成为大牛的必经之路. 下面感谢一位前端开发小伙伴总结的前端开发规范,通过学习相关开发规 ...
- Vue中scoped css和css module比较
scoped css 官方文档 scoped css可以直接在能跑起来的vue项目中使用. 使用方法: <style scoped> h1 { color: #f00; } </st ...
随机推荐
- Android之DOM解析XML
一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...
- samba服务
安装samba服务步骤ps -e 查看进程ps -e | grep 文件名 管道符的使用rpm -qa 安装包的查看rpm -qa | grep samba 抓Samba安装包 注释:包与包之间有依赖 ...
- 机器指令翻译成 JavaScript —— No.4 动态跳转
上一篇,我们用模拟流程的方式,解决了跳转问题. 不过静态跳转,好歹事先是知道来龙去脉的.而动态跳转,只有运行时才知道要去哪.既然流程都是未知的,翻译从何谈起? 动态跳转,平时出现的多吗?非常多!除了 ...
- 用命令行工具创建 NuGet 程序包
NuGet.exe 下载地址 本文翻译自: https://docs.nuget.org/Create/Creating-and-Publishing-a-Package https://docs.n ...
- SQL开发技巧(二)
本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...
- 如何扩展 Visual Studio 编辑器
在 Visual Studio 2010 的时代,扩展 Visual Studio 的途径有很多,开发者可以选择宏.Add-in.MEF 和 VSPackages 进行自定义的扩展.但是宏在 Visu ...
- ABP源码分析三十四:ABP.Web.Mvc
ABP.Web.Mvc模块主要完成两个任务: 第一,通过自定义的AbpController抽象基类封装ABP核心模块中的功能,以便利的方式提供给我们创建controller使用. 第二,一些常见的基础 ...
- Rxjava cold/hot Observable
create Observable分为cold以及hot两种,cold主要是静态的,每次subscribe都是从头开始互不干扰,而hot的在同一时刻获得的值是一致的 cold Observable 使 ...
- selenium自动化基础知识
什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...
- iOS 地图定位及大头针的基本使用
地图 Part1 - 定位及大头针的基本使用 一.MapKit 作用 : 用于地图展示 如大头针,路线,覆盖层展示等(着重界面展示) 使用步骤 导入头文件 #import <MapKit/Map ...