【译】react:css in js

作者: candice2cc | 来源:发表于2017-02-28 20:49 被阅读119次

注:原文作者是来自facebook的前端基础设施团队的Christopher Chedeau。

大规模项目中面临的css问题:

  • 全局命名空间
  • 依赖
  • 无用代码移除
  • 压缩
  • 共享常量
  • 定制化
  • 隔离

举个Button的例子:

/* button.css */
.button{
    background: #f6f7f8 url(/images/button/background.png) repeat-x;
    border: 1px solid #cdced0;
    border-radius: 2px;
    box-shadow: 0 1px 1px rgba(0,0,0,0.05);
}

.button-depressed{
    background-color: #4e69a2;
    border-color:#c6c7ca;
    color:#5890ff;
}

以上我们设计了一个button,存在常态和按下状态。

全局变量

在w3schools.com的JavaScript的最佳实践中,建议避免使用全局变量。

w3c javascript 最佳实践

对于我来说,在css中仍然存在全局变量是一件让人疯狂的事情。在js编程中,我们很早就知道全局变量是不好的实践。
我们学习使用局部变量、自执行函数、模块化编程来解决全局变量的问题。
但是,在bootstrap的css中,存在超过600个的全局变量。
在Facebook,我们使用一种css扩展来解决这个问题。

/* button.css */
.button/container{


/* dropdown.css */
.dropdown/container .button/container{

这种方式,只有在button.css文件中的button/container样式才会参与build,如果视图在dropdown.css中使用,它将不会参与build.

如果需要导出全局变量,可以采用以下写法:

.button/container/public{


.dropdown/container .button/container/public{

调用部分:

/* button.css */
.button/container{

/* button.js */
<div className={cx('button/container')}>

因为button/container不是有效的classname,因此我们的调用方式需要发生变化,调用cx(class extension)来完成转换。

依赖

/* button.css */
.button/container{
/* button.js */
requireCSS('button')
<div className={cx('button/container')}>

以前我们把css打包到一个独立的文件中,现在我们把它们分割成一个个独立的文件,分别引入依赖。
很久以来,我们一直要求开发者只引入需要的css文件。但是如果其他人引入了某个css文件,它依旧会存在。
现在我们有了cx,它会进行静态分析,可以自动注入。

无用代码移除

因为cx是唯一生成样式的方式,这样我们可以解决最麻烦的问题:移除无用的代码。

压缩

通过cx可以最小化所有的classname,让js和css文件更小。

共享常量

.button/container{
    /* keep in sync with button.js */
    padding:5px;

//Keep in sync with button.css
var buttonPadding=5;

很长一段时间,我们采用注释或者命名约定的方式来共享常量。

现在我们引入了css变量。

/* button.css */
.button/container{
    padding:var(button-padding);
var buttonPadding = cssVar('button-padding');
$CSSVar = array(
    'button-padding' => 5,
);

由于facebook很多项目使用了php语言,所以我们在php中定义了css变量。

此时,我们依旧存在两个没有解决的问题:定制化和隔离。

css in js方案

这一刻我们等了很久...

/* button.js */
var styles = {
    container: {
        backgroud: '#f6f7f8 url(/images/button/background.png) repeat-x',
        border: '1px solid #cdced0',
        borderRadius: 2,
        boxShadow: '0 1px 1px rgba(0,0,0,0.05)'
    },
    depressed: {
        backgroundColor: '#4e69a2',
        borderColor: '#c6c7ca',
        color: '#5890ff'
    }
};

我们使用内联样式来渲染

<div style={styles.container}>

内联样式并没有那么糟糕。
首先:我们依旧在一个独立的文件中编写样式;
其次:style实际比class语义上更好;
最后:我们并没有直接应用style,而是通过React Virtual DOM。

前五个问题顺利解决。

定制化

/* button.js */
propTypes:{
    isDepressed:React.PropTypes.bool,
    style:React.PropTypes.object,
},

<div style={m(
    styles.container,
    this.props.isDepressed && styles.depressed,
    this.props.style
)}>

于是,我们同时解决了后两个问题。很明显,当在js中写样式,样式中的class只会独立出现相互隔离。

结论

我并不是要说服你们抛弃css,使用js。
我们有了大量的css库,例如less、sass...但是他们都没有解决上面的7大问题。
css也并不是web中存在底层缺陷的唯一部分,但是React在尝试解决他们中的一些问题。
我希望你们打破天花板,面对搭建web服务面临的困境,去思考、讨论并解决。

相关文章

  • 【译】react:css in js

    注:原文作者是来自facebook的前端基础设施团队的Christopher Chedeau。 大规模项目中面临的...

  • 10.React中CSS动画19-04-30

    一.React中实现CSS过渡动画 App.js style.css 一.React中使用CSS动画 style....

  • React 使用样式

    在React中使用样式 内联样式的写法 普通的css写法 css modules css in js (使用 st...

  • webpack 中实现自动识别 CSS Modules

    背景 在 React 项目中使用 CSS 时,如果不使用 CSS in JS 的方案,一般会直接在 JS 文件中导...

  • 技术栈

    前端:react样式:css in js状态管理:dvaAPI查询:ApolloAPI开发:strapinosql...

  • [react]7.1练习

    1、实现顶部tab点击效果 App.js style.css TabControl.js 2、React-slot...

  • 使用 React 的 CSS 模块指南

    有许多不同的方法可以为 React 组件提供样式,例如导入纯 CSS、使用样式组件、JS-in-CSS 或 CSS...

  • 面试题一览

    HTML与CSS HTML与CSS常用编译工具 原生js h5 React Vue ES6 javascript框...

  • React-Native的实现原理

    React-Native:可以用JSX(JS的语法扩展) 混编js、css、html,只关心如何用 JavaScr...

  • Day24 知识点 part1

    持续 SQL交互学习 JS 函数式编程指南 React.js 小书 碎片 css-animation-101 He...

网友评论

    本文标题:【译】react:css in js

    本文链接:https://www.haomeiwen.com/subject/vndfgttx.html