不要再在JavaScript中写CSS了

本文作者是 react-css-modules 和 babel-plugin-react-css-modules 的作者。并不是对 CSS in JavaScript: The future of component-based styling,或是使用样式组件的反对,而是一种补充,web 开发者要了解自己的需求,明白自己使用 styled-components 的真正原因。

9 个谎言

CSS 不应随意放置。许多项目选择将样式写在 JavaScript 中的理由不对。本文列出了常见的误解,以及解决问题的现存 CSS 方案。

本文的任何言论都没有对某个项目或人进行人身攻击的意思。styled-components 是 React 的目前趋势,所以我将 styled-components 定义为“JavaScript 中的 CSS”。

styled-components 的发起人(Max Stoiber、Glen Maddern 以及所有的贡献者)都很聪明、想法独特,出发点也是好的。

为了完全透明,我还要指出我是 react-css-modules 和 babel-plugin-react-css-modules 的作者。

小红帽

CSS 和 JavaScript 历史

层叠样式表(CSS)是为描述标记语言文档的展现样式而出现的。JavaScript 是为了组合图片、插件等组件而创造的一种“胶水语言”。随着发展,JavaScript 拓展、转变,有了新的应用场景。

Ajax 的出现(2005)是一个重要的里程碑。这时 Prototype、jQuery、MooTools 等库已经吸引了大量的拥护者,共同解决后台跨浏览器数据获取问题。这又引发了新的问题:如何管理数据?

到了 2010 年,Backbone.js 出现,成为了应用状态管理的行业标准。不久后,Knockout 和 Angular 双向绑定的特点吸引了所有人。之后,React 和 Flux 出现,开启了单页应用(SPA)的新纪元,组件构造应用。

那么 CSS 呢?

借用 styled-components 文档中的话:

纯 CSS 的问题在于它产生的那个时代,网站由文档组成。1993 年,网站产生,主要用于交换科学文献,CSS 是设计文献样式的解决方案。但是如今我们构建的是丰富的、面向用户的交互应用,而 CSS 并不是为此而生的。

我不这么认为 。

CSS 已经发展到可以满足现代 UI 的需求了。过去十年中出现的新特性数不胜数(pseudo-classes、pseudo-elements、CSS variables、media queries、keyframes、combinators、columns、flex、grid、computed values 等等)。

从 UI 的角度看,“组件”是文档中一个独立的片段(

 

首先——关系不大。差异基本可以忽略。

其次,说的也不对。字符数量取决于样式命名。

 
 
 
 

这同样适用于本文之后的构造样式(Myth 5:给组件设置条件样式更简单)。styled-components 只是在多数基本组件的情况下稍胜一筹。

Myth 3:styled-components 使人更关注语义化

前提就不对。样式和语义化代表着不同的问题,需要不用的应对方案。引用 Adam Morse(mrmrs)的话:

内容语义化和视觉样式 没有半点关系。当我用乐高建造东西时,我从来不会想“这是引擎的一部分”,我想着“这是个 1×4 的蓝色乐高,我用来随便做什么都行”。不论水下潜水基地还是飞机——我清晰地知道怎么用这个乐高块。

– http://mrmrs.io/writing/2016/03/24/scalable-css/

(强烈建议读一读 Adam 关于 可拓展 CSS 的文章)

我们还可以举个例子看看两者是否相关。

示例:

 
 
 
  1.   
  2.     Foo
  3.     Bar
  4.   
  5.  

语义化是要使用正确的标签构造标记。你能知道这些组件会渲染成什么 HTML 标签吗?不,你不知道。

和下面这段代码比较下:

 
 
 
    1.   
    2.     Foo
    3.     Bar
    4.   
     

Myth 4:拓展样式更容易

v1 版本可以用 styled(StyledComponent) 拓展样式;v2 引进了 extend 方法来拓展已存在的样式,比如:

 
 
 
  1. const Button = styled.button`
  2.   padding: 10px;
  3. `;
  4. const TomatoButton = Button.extend`
  5.   color: #f00;
  6. `; 

这挺好。但是你可以在 CSS 中完成(或者使用 CSS 模块组合 或 SASS 继承混合 @extend)。

 
 
 
  1. button {
  2.   padding: 10px;
  3. }
  4. button.tomato-button {
  5.   color: #f00;

难道不比 JavaScript 简单?

Myth 5:给组件设置条件样式更简单

这点是说你可以根据组件属性给组件设置样式,比如:

 
 
 
  1.  

这在 React 中很有用。毕竟组件行为就是由属性控制的。给属性值直接绑定样式有意义吗?可能吧。但是来看看组件的实现代码:

 
 
 
  1. styled.Button`
  2.   background: ${props => props.primary ? '#f00' : props.secondary ? '#0f0' : '#00f'};
  3.   color: ${props => props.primary ? '#fff' : props.secondary ? '#fff' : '#000'};
  4.   opacity: ${props => props.active ? 1 : 0};
  5. `; 

利用 JavaScript 按条件创造样式表是挺强大的,但是这也意味着样式难以理解,对比以下 CSS:

 
 
 
  1. button {
  2.   background: #00f;
  3.   opacity: 0;
  4.   color: #000;
  5. }
  6. button.primary,
  7. button.seconary {
  8.   color: #fff;
  9. }
  10. button.primary {
  11.   background: #f00;
  12. }
  13. button.secondary {
  14.   background: #0f0;
  15. }
  16. button.active {
  17.   opacity: 1;

这样 CSS 更简短(229 VS 222 字符),(个人认为)也更容易理解。此外,还可以用预处理器使 CSS 分组、更短:

 
 
 
  1. button {
  2.   background: #00f;
  3.   opacity: 0;
  4.   color: #000;
  5.   
  6.   &.primary,
  7.   &.seconary {
  8.     color: #fff;
  9.   }
  10.   &.primary {
  11.     background: #f00;
  12.   }
  13.   &.secondary {
  14.     background: #0f0;
  15.   }
  16.   &.active {
  17.     opacity: 1;
  18.   }

Myth 6:有利于代码组织

有些人告诉我他们喜欢 styled-components,因为它可以让样式和 JavaScript 在一个文件中。

我理解同一组件有许多文件很烦,但是把样式和标记塞进一个文件的方法很糟糕。这样不仅版本控制难以回溯,而且所有组件都需要滚动很长一段距离,而不是简单地点下按钮。

如果一定要把 CSS 和 JavaScript 放在一个文件中, 可以考虑使用 css-literal-loader。它可以在 build 时用 extract-text-webpack-plugin 提取 CSS,用标准 loader 配置处理 CSS。

Myth 7:DX 很方便,这工具太棒了!

很明显你没用过 styled-components。

Myth 8:性能更好,bundle 更小

Myth 9:它可以开发响应式组件

这说的是依据环境给组件设置样式的能力,比如父容器偏移量、子元素数量等。

首先,styled-components 和响应式没什么关系。这已经超出了这个主题的范围。这种情况最好直接设置组件的 style,以避免额外的成本。

但是,元素查询是个有趣的问题,也逐渐成为 CSS 中的一个高热话题,主要是 EQCSS 等类似项目。元素查询和 @media queries 在语法上很相似,只是元素查询操作具体某些元素。

 
 
 
  1. @element {selector} and {condition} [ and {condition} ]* { {css} }

{selector} 是 CSS 选择器对应着一或多个元素。例如:#id 或 .class

{condition} 由尺寸和值组成。

{css} 可以包含:任何合法的 CSS 规则。(例如:#id div { color: red })

元素查询可以用 min-width、max-width、min-height、max-height、min-characters、max-characters、min-children、max-children、min-lines、max-lines、min-scroll-x、max-scoll-x 等 (详见 http://elementqueries.com/)条件给元素设置样式。

总有一天类似 EQCSS 的内容也会出现在 CSS 标准中的(希望如此)。

等下!

大部分内容都长期有效,无论是社区、React 变更或 styled-components 本身。但意义何在?CSS 已被广泛支持,有大量的社区,也确实行之有效。

本文的目的并不是阻止读者在 JavaScript 中使用“CSS”或是 styled-components。styled-components 一个很棒的使用场景是:更好的跨平台支持性。不要因为错误的理由使用它。

那么我们应该用什么呢?

使用 Shadow DOM v1 还为时尚早(51% 支持率)。CSS 应遵循命名协议(建议 BEM),如果担心类名冲突(或懒得用 BEM),可以用 CSS modules。如果你在开发 React web,考虑用 babel-plugin-react-css-modules。如果在开发 React Native,styled-components 更好。

分享题目:不要再在JavaScript中写CSS了
链接地址:http://www.shufengxianlan.com/qtweb/news12/390162.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

猜你还喜欢下面的内容

动态网站知识

分类信息网站