[译]5分钟介绍Styled Components

CSS很奇怪,你花上15分钟就可以学会它的基础,但是需要花费数年才能想到一个好方法来组织你的样式。

造成上述问题的原因有一部分是语言本身的怪癖。除了盒模型以外,CSS是很局限的:没有变量、循环或者函数。同时,它又允许你使用元素、类、ID或者它们的组合来改变样式。

混乱的样式表

你可能已经亲身经历过,样式表常常是造成混乱的原因。尽管像SASS、LESS这种预处理语言添加了很多好用的特性,但是他们依旧没有有效地阻止CSS变混乱。

于是组织代码的任务就留给了像 BEM这样的方法,虽然很有效,但是它完全是自选方案,不能被强制应用在语言或者工具层面。

CSS新浪潮

最近几年,基于JavaScript的新工具正试图通过改变CSS的书写方式,从根本上解决这些问题。

Styled Components 就是其中之一,因为既具备创新性同时保留了编码习惯,它很快吸引了大量的关注。因此如果你正在使用React(如果没有,看看我的JS学习计划 和我的 React简介),你一定要看看这个CSS新方式。

我最近在用它重构我的个人网站,今天我想把我在重构过程中学到的东西在这里分享一下。

组件,样式化

关于Styled Components您首先要理解的是——正如它的名字所表示的——样式化的组件。 你不必再根据类名或HTML元素来为HTML元素或组件写样式了:

1
<h1 className="title">Hello World</h1>
1
2
3
4
h1.title{
font-size: 1.5em;
color: purple;
}

相反,你定义具有自己的封装样式的样式化组件(styled components),然后就可以自由地在你的代码中使用它:

1
import styled from 'styled-components';
1
2
3
4
const Title = styled.h1`
font-size: 1.5em;
color: purple;
`;
1
<Title>Hello World</Title>

这看上去有一些小的差异,而事实上两者的语法很相似。但它们的关键区别在于样式现在是组件的一部分了。

换句话说,我们正在摆脱 CSS 类名作为组件和其样式的中间步骤这种情况。

就像styled-components的联合创始人 Max Stoiber 所说:

styled-components的最基本思想就是通过移除样式和组件之间的映射来执行最佳实践”

减少复杂性

乍一看会感觉这是反直觉的,因为使用CSS而不直接用带样式的html元素(还记得 <font>标签吗)的重点就是通过引用中介类名来解耦样式和标记。

但是这种解耦也带来了很多的复杂性,而且与CSS相比,像JavaScript这样的“真正”的编程语言可以更好地处理这种复杂性。

用属性(Prop)代替类名(Class)

为了遵循“去类名”(no-classes)的理念,当需要定义一个组件的行为时,styled-component使用属性而不是类名。因此不应该用如下方式:

1
<h1 className="title primary">Hello World</h1> // will be blue
1
2
3
4
5
6
7
8
h1.title{
font-size: 1.5em;
color: purple;
&.primary{
color: blue;
}
}

你应该这样写:

1
2
3
4
const Title = styled.h1`
font-size: 1.5em;
color: ${props => props.primary ? 'blue' : 'purple'};
`;
1
<Title primary>Hello World</Title> // will be blue

就像你看到的, styled-components通过封装所有CSS和HTML相关的实现细节来让您的组件更加干净。

也就是说,样式组件的CSS仍然是CSS。这样的代码也是完全有效的(尽管平时不这么用):

1
2
3
4
5
6
7
8
const Title = styled.h1`
font-size: 1.5em;
color: purple;
&.primary{
color: blue;
}
`;
1
<Title className="primary">Hello World</Title> // will be blue

这个特性让styled-components很容易被接受:当它被怀疑的时候,你同样可以使用你熟悉的方法去使用它!

注意事项

值得注意的是,styled-components还只是一个年轻的项目,很多新的特性还没有被完全支持。例如,如果你想从父组件中为子组件添加样式,你现在需要先使用CSS类名(至少要等到styled-components的v2版本出来才可以实现)。

这里同样还没有在服务端预渲染你的CSS“官方途径”,虽然通过手动注入样式肯定是可以实现的。

并且,styled-component会生成随机的类名,这会导致很难用浏览器调试出你是在哪里定义的样式。

但是令人振奋人心的是 styled-components的核心成员意识到了所有这些问题,并且正在努力地逐一修复它们。 第二个版本即将发布,还有点小期待呢!

了解更多

我的目标不是详细解释styled-components是如何工作的,而是给您简单的介绍他的特性,以便您自己决定是否使用它。

如果我已经激发了你的好奇心,你可以通过以下方式了解更多:

如果你想要了解更多,你还可以看看 Glamor,它是CSS新浪潮的另一种实现方式