likes
comments
collection
share

React的CSS方案

作者站长头像
站长
· 阅读数 34

React的CSS方案

CSS的缺陷

  • 样式与状态相关的情况越来越多,需要动态、能直接访问组件state的css。
  • css不是组件化。一切样式都是全局,类的命名重复,但当你使用三方插件时却无法避免命名冲突。

关于sass题外话

  • sass指预编译器和缩进式css语言
  • 预编译器有两种node-sass和dart-sass,node-sass已经退出舞台了
  • scss并不能解决css的问题

Vue的解决方案

  • v-bind 和 class/style 的结合,解决了依赖变化时样式发生变化 <div v-bind:class="{ active: isActive }"></div><div v-bind:class="[activeClass, errorClass]"></div><div v-bind:style="styleObject"></div> <div v-bind:style="[baseStyles, overridingStyles]"></div>
  • scoped css的语法

内联CSS

传统的inline-style

const textStyles = {
  color: 'white',
  backgroundColor: this.state.bgColor
};

<p style={textStyles}>inline style</p>

和Vue的内联样式非常相似

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

缺陷:

  • 内联样式并不支持所有的 css,媒体查询,:before和:nth-child等 pseudo selectors

Vue可以通过计算属性计算出一个样式对象,解决了样式与状态相关的情况。切换class也可以做到

引入式CSS

最普通常见的方式,在 jsx 文件中引入import './App.css',这种方式适合引入CSS-reset和SCSS的全局变量。

@import-normalize 是 create-react-app 官方自带的 reset 和我们常用的 reset 的区别就在于,我们会把所有样式都清零,而normalize只是给所有标签加了一个默认样式,消除了不同浏览器对不同标签的默认样式。

normalize 并没有什么卵用。

Css in Js

主要依赖于很多React库Radium,Aphrodite,下面介绍一下Radium

import Radium from 'radium';

const Button = () => (
    <button
        style={styles.red}>
        {this.props.children}
    </button>;
)

var styles = {
  red: {
    backgroundColor: 'red'
  }
};

Button = Radium(Button);

Radium is activated by wrapping your component。

这种类型的库扩展了React能支持的css的范围,并且通过给Button组件传入一个对象,并把对象放到style数组中,完成了根据state变化style

    style={[
      styles.base,
      this.props.block && styles.block
    ]}>

样式只作用于import它的组件

Css Modules

Css Modules 并不是React专用解决方法,适用于所有使用 webpack 等打包工具的开发环境。以 webpack 为例,在 css-loader 的 options 里打开modules:true 选项即可

import styles from './table.css';

    render () {
        return <div className={styles.table}>
            <div className={styles.row}>
                <div className={styles.cell}>A0</div>
                <div className={styles.cell}>B0</div>
            </div>
        </div>;
    }
/* table.css */
.table {}
.row {}
.cell {}

Css Modules还有一大缺憾:和Vue的解决一样,因为css写在css文件,无法处理动态css。

styled-components

ES6 的模板字符串,在js文件里写纯粹的css。

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

返回的是一个带样式的组件

// 在充分使用css全部功能的同时,非常方便的实现动态css, 甚至可以直接调用props!
const Wrapper = styled.section`
  padding: 4em;
  background: ${props => props.bgColor};
`;

小结

  • 要解决的两个问题:模块化和动态css
  • 内联CSS,引入式CSS,CSS in JS,Css Modules
  • 内联CSS:部分伪元素选择器不支持
  • 引入式:样式作用于全局
  • CSS in JS:很好的实现了state和style的结合,因为css就在js文件里直接访问就行
  • CSS in JS 是对内联CSS的升级补充了内联不支持的部分选择器,完美地实现了模块化和动态CSS
  • Css Modules:利用className来处理样式,无法处理动态css。
转载自:https://juejin.cn/post/6844904164212867085
评论
请登录