为组件添加样式的方法主要有两种:外部CSS样式表和 style内联样式

  1. Grid栅格
  2. Flexbox
  3. style行内样式
  4. 全局样式
  5. css module
  6. css in js
    1. styled-component
  7. less & sass
    1. 参考资料 https://zhuanlan.zhihu.com/p/126316825

css in js增加了成本复杂性
css样式的层叠性和灵活性,是 css in js 没有的
请停止 css in js https://zhuanlan.zhihu.com/p/26878157

组件样式如何覆盖

  1. 组件样式覆盖全局的样式 > index.less

全局样式

  1. /index.css, import引入样式文件
  2. /index.js 直接引入整个 css文件
  3. 缺点:造成css 样式的全局污染 ```jsx import ‘./index.css’

组件中使用全局样式

  1. <a name="CsB78"></a>
  2. ### 全局样式规范
  3. 1. 命名规则: xxx.css
  4. 2. 引入方式 import ‘xxx.css’
  5. 3. 用法:<div className='styleName'>
  6. 把样式表文件当作一个模块,在使用该样式表的组件中,像导入其他组件一样导入样式表文件
  7. 1. 基础样式表,公共的全局样式
  8. ```jsx
  9. import './style.css'; // 要保证相对路径设置正确

覆盖 antd的样式

需要覆盖 Ant Design 样式的,都放在 overwrite-antd.css里面
在 antd的样式后面加上 __ow__

  1. .ant-treee._ow_ { background-color: #96f }
  2. .ant-card-head._ow_, .ant-card-body._ow_ { padding: 16px }

方法的覆盖(override)重载(overload)和重写(overwrite)

css module

  1. css 模块化
  2. 有自己的作用域

  3. 模块化的结构处理css文件,把 css转换为 对象

    1. 有个这个对象之后,就可以通过引用对象属性的方式去定义样式
    2. 样式用小驼峰命名
    3. 如果样式有:横线,要用括号来获取,类似于 js的变量
  4. 好处:更符合模块化的开发原则
    1. 解决了全局污染的问题
    2. 解决了命名混乱的问题
    3. 没有依赖管理。CSS Module 可以让整个工程不使用 saas 或者 less 这样的第三方库
  5. create-react-app自从2.0.版本就已经开始支持CSS Modules
    1. https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
    2. css module文档 http://www.ruanyifeng.com/blog/2016/06/css_modules.html
  1. // 是 css modules
  2. import styled from './index.less';
  3. import styled from './index.module.less';
  4. // 不是 css modules
  5. import './index.css';
  6. import './index.less';

css-module命名规范

  1. 命名规则: xxx.module.css
  2. 引入方式 import xxx from ‘xxx.module.css’
  3. 用法:
  1. import styled from './app.module.less'
  2. function App() {
  3. return (
  4. <div className={styled.card}>
  5. <ul className={styled.cardList}>
  6. <li className={styled.cardItem}>01</li>
  7. <li className={styled['card-item']}>02</li>
  8. </ul>
  9. </div>
  10. )
  11. }

/app.mobule.less

  1. .app {
  2. border: 1px solid #ddd;
  3. &-List {
  4. margin-bottom: 16px;
  5. list-style-type: none;
  6. &:last-child {
  7. margin-bottom: 0
  8. }
  9. }
  10. &-Item {}
  11. .card-item {}
  12. }

样式模块的引用

用 composes 关键字可以在 title 样式里应用 link 样式,,类似于继承

  1. .link {
  2. text-decoration: underline;
  3. text-indent: 2em;
  4. }
  5. .title{
  6. composes: link;
  7. color: red;
  8. font-size: 20px;
  9. }

配置 d.ts自动转化 css

  1. tsx无法识别 css格式的文件,解决:给 css加上 TS的类型声明
  2. *.d.ts
  3. src/ 目录下,新建 custom.d.ts
    1. import styled from './app.module.css'
    custom.d.ts
    1. declare module "*.css" {
    2. const css: {[key: string]: string}
    3. export default css
    4. }

typescript-plugin-css-modules

  1. 让编辑器对 css代码有智能提示
  2. https://www.npmjs.com/package/typescript-plugin-css-modules

    1. npm install typescript-plugin-css-modules -D
  3. tsconfig.json配置 plugins插件,vscode需要配置下 settings.json

    1. "plugins": [
    2. {
    3. "name": "typescript-plugin-css-modules"
    4. }
    5. ]

    plugin-css-modules.gif

vscode配置

  1. 项目根目录新建 .vscode文件夹,并进入
  2. 新建 settings.json,让 vscode可以识别

image.png

  1. settings.json
    1. {
    2. "typescript.tsdk": "node_modules/typescript/lib",
    3. "typescript.enablePromptUseWorkspaceTsdk": true
    4. }

inline-style

行内样式,类似于 style的行内样式
行内样式实际上就是 React 元素上的一个属性,属性的值是对象,所有对象的属性名均为 CSS属性
需要注意的是, CSS 属性写法遵循小驼峰命名法
最终生成的是 HTML的 style行内样式

内联样式实际上是一种CSS in JS的写法:将CSS样式写到JS文件中,用JS对象表示CSS样式
style使用了两个大括号,这可能会让你感到迷惑

  1. 其实,第一个大括号表示 style的值是一个JavaScript表达式
  2. 第二个大括号表示这个JavaScript表达式是一个对象 ```jsx

const style = {width: 100, height: 300, backgroundColor: ‘red’} function App() { return

}

  1. <a name="b2sMa"></a>
  2. ## classnames
  3. 可以在同一个标签上使用更多的 CSS 名称
  4. ```bash
  5. npm install classnames --save

classnames的用法

  1. import classnames from 'classnames'
  2. import styled from './list.module.css';
  3. function App() {
  4. const [count, setCount] = useState(10)
  5. const cls = classnames('col-2', {
  6. 'grid-6': count > 12
  7. })
  8. return (
  9. <div className={ cls('title', 'list-title') }>
  10. <p className={`col-2 ${count ? 'grid-6' : ''}`}/>
  11. // 全局样式和局部样式混用
  12. <div className={`col-2 ${styled['styleName']}`} />
  13. </div>
  14. )
  15. }

bind

引入 classnames
定义 cls 方法,使用 bind 方法,绑定 style 对象

  1. import styled from './list.module.css';
  2. import classnames from 'classnames/bind'
  3. // 定义 cls,使用bind方法绑定 style样式
  4. const cls = classnames.bind(styled)
  5. function App() {
  6. return (
  7. <div className={ cls('title', 'list-title') }>
  8. <p className={`col-2 ${count ? 'grid-6' : ''}`}/>
  9. </div>
  10. )
  11. }

css in js JSS

  1. jss https://cssinjs.org
  2. 请停止 css-in-js 的行为 https://zhuanlan.zhihu.com/p/26878157
  3. css in js 通过 JS 来声明、抽象样式从而提高组件的可维护性
    1. 从组件的层面对 CSS 进行封装
    2. 在组件加载时动态的加载样式,动态生成类名从而避免全局污染

jss

image.png

styled-components

style-components css-in-js https://styled-components.com/
style-components高级功能:

  1. 变量
  2. 循环
  3. 函数
  1. npm install --save styled-components

image.png

styled-components用法

  1. // 创建一个 Title 组件,它将渲染一个附加了样式的 <h1> 标签
  2. const Title = styled.h1`
  3. font-size: 1.5em;
  4. text-align: center;
  5. color: palevioletred;
  6. `;
  7. // 创建一个 Wrapper 组件,它将渲染一个附加了样式的 <section> 标签
  8. const Wrapper = styled.section`
  9. padding: 4em;
  10. background: papayawhip;
  11. `;

react组件中使用样式

  1. function App() {
  2. return (
  3. <Wrapper>
  4. <Title>
  5. Css也是一个组件
  6. </Title>
  7. </Wrapper>
  8. )
  9. }