CSS-IN-JS是web项目中将CSS代码捆绑在JavaScript代码中的解决方案。
这种方案旨在解决CSS的局限性,例如缺乏动态功能,作用域和可移植性。
CSS-IN-JS是一种css的解决方案,而Emotion库则是具体的工具库。
Emotion是一个旨在使用JaveScript编写CSS样式的库
npm install @emotion/core @emotion/styled
通知babel,不需要将jsx语法转换为React.createElement方法,而是转换为emotion的jsx方法
在组件使用导入jsx
import { jsx } from '@emotion/core'
在package.json文件中找到babel属性,加入如下内容
"@emotion/babel-preset-css-prop"
效果如下:
const style = css`
width:100px;
height:100px;
background:'green'
`
const style =css({
width:200,
height:200,
background:'yellow'
})
props对象中的css属性优先级高于组件内部的css属性,在调用组件时可以在=覆盖组件默认样式。
样式化组件就是用来构建用户界面的,是emotion库提供的另一种 为元素添加样式的方式
import styled from '@emotion/styled'
// 字符串形式
const Button = styled.button`
color:red
`;
// 对象形式
const Button = styled.buttom({
color:red
})
// 字符串形式
const Button = sytled.button`
width:${props => props.width||100px}
`
// 对象形式
const Button = sytled.button(props =>{
width:props.width||100
})
// 或者如下
const Button = sytled.button({
// 这里是默认
width:10
},props =>({
// 这里是props传进来的,这样就不用写判断了
width:100
}))
const Demo = ({className}) => <div className={className}>Demo</div>
const Fancy = styled(Demo)`
color:red;
`
// 或
const Fancy = styled(Demo)({
color:red
})
子组件单独调用color为red,父组件调用时Child的color为green
// 字符串形式
const Child = styled.div`
color:red
`
const parent = sytled.div`
${Child}:{
color:'green'
}
`
// 对象形式
const Child = styled.div({
color:'red'
})
const parent = sytled.div({
[Child] {
color:'green'
}
})
通过&进行关联,& 表示组件本身
const Container = styled.div`
color:red;
& > a {
color:pink;
}
`
要使用组件中的样式,但要更改呈现的元素,可以使用as属性
const Button = styled.button`
color:red;
`
<Button as='a' href='#'>button</Button>
在样式组合中,后调用的样式优先级高于先调用的样式
const base = css`
color:yellow;
`
const danger = css`
color:red;
`
<button css={[base,danger]}>button</button>
import { css,Global } from '@emotion/core'
const globalStyles = css`
body {
margin:0;
background:red;
}
`
function App(){
return <>
<Global styles ={globalStyles} />
app
</>
}
使用emotion提供的 keyframs
import { css, keyframes} from '@emotion/react'
import React from 'react'
const move = keyframes`
0%{
background:red;
left:0;
top:0;
}
100% {
background:tomato;
left:600px;
top:300px;
}
`
const boxCss = css`
width:100px;
height:100px;
position:absolute;
animation: ${move} 2s ease infinite alternate;
`
function App(){
return <div
// @ts-ignore
css = {boxCss}
>app</div>
}
下载主题模块
npm install emotion-theming
import { ThemeProvider } from 'emotion-theming'
// 存储主题样式
const theme = {
colors:{
primary:'hotpink'
}
}
<ThemeProvider theme={theme}></ThemeProvider>
// 获取主题内容
const getPrimaryColor = props => css`
color:${props.colors.primary}
`
<div css={getPrimaryColor}></div>
// 第二种方式
import { useTheme } from 'emotion-theming'
function Demo(){
const theme = useTheme();
}
}
}
```typescript
// 获取主题内容
const getPrimaryColor = props => css`
color:${props.colors.primary}
`
// 第二种方式
import { useTheme } from 'emotion-theming'
function Demo(){
const theme = useTheme();
}