github代码库:GitHub - OnionGF/CSS-in-js: css-in-js 代码库

集成在 css 代码 在 javaScript 文件中

目录:

  • 为什么会有 CSS-IN-JS
  • CSS-IN-JS 介绍
  • Emotion 库

1、为什么会有 CSS-IN-JS

CSS-IN-JS 是 WEB 项目中 将 CSS 代码 捆绑在 JavaScript 代码中的解决方案
这种方案旨在解决 CSS 的局限性, 例如缺乏动态功能, 作用域和 可移植性

css 没有作用域的概念, css-in-js 利用js 的作用域 来模拟 css 的作用域

2、CSS-IN-JS 介绍

优点:

  • 让 CSS 代码拥有独立的作用域,组织 css 代码泄漏到组件外部,防止样式冲突
  • 让组件更具有可移植性,实现开箱即用,轻松创建松耦合的应用程序
  • 让组件更具有可重用性,只需编写一次即可,可以在任何地方运行,不仅可以在用一个应用程序中重用组件,而且可以在使用相同框架构建的其他应用中重用组件
  • 让样式具有动态功能,可以将复杂的逻辑应用于样式规则,如果要创建需要动态动能的复杂UI,他是理想的解决方案

缺点:

  • 为项目增加了额外的复杂性
  • 自动生成的选择器大大降低了代码的可读性

    3、Emotion 库

    3.1 Emotion 介绍

    Emotion 是一个旨在使用JavaScript 编写的 CSS 样式的库

    npm install @emotion/core @emotion/styled

3.2 css 属性支持

1、jsx Pragma

通知babel,不再需要将 jsx 语法转换为 React.createElement 方法,而是需要转换为 jsx 方法
image.png

2、Babel Preset (推荐)

  • npm run eject
  • npm install @emotion/babel-preset-css-prop
  • 在 package.json 文件中找到 babel 属性,加入以下内容
  • image.png

如果报错 尝试执行下面的命令解决:

npm install @mui/material @emotion/react @emotion/styled

3.3 css 方法

1、String Styles (推荐 更符合 写css 代码的习惯)

  1. import { css } from '@emotion/core';
  2. const style = css`
  3. width: 100px;
  4. height: 100px;
  5. background: skyblue
  6. `
  7. <div css={style}>CSS-IN-JS</div>

2、Object Styles

  1. import { css } from '@emotion/core';
  2. const style = css({
  3. width: 100;
  4. height: 100;
  5. background: 'skyblue'
  6. });
  7. <div css={style}>CSS-IN-JS</div>

3.4 css属性优先级

prop 对象中的css 属性优先级高于组件内部的 css 属性
在调用组件时可以再覆盖组件默认样式

  1. import React from 'react';
  2. import { css } from '@emotion/core'
  3. const style = css`
  4. width: 100px;
  5. height: 200px;
  6. background: skyblue;
  7. `
  8. function Css(props) {
  9. return <div css={style} {...props}> css - in - js </div>
  10. }
  11. export default Css;

如上述代码所示, props 时外部调用组件时传进来的样式
当style 和 props 同时存在时, props 样式的优先级是高于style 样式的

3.5 Styled Components 样式化组件

样式化组件就是采用构建用户界面的, 是emotion 库提供的
另一种 为元素添加样式的方式

3.5.1、 创建样式化组件

import styled from ‘@emotion/styled’

1、String Styles
image.png

2、Object Styles
image.png

  1. import styled from '@emotion/styled';
  2. const Button = styled.button`
  3. width: 100px;
  4. height: 50px;
  5. background: blue;
  6. `
  7. function App() {
  8. return (
  9. <div>
  10. <Button>我是一个按钮</Button>
  11. </div>
  12. );
  13. }
  14. export default App;

3.5.2、 根据 props 属性覆盖样式


1、String Styles

image.png

2、Object Styles

image.png
image.png

3.5.3、为任何组件添加样式

有一个Demo 组件 , 想在每次调用时, 为其传递不同的组件样式

1、String Styles

image.png

2、Object Styles

image.png

3.5.4、通过父组件设置子组件样式

Child 组件单独用的时候 文字是 红色
Child 组件 被 Parent 组件包裹的时候 文字是 绿色

1、String Styles

image.png

2、Object Styles

image.png

3.5.5、嵌套选择器 &

& 表示组件本身
如:
&:hover 鼠标滑过组件时
& > span 组件的子元素 span
image.png

3.5.6 as 属性

要使用组件中的样式, 但要更改呈现的元素, 可以使用 as 属性
image.png

3.6 样式组合

在样式组合中,后调用的样式优先级高于先调用的样式

import { css } from ‘@emotion/core’

image.png

3.7 全局样式

image.png

3.8 关键帧动画

import { keyframes, css } from ‘@emotion/core’

image.png

  1. import { keyframes, css } from '@emotion/core'
  2. const move = keyframes`
  3. 0% {
  4. left:0;
  5. top: 0;
  6. background: pink;
  7. }
  8. 100% {
  9. top: 300px;
  10. left: 600px;
  11. background: skyblue;
  12. }
  13. `
  14. const box = css`
  15. width: 100px;
  16. height: 100px;
  17. position: absolute;
  18. animation: ${move} 4s ease infinite alternate;
  19. `
  20. function Box () {
  21. return <div css={box}>app move</div>
  22. }
  23. export default Box

3.9 主题

1、主题模块emotion-theming (该模块已经移动到@emotion/react)

npm install emotion-theming

2、引入 ThemeProvider 组件

import { ThemeProvider } from ‘@emotion/react’;

3、将 ThemeProvider 放置在视图最外层、添加主题内容

  1. const root = ReactDOM.createRoot(document.getElementById('root'));
  2. const theme = {
  3. colors: {
  4. primary: 'tomato'
  5. }
  6. }
  7. root.render(
  8. <React.StrictMode>
  9. <ThemeProvider theme={theme}>
  10. <App />
  11. </ThemeProvider>
  12. </React.StrictMode>
  13. );

4、获取主题内容

1、props 方式获取

  1. const themeColor = props => css`
  2. color: ${props.colors.primary}
  3. `

2、钩子函数的方式获取

  1. import { useTheme } from '@emotion/react';
  2. const theme = useTheme()
  3. const themeColor = props => css`
  4. color: ${theme.colors.primary}
  5. `