Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

预处理器支持CSS的@support的可能性 #24

Open
hax opened this issue Jun 29, 2015 · 19 comments
Open

预处理器支持CSS的@support的可能性 #24

hax opened this issue Jun 29, 2015 · 19 comments
Labels

Comments

@hax
Copy link
Owner

hax commented Jun 29, 2015

@supports (text-shadow: 0 0 .3em gray) { 
    h1 {
        color: transparent;
        text-shadow: 0 0 .3em gray; 
    }
}

可编译为:

:root[data-cssrules-1] h1 {
  ...
}
cssSupports('text-shadow: 0 0 .3em gray')

let id = 0
function cssSupports(cssDecl) {
  let e = document.createElement('div')
  e.style.cssText = cssDecl
  if (e.style.cssText === cssDecl) {
    document.documentElement.dataset[`cssrules-${++id}`] = true
  }
}

注意:

  • 此代码为简单想法,未经验证。
  • :root应该可获得优化从而解决属性选择器慢的问题。
  • :root排除了所有不支持:root的老浏览器如IE6,我们一般可假设所有需要@supports的特性均是IE6不支持的。
  • 编译后specificity增加了2个类/伪类,可简单的在所有选择器前添加:root:root以保持一致。
  • cssText赋值实际会重新格式化,且需要考虑简写属性被展开为多个属性的情况。
@hax hax added the 笔记 label Jun 29, 2015
@hax hax changed the title 支持CSS的@support的可能性 预处理器支持CSS的@support的可能性 Jun 29, 2015
@Justineo
Copy link

先检查 e.style[prop] 是不是 undefined 确定支不支持属性,然后赋值完看值是不是 '' 来决定支不支持属性值?

@hax
Copy link
Owner Author

hax commented Jun 29, 2015

@Justineo 是应该这样。本文只是列一个初步的结构。话说你知道有什么预处理器支持@supports的转换吗?

@cssmagic
Copy link

理论上是可行的,不过实际操作会遇到一些问题。参考以下代码:

var decl = 'margin: 0 0 0 0'
document.body.style.cssText = decl
console.log(document.body.style.cssText)  // => 'margin: 0px;'

这样写着写着发现要在前端实现一套 CSS 属性解析器了。

如果需要 JS 参与的话,大多数人应该会选择 Modernizr 这样的方案吧。


不好意思,第一次读此文时没有看到这一句(道理类似):

cssText赋值实际会重新格式化,且需要考虑简写属性被展开为多个属性的情况。

@cssmagic
Copy link

:root 排除了所有不支持 :root 的老浏览器如 IE6,我们一般可假设所有需要 @supports 的特性均是 IE6 不支持的。

IE9 才支持 :root。当然这问题也不大。

编译后specificity增加了2个类/伪类,可简单的在所有选择器前添加 :root:root 以保持一致。

:root 自己也可能会有样式。预处理器(或后处理器)无法获知某个选择符是否是 :root 本身。这是一个大问题。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@cssmagic

所有在选择器里明确写出:roothtml的是可以知道的。问题在于没有它们的class选择器或属性选择器之类的。一个粗暴的办法是所有选择器前加两种 :root:root——
:root:root.xxx, :root:root .xxx { ... } 。(为了不支持 :root 的浏览器,可改为 .-pc-root。)

更简单的办法是要求所有针对根的样式规则明确写出:root,以及减少这样的样式(写到body上去)。这可视为一个limitation,好在写到root上样式的use cases比较少。我们最常见的一种用法是Modernizr。而本方式实际上是取代Modernizr的特性class方式的。而针对user-agent的hack也可以通过扩展一个类似@supports的机制达成。

@Justineo
Copy link

@hax 好像没有耶,这个除了 CSS 以外还要引入 JS,预处理器一般都不会有这个吧。

@cssmagic 用我说的方法应该不需要处理 cssText 格式了。Modernizr 对开发 CSS 代码是不透明的,而且 @supports 可以查询的 CSS feature 要比 Modernizr 细吧。样式是不是 :root 本身在编译时肯定判断不了,但是也不是不能解决:

:root[data-cssrules-1] h1,
h1:root[data-cssrules-1] {
  // ...
}

只是感觉丑陋了点...不然就是得限制只能用 html 或者 :root 而不能用 class 或者其他选择器。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@Justineo 嗯,我正是觉得现有的预处理器只能编译出css,是大大削弱了其能力啊,尤其是polyfill的能力。

@sapjax
Copy link

sapjax commented Jun 30, 2015

在Shadow DOM里面的样式应该也有问题,:root[data-cssrules-1] h1 没有对跨边界做处理。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@sapjax shadow dom 本来就不该处理啊。

@sapjax
Copy link

sapjax commented Jun 30, 2015

@hax 额,难道我理解错了?
你给文档的根节点加属性选择器,然后通过属性选择器来匹配后代节点, 如果我的一个css文件样式是应用到shadow dom内部的,使用了@support,这样转换之后,:root[data-cssrules-1] h1就不能匹配到shadow dom内部的元素了啊(预处理的时候,实际上是无法知道css要应用到什么地方的)。

不过存在一种状况是:可能不支持@support和不支持shadow dom的浏览器有很大一部分是重合的,那么反而没有问题了。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@sapjax shadow dom本来就是要特殊语法的啊,比如/deep/之类的。它跟其他特性是正交的。

@sapjax
Copy link

sapjax commented Jun 30, 2015

@hax
我指的是那些本身就在shadow dom内部的样式, 开发的时候可能是一个独立css文件,最终会在本地编译或者执行时inlineshadow domshadow root中。

这样的样式因为意图是只作用于shadow dom内部,并不存在跨作用域边界的需求,所以是不需要写/deep/的,但是经过你上面的处理后,反而需要写/deep/才能保持原来的样式生效,并且改变了语义,作用到所有的元素上去了,因为css预处理器是不知道shadow domnodeName是什么的。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@sapjax 我理解你的意思了。shadow dom的样式应该需要单独处理,比如把 :root 换成 :host 之类的?

@sapjax
Copy link

sapjax commented Jun 30, 2015

@hax 嗯,但是问题是没有办法给:host对应的节点增加[data-cssrules-1]这样的属性了,因为无法确定:host对应的节点是什么。

@hax
Copy link
Owner Author

hax commented Jun 30, 2015

@sapjax 嗯,scoped style跟本方法的假设是矛盾的。

不过如你所言,shadow dom的支持浏览器基本上是@supports的真子集。且shadow dom没有比较可靠的polyfill。所以几乎可以不管这个事情。

@yisibl
Copy link

yisibl commented Oct 26, 2015

所以这个想法是我之前说的提供 「浏览器运行时」 的 CSS 处理器?:ghost:

@yisibl
Copy link

yisibl commented Oct 26, 2015

@hax
Copy link
Owner Author

hax commented Nov 4, 2015

@yisibl 这个并不是运行时的css processor,只是一个需要运行时配合的css processor 😹

@yisibl
Copy link

yisibl commented Nov 4, 2015

@hax 😂 我差不多就是这个意思。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants