Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

css-in-js: emotion / jss #152

Open
magicdawn opened this issue Nov 19, 2022 · 4 comments
Open

css-in-js: emotion / jss #152

magicdawn opened this issue Nov 19, 2022 · 4 comments

Comments

@magicdawn
Copy link
Owner

magicdawn commented Nov 19, 2022

why

之前用过 jss / styled-components, 体验都一般, 依旧坚持 css modules.

css modules 重构的时候比较麻烦:

  • 样式拆分怎么做, 新建 .module.less ? 还是依旧使用原来的样式文件
  • 这样 css in js 的优势来了.
@magicdawn
Copy link
Owner Author

magicdawn commented Nov 19, 2022

@emotion/css

const cls = css`
  margin-top: 1px;
`
  • 比较直接, 生成 className, 返回值类型 string

@emotion/react

  • 用法和 @emotion/css 一样, 但返回值是 SerializedStyles object 类型

css prop

css prop 接收 SerializedStyles 类型, 转变成 className, 传递到最后的 className prop 中

这种转换需要用到 babel plugin

在 vite 中使用

https://dev.to/glocore/configure-emotion-with-your-vite-react-project-7jl

// vite.config.ts
react({
  jsxImportSource: "@emotion/react",
  babel: {
    plugins: ["@emotion/babel-plugin"],
  },
}),

// tsconfig.json
"compilerOptions": {
  "jsx": "react-jsx",
  "jsxImportSource": "@emotion/react"
}

为什么使用 @emition/react

  • SerializedStyles object 类型是可以 compose 的, @emotion/css 直接变成字符串, 就没有多少可以做的事情
  • @emition/css 传递到 className prop, @emotion/react 传递到 css prop, 一样不费力

css 优先级

https://emotion.sh/docs/css-prop#style-precedence

  • Class names containing emotion styles from the className prop override css prop styles.
  • Class names from sources other than emotion are ignored and appended to the computed emotion class name.

有点拗口, 简单说就是

  • props.className css prop transform 而来的, 就会与本级 css prop 合并
  • props.className 如果是普通字符串, 则是 append 到最后 className 里

@magicdawn
Copy link
Owner Author

magicdawn commented Sep 2, 2023

vscode-styled-components & @styled/typescript-styled-plugin

links

vscode-styled-components

vscode 插件, 负责代码高亮. 而且只能高亮 css tag, 变成 import {css as css2} from '@emotion/css' 就失效了

原因, vscode extension contribution 是静态的 json 文件, 目前没有支持配置 styled-components/vscode-styled-components#303 标签 E-Hard

配置

目前支持 css / keyframes / injectGlobal / createGlobalStyles? / stylesheet 这些 tag

@styled/typescript-styled-plugin

  • MS 出的 typescript compiler plugin, styled-components 新的 fork
  • 单独装这个的话, 有 intellisense, 没有高亮

@magicdawn
Copy link
Owner Author

magicdawn commented Sep 2, 2023

format

对于 emotion 而言

// ✅ prettier can format this
const cls = css`
  text-align: center;
`

// ❌ prettier can NOT format this
const cls = styled`
  text-align: center;
`

// ✅ prettier can format this
const cls = styled.xxx`
  text-align: center;
`

@magicdawn
Copy link
Owner Author

magicdawn commented Jan 27, 2024

同时使用 @emotion/css & @emotion/react

  • 大多数情况使用 import {css} from '@emotion/react' 就好
  • 但有时有直接生成 className 的需求, 需要 @emotion/css
  • 可以这样
    import { css as generateClassName } from '@emotion/css'
    export const styled = { generateClassName }
    
    const cls1 = styled.generateClassName`
      color: red;
    `
    // 可以兼具 intellisense & format

新增 tags 需要改造:

  • vscode-styled-components syntaxes/styled-components.json
  • prettier 改造, 没看过代码.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant