【译】统同样式语言

统同样式语言

在过去几年中,咱们见证了 CSS-in-JS 的兴起,尤为是在 React 社区。固然,它也饱含争议。不少人,尤为是那些已经对 CSS 很是熟悉的人都表示难以置信。android

"为何有人要在 JS 中写 CSS?webpack

这简直是一个可怕的想法!ios

希望他们学过 CSS !"git

若是这就是你的反应,那么请继续读下去。咱们来看看到底为何在 JavaScript 中编写样式并非一个可怕的想法,而且为何我认为你应该关注这个快速发展的领域。github

对社区的误解

React 社区常常被 CSS 社区误解,反之亦然。对我来讲这颇有趣,由于我常常混迹于这两个社区。

我从九十年代后期开始学习 HTML,而且从基于表格布局的黑暗时代以来就一直使用 CSS。受 CSS Zen Garden 启发,我是最先一批将现有代码向 语义化标签 和级联样式表迁移的人。不久以后,我开始专一于先后端分离,使用非侵入式 JavaScript 和客户端的交互来装饰服务端渲染的 HTML。围绕这些作法有一个小型且充满活力的社区,而且咱们成为第一代尝试给浏览器平台应有尊重的前端开发者。

伴随这样的背景,你可能会认为我会强烈反对 React 的 HTML-in-JS 模式,它彷佛违背了咱们所坚持的原则,但实际上偏偏相反。根据个人经验,React 的组件模型加上服务端渲染的能力,最终给咱们提供了一种构建大规模复杂单页应用的方式,从而使咱们可以将快速,可访问,逐渐加强的应用推送给咱们的用户。在 SEEK 上咱们就利用了这种能力,这是咱们的旗舰产品,它是 React 单页应用程序,当 JavaScript 被禁用时咱们的核心搜索流程依然可用,由于咱们经过在服务器端运行同构的 JavaScript 代码来完成到传统的网站优雅降级。

因此,也请考虑一下我抛出的从一个社区到另外一个社区的橄榄枝。让咱们一块儿尝试理解这个转变。它可能不完美,它可能不是你计划在产品中使用的东西,它可能对你不是颇有说服力,可是至少值得你尝试思考一下。

为何使用 CSS-in-JS?

若是你熟悉我最近作的与 React 以及 CSS 模块相关的工做,当看到我维护 CSS-in-JS 时你可能会很惊讶。

毕竟,一般那些但愿有局部样式可是又不但愿在 JS 中写 CSS 的开发者会选择使用 CSS 模块。事实上,甚至我本身在工做中也还没用到 CSS-in-JS。

尽管如此,我任然对 CSS-in-JS 社区保持浓厚的兴趣,对他们不断提出的创意保持密切关注。不只如此,我认为更普遍的 CSS 社区对它也应该很感兴趣

缘由是什么呢?

为了更清楚地了解为何人们选择在 JavaScript 中编写他们的样式,咱们将重点关注采用这种方式时带来的实际好处。

我把它分为五个方面:

  1. 局部样式

  2. 关键 CSS

  3. 智能优化

  4. 打包管理

  5. 在非浏览器环境下的样式

让咱们进一步的细分而且仔细看看 CSS-in-JS 提供的每一点优点。

1.

局部样式

想要在大规模项目中高效的构建 CSS 是很是困难的。当加入一个现有的长期运行的项目时,一般咱们会发现 CSS 是系统中最复杂的部分。

为了解决这个问题,CSS 社区已经投入了巨大的努力,经过 Nicole SullivanOOCSSJonathan SnookSMACSS 均可以使咱们的样式更好维护,不过 Yandex 开发的 BEM 更流行一些。

根本上来讲,BEM (纯粹用于 CSS)只是一个命名规范,它要求样式的类名要遵照 .Block__element--modifier 的模式。在任何使用 BEM 风格的代码库中,开发人员必须始终遵照 BEM 的规则。当严格遵照时,BEM 的效果很好,可是为何这些如同做用域通常基础的功能,却只使用单纯的命名规范来限制呢?

不管是否有明确表示,大多数 CSS-in-JS 类库都遵循 BEM 的思路,它们尝试将样式定位到单个 UI 组件,只不过用了彻底不一样的实现方式。

那么在实际编写代码时什么样的呢?当使用 Sunil Pai 开发的 glamor 时,代码看起来像下面这样:

import { css } from 'glamor'
const title = css({
  fontSize: '1.8em',
  fontFamily: 'Comic Sans MS',
  color: 'blue'
})
console.log(title)
// → 'css-1pyvz'

你可能会注意到代码中没有 CSS 的类名。由于它再也不是一个指向定义在项目其余位置 class 的硬编码,而是由咱们的库自动生成的。咱们没必要再担忧全局做用域内的选择器冲突,这也意味着咱们再也不须要替他们添加前缀了。

这个选择器的做用域与周围代码的做用域一致。若是你但愿在你应用的其余地方使用这个规则,你就须要将它改写成一个 JavaScript 模块而且在须要使用的地方引用它。就保持代码库的可维护性而言,它是很是强大的,它确保了任何给定的样式均可以像其余代码同样容易追踪来源

经过从仅仅是命名约定到默认强制局部样式的转变,咱们已经提升了咱们样式质量的基准线。BEM 已经烙在里面了,而再也不是一个可选项。

在继续以前,我要说明相当重要的一点。

它生成的是真正的级联样式,而不是内联样式

大多数早期的 CSS-in-JS 库都是将样式直接添加到每一个元素上,可是这个模式有个严重的缺点,'styles' 属性并不能作到 CSS 能够作到的每件事。大多数新的库再也不关注于动态样式表,而是在运行时在全局样式中插入和删除规则。

举个例子,让咱们看看 Oleg Slobodskoi 开发的 JSS,这是最先的 CSS-in-JS 库之一,而且它生成的是真实的 CSS

当使用 JSS 时,你可使用标准的 CSS 特性,好比 hover 和媒体查询,它们会映射到相应的 CSS 规则。

const styles = {
  button: {
    padding: '10px',
    '&:hover': {
      background: 'blue'
    }
  },
  '@media (min-width: 1024px)': {
    button: {
      padding: '20px'
    }
  }
}

一旦你将这些样式插入到文档中,你就可使用那些自动生成的类名。

const { classes } = jss.createStyleSheet(styles).attach()

不管你是使用一个完整的框架,仍是简单的使用 innerHTML,你均可以在 JavaScript 中使用这些生成的 class,而不是硬编码你的 class 字符串。

document.body.innerHTML = `
  <h1 class="${classes.heading}">Hello World!</h1>
`

单独使用这种方式管理样式并无多大的优点,它一般和一些组件库搭配使用。所以,一般能够找到用于最流行库的绑定方案。例如,JSS 能够经过 react-jss 的帮助轻松地绑定到 React 组件上,在管理生命周期的同时,它能够帮你给每一个组件插入一小段样式。

import injectSheet from 'react-jss'
const Button = ({ classes, children }) => (
  <button className={classes.button}>
    <span className={classes.label}>
      {children}
    </span>
  </button>
)
export default injectSheet(styles)(Button)

经过将咱们的样式集中到组件上,能够将他们和代码跟紧密的结合,这不就是 BEM 的思想么?因此 CSS-in-JS 社区的不少人以为在全部的样式绑定样板中,提取、命名和复用组件的重要性都丢失了。

随着 Glen MaddernMax Stoiber 提出了 styled-components 的概念,出现了一个新的思考这个问题的方式。

咱们直接建立组件,而不是建立样式而后手动地将他们绑定到组件上。

import styled from 'styled-components'

const Title = styled.h1`
  font-family: Comic Sans MS;
  color: blue;
`

使用这些样式时,咱们不会将 class 添加到存在的元素上,而是简单地渲染这些被生成的组件。

<Title>Hello World!</Title>

虽然 styled-components 经过模板字面量的方式使用了传统的 CSS 语法,可是有人更喜欢使用数据结构。来自 PayPalKent C. Dodds 开发的 Glamorous 是一个值得关注的替代方案。

Glamorous 和 styled-components 同样提供了组件优先的 API,可是他的方案是使用对象而不是字符串,这样就无需在库中引入一个 CSS 解析器,能够下降库的大小并提升性能。

import glamorous from 'glamorous'

const Title = glamorous.h1({
  fontFamily: 'Comic Sans MS',
  color: 'blue'
})

不管你使用什么语法描述你的样式,他们再也不仅仅是组件的一部分,他们和组件已经没法分离。当使用一个像 React 这样的库时,组件是基本构建块,而且如今咱们的样式也成了构建这个架构的核心部分。若是咱们将咱们应用程序中的全部内容都描述为组件,那么为何咱们的样式不行呢?

考虑到咱们以前介绍的对系统作出改变的意义,对于那些有丰富 BEM 开发经验的工程师来讲,这一切看起来彷佛是一个很小的提高。事实上,CSS 模块让你在不用放弃 CSS 工具生态系统的同时得到了这些提高。不少项目坚持使用 CSS 模块还有一个缘由,他们发现 CSS 模块充分解决了编写大规模 CSS 的问题,而且能够保持编写常规 CSS 时的习惯。

然而,当咱们开始在这些基本概念上构建时,事情开始变得更有趣。

2.

关键 CSS

在文档头部内联关键样式已经成为一种比较新的最佳实践,经过仅提供当前页面所需的样式能够提升首屏时间。这与咱们经常使用的样式加载方式造成了鲜明对比,以前咱们一般会强制浏览器在渲染以前为应用下载全部的样式。

虽然有工具能够用于提取和内联关键 CSS,好比 Addy Osmanicritical,可是他们没法从根本上改变关键 CSS 难以维护和难以自动化的事实。这是一个棘手的、可选的性能优化,因此大部分项目彷佛放弃了这一步。

CSS-in-JS 则是一个彻底不一样的故事。

当你的应用使用服务端渲染时,提取关键 CSS 不只仅是一个优化,从根本上来讲,服务器端的 CSS-in-JS 是使用关键 CSS 的首要工做。

举个例子,当使用 Khan Academy 开发的 Aphrodite 给元素添加 class 时,能够经过内联调用它的 css 函数来跟踪在此次渲染过程当中使用的样式。

import { StyleSheet, css } from 'aphrodite'
const styles = StyleSheet.create({
  title: { ... }
})
const Heading = ({ children }) => (
  <h1 className={css(styles.heading)}>{ children }</h1>
)

即使你全部的样式都是在 JavaScript 中定义的,你也能够很轻松的从当前页面中提取全部的样式并生成一个 CSS 字符串,在执行服务端渲染时将它们插入文档的头部。

import { StyleSheetServer } from 'aphrodite';

const { html, css } = StyleSheetServer.renderStatic(() => {
  return ReactDOMServer.renderToString(<App/>);
});

你能够像这样渲染你的关键 CSS:

const criticalCSS = `
  <style data-aphrodite>
    ${css.content}
  </style>
`;

若是你看过 React 的服务端渲染模型,你可能会发现这个模式很是熟悉。在 React 中,你的组件在 JavaScript 中定义他们的标记,但能够在服务器端渲染成常规的 HTML 字符串。

若是你使用渐进加强的方式构建你的应用,尽管所有使用 JavaScript 编写,但也有可能在客户端根本就不须要 JavaScript

不管用哪一种方式,客户端 JavaScript bundle 都要包含启动单页应用所需的代码,它能让页面瞬间活起来,并与此同时开始浏览器中进行渲染。

因为在服务器上渲染 HTML 和 CSS 是同时进行的,就像前面的例子所示, Aphrodite 这样的库一般会以一个函数调用的方式帮助咱们流式生成关键 CSS 和服务端渲染的 HTML。如今,咱们能够用相似的方式将咱们的 React 组件渲染成静态 HTML。

const appHtml = `
  <div id="root">
    ${html}
  </div>
`

经过在服务器端使用 CSS-in-JS,咱们的单页应用不只能够脱离 JavaScript 工做,它甚至能够加载的更快

与咱们选择器的做用域同样,渲染关键 CSS 的最佳实践现在已经烙在里面了,而不是一个可选项

3.

更智能的优化

咱们最近看到了构建 CSS 的新方式的兴起,好比 YahooAtomic CSSAdam MorseTachyons,它们更喜欢短小的,单一用途的类名,而不是语义化的类名。举个例子,当使用 Atomic CSS 时,你将使用相似于函数调用的语法去做为类名,而且这些类名会在以后被用来生成合适的样式表。

<div class="Bgc(#0280ae.5) C(#fff) P(20px)">
  Atomic CSS
</div>

经过最大程度地提升类的复用性以及用内联样式的方式同样有效处理类名,能够达到尽量地精简 CSS 的目的。虽然文件大小的减小很容易体现,但对于你的代码库和团队成员的影响确实是微乎其微的。这些优化会从底层引发你的 CSS 和标记语言的变化,使他们成为构建工做中更重要的部分。

正如咱们已经介绍过的,当使用 CSS-in-JS 或者 CSS 模块时,你再也不须要在 HTML 中硬编码你的类名,而是动态引用由库或者构建工具自动生成的 JavaScript 变量。

咱们这样写样式:

<aside className={styles.sidebar} />

而不是:

<aside className="sidebar" />

这个变化可能看起来至关肤浅,可是从如何管理标记语言和样式之间关系上来讲,这倒是一个里程碑式的改变。经过给咱们的 CSS 工具不止修改样式,还能修改最终提供给组件的 class 的能力,咱们为咱们的样式表解锁了一个全新的优化方式。

若是看看上面的例子,就会发现 'styles.sidebar' 对应了一个字符串,但并无什么去限制它只能是一个 class。就咱们所了解的,它能够很容易的对应成表示十几个 class 的字符串。

<aside className={styles.sidebar} />
// Could easily resolve to this:
<aside className={'class1 class2 class3 class4'} />

若是咱们能够优化咱们的样式,为每一套样式生成多个类,咱们就能够作一些很是有趣的事。

我最喜欢的例子是 Ryan Tsao 编写的 Styletron

与 CSS-in-JS 和 CSS 模块自动添加 BEM 风格前缀的过程相同,Styletron 对 Atomic CSS 也作了相同的事。

它的核心 API 专一于一件事,为每一个由属性、值、媒体查询组合起来的样式定义一个独立的 CSS 规则,而后返回自动生成的 class。

import styletron from 'styletron';
styletron.injectDeclaration({
  prop: 'color',
  val: 'red',
  media: '(min-width: 800px)'
});
// → 'a'

固然,Styletron 也提供了一些高级 API,好比它的 injectStyle 函数容许一次定义多个规则。

import { injectStyle } from 'styletron-utils';
injectStyle(styletron, {
  color: 'red',
  display: 'inline-block'
});
// → 'a d'
injectStyle(styletron, {
  color: 'red',
  fontSize: '1.6em'
});
// → 'a e'

尤为要注意上面生成的类名之间的相同点。

经过放弃对 class 自己的低级控制,而仅定义所须要的样式集合,这些库就能帮咱们生成最佳的 class 原子集合。

以前咱们经过手工查找的方式将样式分割成可复用的 class,如今已经能够彻底自动化的完成这种优化了,而且你应该也开始注意到这个趋势。原子性 CSS 已经烙在里面了,并不是一个可选项

4.

包管理

在谈论这一点以前,咱们先停下来问本身一个看似简单的问题。

咱们如何共享 CSS?

咱们已经从手动下载 CSS 文件向使用前端专门的模块管理工具转变,好比 Bower,或者如今经过 npm 可使用 Browserifywebpack。虽然这些工具已经自动处理了外部模块的 CSS 依赖,可是目前前端社区大多仍是手工处理 CSS 的依赖关系。

不管使用哪一种方式,CSS 之间的依赖都不是很好处理。

大家许多人可能还记得,在使用 Bower 和 npm 管理 JavaScript 模块时,出现过相似的状况。

Bower 没有依赖任何特定的模块格式,而发布到 npm 的模块则要求使用 CommonJS 模块格式。这种不一致,对发布到二者任何一个平台的包的数量都产生了巨大的影响。

小型可是有复杂依赖关系的模块更愿意使用 npm,Bower 则吸引了大量大型而独立的模块,固然,你可能也就有两三个模块,再加几个插件,但因为在 Bower 中你的依赖没有一个模块系统去做支撑,每一个包没法简单的利用它本身的依赖关系,因此在整合这一块,基本上就留给开发者手动去操做了。

所以,随着时间的推移,npm 上的模块数量呈指数性增加,而 Bower 只能是有限的线性增加。虽然这多是各类缘由致使的,可是不得不说,主要缘由仍是在于两个平台处理运行时包与包之间的依赖关系的不一样方法。

很不幸,这对于 CSS 社区来讲太熟悉了,咱们发现相对于 npm 上的 JavaScript 来讲,独立 CSS 模块的数量也增加的很慢。

若是咱们也想实现 npm 的指数增加该怎么作?若是咱们想依赖不一样大小不一样层次的复杂模块,而不是专一于大型、全面的框架呢?为了作到这一点,咱们不只须要一个包管理器,还须要一个合适的模块格式。

这是否意味着咱们须要专门为 CSS 或者 Sass 和 Less 这样的预处理器设计一个包管理工具?

有趣的是,在 HTML 上咱们已经实现了相似的功能。若是你问我相同的问题:咱们如何共享标记语言?你可能很快会想起来,咱们几乎不会直接共享原始的 HTML —— 咱们共享 HTML-in-JS

咱们经过 jQuery 插件Angular 指令集React 组件实现了这个功能。咱们的大组件由小组件组成,每个小组件都有着本身的 HTML,它们也都独立的发布在了 npm 上。HTML 这种格式可能不足以强大到完成这个功能,可是经过将 HTML 嵌入到完整的编程语言中,咱们就能够很轻松的越过这个限制。

咱们能不能像 HTML 那样,经过 JavaScript 去分享 CSS呢?能不能使用函数来返回对象和字符串而不是使用 mixins ?又或者咱们利用 Object.assign 和新的 object spread 操做符merge 对象而不是用 extending classes 呢?

const styles = {
  ...rules,
  ...moreRules,
  fontFamily: 'Comic Sans MS',
  color: 'blue'
}

一旦咱们开始用这种方式编写咱们的样式,咱们就可使用相同的模式、相同的工具、相同的基础架构、相同的生态系统来编写和分享咱们的样式代码,就像咱们应用程序中的其余任何代码同样。

Max StoiberNik GrafBrian Hough 开发的 Polished 就是一个很好的例子。

Polished 就像是 CSS-in-JS 界的 Lodash,它提供了一整套完整的 mixins、颜色函数等等,使得在 JavaScript 中能够获得使用 Sass 编写样式的体验。最大的区别在于,如今这些代码在复用、测试和分享方面,都提升了一个层次,而且可以完整的使用 JavaScript 模块生态系统。

当谈到 CSS 时咱们会想,做为一个由小型可复用的开源模块组合成的一个样式集合,咱们如何得到和 npm 上其余模块类似的开源程度?奇怪的是,咱们最终经过将咱们的 CSS 嵌入其余的语言而且彻底拥抱 JavaScript 模块实现了这一点。

5.

在非浏览器环境下的样式

到目前为止,个人文章已经涵盖了全部的要点,虽然在 JavaScript 中编写 CSS 会容易的多,可是常规的 CSS 并不是完不成这些功能。这也是我把最有趣、最面向将来的一点留到如今的缘由。这一点并不必定能在现在的 CSS-in-JS 社区中发挥巨大的做用,但它可能会成为将来设计的基础层面。它不只会影响开发人员,也会影响设计师,最终它将改变这两个领域相互沟通的方式。

首先,为了介绍它,咱们须要先简单介绍一下 React。

React 的理念是用组件做为最终渲染的中间层。在浏览器中工做时,咱们构建复杂的虚拟 DOM 树而不是直接操做 DOM 元素。

有趣的是,DOM 渲染相关的代码并不属于 React 的核心部分,而是由 react-dom 提供的。

import { render } from 'react-dom'

尽管最初 React 是为 DOM 设计的,而且大部分状况下仍是在浏览器中使用,可是这种模式也容许 React 只经过简单地引入新的渲染引擎就能从容面对各类不一样的使用环境。

JSX 不只仅能够用于虚拟 DOM,他能够用在任何的虚拟视图上。

这就是 React Native 的工做原理,咱们经过编写那些渲染成 native 的组件以实现用 JavaScript 编写真正的 native 应用,好比咱们用 ViewText 取代了 divspan

从 CSS 的角度来看,React 最有趣的就是它拥有本身的 StyleSheet API

var styles = StyleSheet.create({
  container: {
    borderRadius: 4,
    borderWidth: 0.5,
    borderColor: '#d6d7da',
  },
  title: {
    fontSize: 19,
    fontWeight: 'bold',
  },
  activeTitle: {
    color: 'red',
  }
})

在这里你会看到一组熟悉的样式,咱们编写了颜色、字体和边框样式。

这些规则都很是简单,而且很容易映射到大部分的 UI 环境上,可是当涉及到 native 布局时,事情就变得很是有趣了。

var styles = StyleSheet.create({
  container: {
    display: 'flex'
  }
})

由于在浏览器环境以外,因此 React Native 有本身的 flexbox 实现

最初发布时他是一个名为 css-layout 的JavaScript 模块,彻底用 JavaScript 从新实现了 flexbox(包含充分的测试),为了更好的可移植性它如今已经迁移到 C 语言。

鉴于这个项目的影响力和重要性,它被赋予了更重要的品牌 ——— Yoga

虽然 Yoga 专一于将 CSS 迁移到非浏览器环境中,可是仅关注于 CSS 特性的一小部分没法扩大它的统治范围。

"Yoga 的重点是成为一个有表现力的布局框架,而不是去实现一套完整的 CSS"

这看起来彷佛很难实现,可是当你回顾 CSS 体系的历史时会发现使用 CSS 进行规模化的工做就是选择一个合适的语言子集

在 Yoga 中,为了控制样式的做用域,他们避开了级联样式,而且将布局引擎彻底集中在 flexbox 上。虽然这样会丧失不少功能,但它也为须要嵌入样式的跨平台组件创造了惊人的机遇,咱们已经看到几个试图利用这个特性的开源项目。

Nicolas Gallagher 开发的 React Native for Web 旨在成为 react-native 的一个替代品。当使用 webpack 这类打包工具时,很容易用别名来替换第三方库。

module: {
  alias: {
    'react-native': 'react-native-web'
  }
}

使用 React Native for Web 后能够在浏览器环境中运行 React Native 组件,包括 React Native 样式 API

一样,Leland Richardson 开发的 react-primitives 也提供了一套跨平台的原始组件,它能够抽象目标平台的实现细节,为跨平台组件创造可行的标准。

甚至 微软 也开始推出 ReactXP,这个库旨在简化跨 web 和 native 的工做流,它也有本身的跨平台样式实现

即便你不编写 native 应用程序,也要注意一点:拥有一个真正的跨平台组件抽象,可以使咱们将目标设定在那些高效的、无限可能的环境中去,有时这些会让你没法想象。

我所见过的最使人震惊的例子是 AirbnbJon Gold 开发的 react-sketchapp

咱们不少人都花费了大量时间去尝试标准化咱们的设计语言,而且尽量的避免系统中的重复。不幸的是,尽管咱们但愿样式只有一个来源,但咱们最多也只能减小到两个,开发人员的动态样式以及设计师的静态样式。虽然这已经比咱们以前的模式好了不少,可是它仍然须要咱们手工的将样式从 Sketch 这样的设计工具上同步到代码里。这也是 react-sketchapp 被开发出来的缘由。

感谢 Sketch 的 JavaScript API,以及 React 链接到不一样渲染引擎的能力,react-sketchapp 让咱们能够用跨平台的 React 组件渲染咱们的 Sketch 文件。

不用多说,这极可能改变设计师和开发人员的合做方式。如今,当咱们对设计进行迭代时,不管在设计工具仍是开发者工具上,咱们均可以经过相同的声明引用同一个组件。

经过 Sketch 中的符号React 中的组件,咱们的行业已经开始从本质上趋于抽象,而且经过使用相同的工具咱们能够更紧密的协做。

这么多新的尝试都来自 React 和其周边的社区,看来这并非巧合。

在组件架构中,最重要的是将组件的功能集中在一块儿。这天然包括它的局部样式,往更复杂的方向延伸就涉及到数据的获取。这里要感谢 RelayApollo,让这个过程变得简单。这些成果解锁了巨大了潜力,咱们如今所了解的,只是其中冰山一角。

虽然这对咱们编写样式产生了很大的影响,但其实它对咱们架构里的一切都有很大的影响,固然,是出于好的理由。

经过统一单一语言开发组件的模式,咱们可以从功能上,而不是从技术上,将咱们的关注点进行更好的隔离。将组件的全部内容局部化,用他们构建大型可维护的系统,用以前没法使用的方式进行优化,更容易的分享咱们的工做,以及利用小型开源模块构建大型应用程序。更重要的是,完成这一切并不须要打破渐进加强的理念,也不会让咱们放弃认真对待 web 平台的理念。

最重要的是,我对使用单一语言编写出的组件的潜力感到兴奋,他们造成了一种新的、统一的样式语言基础,以一种史无前例的方式统一了前端社区。

在 SEEK,咱们正在努力利用这一功能,咱们围绕组件模型来构建在线样式指南,其中语义化、交互性和视觉风格都有统一的抽象。这构成了开发人员和设计师之间共享的通用设计语言。

构建一个页面应该尽量的和拼装组件同样简单,这样能够确保咱们工做的高品质,而且让咱们在产品上线好久之后,也有能力去升级其设计语言。

import {
  PageBlock,
  Card,
  Text
} from 'seek-style-guide/react'
const App = () => (
  <PageBlock>
    <Card>
      <Text heading>Hello World!</Text>
    </Card>
  </PageBlock>
)

尽管咱们如今使用 React,webpack 和 CSS 模块构建了这个样式指南,可是这个架构,和任何你以前知道的 CSS-in-JS 系统是一致的。技术上可能不一致,可是核心理念是同样的。

然而,将来这些技术选型可能也须要以一种意想不到的方式进行转变,这也就是为何保持对这个领域的持续关注,对与咱们不断发展的组件生态是如此的重要。咱们如今可能不会用 CSS-in-JS 这项技术,可是极可能没过多久就会出现一个使人信服的理由让咱们使用它。

CSS-in-JS 在短期里有了出人意料的发展,但更重要的是,它只是这个宏伟蓝图的开始。

它还有很大的改进空间,而且它的创新尚未中止的迹象。新的库正不断涌现,它们解决了将来会出现的问题而且提高了开发人员的体验 —— 好比性能的提高,在构建时抽取静态 CSS,支持 CSS 变量以及下降了前端开发人员的入门门槛。

这也是 CSS 社区关注的地方。尽管这些对咱们的工做流程有很大的改动,可是他们不会改变你仍然须要学习 CSS 的事实

咱们可能使用不一样的语法,也可能以不一样的方式构建咱们的应用,可是 CSS 的基本构建块不会消失。一样,咱们行业向组件架构的转变是不可避免的,经过这种方式从新构想前端的意愿只会愈来愈强烈。咱们很是须要共同合做以确保咱们的解决方案普遍适用于各类背景的开发人员,不管是专一于设计的仍是工程的。

虽然有时咱们的观点不一致,可是 CSS 和 JS 社区对于改进前端,把 Web 平台变得更加剧要以及改进咱们下一代 web 开发流程都有很大的激情。社区的潜力是巨大的,并且尽管到目前为止咱们已经解决了大量的问题,仍然有不少工做尚未完成。

到这里,可能你仍是没有被说服,可是彻底不要紧。虽然如今在工做上使用 CSS-in-JS 不是很合适,但我但愿它有合适的缘由,而不是仅仅由于语法就反对它。

不管如何,将来几年这种编写样式的风格可能会愈来愈流行,而且值得关注的是它发展的很是快。我衷心但愿你能够加入咱们,不管是经过贡献代码仍是简单的参与咱们的对话讨论,都能让下一代 CSS 工具尽量的提升前端开发人员的工做效率。或者,我但愿已经让大家至少了解为何人们对这一块如此饱含激情,或者,至少了解为何这不是一个愚蠢的点子。

这篇文章是我在德国柏林参加 CSSconf EU 2017 作相同主题演讲时撰写的,而且如今能够在 YouTube 上看到相关视频。

掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划

相关文章
相关标签/搜索