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-in-js 的行为》 #12

Closed
ascoders opened this issue May 5, 2017 · 4 comments
Closed

精读《请停止 css-in-js 的行为》 #12

ascoders opened this issue May 5, 2017 · 4 comments

Comments

@ascoders
Copy link
Owner

ascoders commented May 5, 2017

文章地址:https://hackernoon.com/stop-using-css-in-javascript-for-web-development-fa32fb873dcc

@ascoders ascoders mentioned this issue May 5, 2017
65 tasks
@ascoders
Copy link
Owner Author

ascoders commented May 10, 2017

本文作者最后也说了,他自己是个标题党,css-in-js 更适合跨平台场景使用,同时文章中提出的 css-in-js 的缺点,最致命问题都已补充解决方案(比如新特性,或者写作时完全不知道 css-in-js 也有 dev tools,或者 IDE 的支持)。

我认为 styled-component 更适合现在的前端规模。

第一,无论是 sass 还是 less 都有一套自己的语法,postcss 更支持了自定义语法,说实话我很抵触写这些自创出的语法,就像我们支持 jsx 而谨慎选择模版引擎一样,自创的语法最大特点就是雷同,格式又不一致,增加了无意义的学习成本。我有一个朋友做了一套类似 RN 的渲染引擎,但不是适配给 react 或者 vue 的,而是直接适配在原生 dom api,我们知道,这些引擎最终会将代码以标准 dom api 执行,从底层入手自然更加通用,所以我更希望学习和使用万变不离其宗的东西,而不愿意使用各种定制的“语法糖”来“提高效率”。

第二,作者提到的 css 标准仍在不断完善,所以对于 css 标准用法未来一定会越来越强,大家可以放心回归 css 的怀抱。我不反对这句话,但作者同时提到了,css-in-js 与 1993 年提出的网页设计思想所违背,其实 css2 在 1998 年才被创建的时候,人们无论如何也想不到网页会有今天的复杂度,当时的 css 设计满足的是当时的要求,换在今天诞生的话,css 绝对不是现在的样子,可能是 css-in-js 的形式展现出来。因此,以 css 建设的初心抨击 css-in-js 是完全不考虑当下前端开发环境的,在实际开发中没有指导意义,就像喝咖啡时侃侃而谈理想,出门左转还是得去搬砖一样,关了网页写码时,我们不得不重新考虑开发体验与平台兼容问题。

第三,就 css 变量与 js 通信而言,虽然草案已经考虑到了这一点,通过表达式与 attribute 通信,使用 jsattribute 同步。不难想象,这种情况维护的变量值最终是存储在 js 中更加妥当,然而 scss 给大家带来的 css first 思想根深蒂固,导致许多基础库的变量完全存储在 _variable.scss 文件中,现在无论是想适应 css 的新特性,还使用 css-in-js 都有巨大的成本,导致项目几乎无法迁移。反过来,如果变量存储在 js 中,就像草案中说的一样轻巧,你只要换一种方式实现 css 就行了。

@jasonslyvia
Copy link
Contributor

这篇文章表面是在讲 CSS in JS,实际上是 CSS Modules 支持者与 styled-components 拥趸之间的唇枪舌剑、你来我往。

我还记得当年 @camsong 在团队内推 CSS Modules 的时候列举了不少了 CSS 现有的问题,现在能想起来的包括书写繁琐(不支持嵌套)、样式易冲突(没有作用域概念)、缺少变量(不便于一键换主题)等不一而足。

为了解决这些问题,社区里的解决方案也是出了一茬又一茬,从最早的 CSS prepocessor(SASS、LESS、Stylus)到后来的后起之秀 PostCSS,再到 CSS Modules、Styled-Component 等。更有甚者,有人维护了一份完整的 CSS in JS 技术方案的对比,点开链接之前你猜猜现在囊括了多少种技术?截止 2017年05月10日11:33:08,这个数字是 49

在纷繁的解决方案背后,我们也应该思考一下选择,或者说考虑 CSS in JS 的初衷是什么?最痛的点是什么?选择这项技术之后会不会带来新的问题?目前看来 Styled-Component 并不完美,甚至对常规 Web 开发很不合适(理由 @ascoders 已经给出);即使是 CSS Modules,在团队的实践中也遇到了很多问题(全局样式覆盖困难,写到最后可能一直在用 :global ,与组件库无法配合等)。

因此,无论是 CSS Modules,还是 Styled-Component,还是上面那份列表中的另外 47 种方案,在决定使用之前务必要想起楚:你最想解决的问题是什么?

@camsong
Copy link
Contributor

camsong commented May 10, 2017

这篇作者是 react-css-modules 的作者,所以观点会有一些偏颇。但整体上我还是认可的,社区里流行的 css-in-js 有点过于理想主义,低估了 CSS 本身的能力和生态。

从 2014 年 Vjeux 的演讲开始,css-in-js 的轮子层出不穷。终于过了三年,鸡血时期已经慢慢过去,大家开始冷静思考了。

文中提到第1点,css-in-js 号称解决的命名空间和样式冲突的问题早已不是问题。第4点论扩展性我也觉得 CSS 占优,第5点需要设置条件样式我觉得 CSS 方案也是更好的,而且 CSS 会更易于调试。

css-in-js 有适用的场景,也有局限:

  1. 不适用于做样式需要定制的组件
    样式就像小孩的脸,说变就变。比如是最简单的 button,可能在用的时候由于场景不同,需要设置不同的 font-sizeheightwidthborder 等等,如果全部使用 css-in-js 那将需要把每个样式都变成 props,如果这个组件的 dom 还有多层级呢?你是无法把所有样式都添加到 props 中。同时也不能全部设置成变量,那就丧失了单独定制某个组件的能力。css-in-js 生成的 className 通常是不稳定的随机串,这就给外部想灵活覆盖样式增加了困难。
  2. 适用于偏逻辑型,样式比较少,且不太需要外部覆盖样式的场景。
    如果是要做一个组件库,让使用方拿着npm就能直接用,样式全部自己搞定,不需要依赖其它组件,如 react-dnd 这种,比较适合。
  3. 适用于 react-native 这类本身就没有 css 的运行环境。

我从15年开始在团队里推行过CSS Modules。总结过它的一系列优点
CSS Modules 能最大化地结合现有 CSS 生态和 JS 模块化能力,我喜欢它强制使用 BEM 的命名法来避免样式污染。但这也带来了它的缺点,可能因些而增加的 :global。还有组件给别人使用时需要使用方修改 webpack 配置 css-loader?modules

如果你过于在乎这些缺点的话建议你直接使用纯 SASS 或 CSS,尤其是 SASS 在现在仍然是很好的选择。

@huangfangrong
Copy link

灭掉CSS文件这个另类!

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

No branches or pull requests

4 participants