【React】CSS

70 阅读2分钟

普通 CSS

内联 style

  • 和 HTML style 一样,元素的内联样式
  • 必须是 JS 对象形式,不可以是字符串
  • 样式名称用驼峰式写法,如 fontSize

className

  • 和 HTML class 一样,设置 CSS 样式名
  • 和 JS class 重复,所以改名 className
  • 可用 clsxclassnames 条件判断

链接

尽量不用内联 style

  • 内联 style 代码量多,性能差
  • 外链样式(用 className)代码复用,性能好

CSS module

普通 CSS 的问题

  • React 使用组件化,每个组件可能使用多个 css 文件样式
  • 多个 CSS 就会造成命名重复,不好管理

CSS Module

  • 每个 CSS 都是一个独立的模块,命名 xxx.module.css
  • 每个模块中的 className 都不一样,会在该模块内部加一个后缀,以隔离和其他 css 文件的样式冲突
  • CRA 原生支持 CSS Module

使用 Sass

  • CSS 写法比较原始,一般使用 Sass less 等预处理语言
  • CRA 支持 Sass Module ,把后缀改为 .scss 即可。Vite 需要手动安装一下 sass。
import React from 'react';
import styles from './index.module.scss';
import classnames from "classnames";

function CardPage() {

    const style2 = styles.box2;
    const itemClassName = classnames({
        // 写成 [] 方便动态样式属性的配置 接收一个变量
        [style2]: true,
        [styles['card-page']]: false,
    });

    return (
        <>
            <div className={styles['card-page']}>
                <div className={styles['box-container']}>box1</div>
                <div className={styles.box2}>box2</div>
            </div>
            <div className={styles['card-page']}>
                <div className={itemClassName}>box3</div>
            </div>
        </>

    );
}

export default CardPage;
.card-page {
  width: 200px;
  height: 200px;
  border: 1px solid #eee;
  padding: 20px;
  background: #535bf2;
  .box-container {
    width: 150px;
    height: 50px;
    border: 1px solid #eee;
    padding: 20px;
    background: #1fc2cb;
  }
  .box2 {
    width: 150px;
    height: 50px;
    border: 1px solid #eee;
    padding: 20px;
    background: #47b068;
  }
}

image.png

css in js

  • 在 JS 中(组件代码中)写 CSS
  • 能更灵活的支持动态样式,直接在 JS 中完成计算和样式切换。这比 css-module 更好。
  • 不用担心 CSS class 重名的问题
  • CSS-in-js 是一个解决方案,并不是一个工具的名称

PS:CSS-in-js 并不是内联 style ,它会经过工具的编译处理,生成 CSS class 的形式。

Styled-components

styled-components.com/ 方便我们使用该解决方案。

import React from 'react';
import styled, {css} from "styled-components";

type ButtonPropsType = {
    primary?: boolean
}
function CardPage() {

    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: #BF4F74;
      ${(props: ButtonPropsType) => props.primary && css`
        background: #eecc6c;
      `}
    `;

    const Wrapper = styled.section`
      padding: 4em;
      background: papayawhip;
    `;

    return (
        <>
            <Wrapper>
                <Title primary>
                    Hello World!
                </Title>
            </Wrapper>
        </>

    );
}

export default CardPage;

image.png

上面将参数传入了 ```` 中,本质上也是一种函数的调用:

image.png

这里不过是内部要求使用这种格式调用函数。

Styled-jsx

github.com/vercel/styl…

但是该库由于是 jsx ,所以用于 tsx 会存在一些类型校验的问题。

Emotion

Emotion – Introduction