难不成是因为天下大势,分久必合,合久必分?
传统前端推崇的“关注点分离”原则,推荐将 HTML、CSS、JavaScript 分离,各司其职。但是随着 React“组件化”思想的推进,已经将 HTML 用 JSX 的形式与 JavaScript 文件整合在一起,CSS 也可以通过以下写法同样的放入一个文件:
1
2
3
4
5
6
7
8
9
10
11
|
const Component = () => (
<div
style={{
color: "white",
fontSize: "12px",
}}
onClick={handleClick}
>
text
</div>
);
|
但是这样写不支持复杂的嵌套、选择器等特性,使用起来不太方便。这里介绍几个 css-in-js 的库和一些基本用法!
基本用法: codeSandbox
1
2
3
4
5
6
7
8
9
10
11
|
import React from "react";
import Styled from "styled-components";
const Button = Styled.a`
border-radius: 3px
// ...
`;
function App() {
return <Button>Learn React</Button>;
}
|
模板字符串也可以用 object 代替:
1
2
3
4
|
const Button = Styled.a({
borderRadius: "3px",
// ...
});
|
使用模板字符串或者传入 object 来生成一个组件,直接使用便可。
全局样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
div {
margin: 20px
}
`;
return (
<>
<GlobalStyle />
<div>
<h3> initial button </h3>
</div>
</>
);
|
基本用法: codeSandbox
1
2
3
4
5
6
7
8
9
|
/** @jsx jsx */
import { jsx } from "@emotion/core";
const baseBtn = {
borderRadius: "3px",
// ...
};
return <button css={baseBtn}>Learn React</button>;
|
emotion 支持给 css 属性传入 object 格式的样式数据,但是想生效需要遵循以下两种方法其一:
- 可以自定义 babelrc 文件的,引入一个 babel preset:
1
2
3
4
|
// .babelrc
{
"presets": ["@emotion/babel-preset-css-prop"]
}
|
- 不可以自定义 babelrc 的,(如使用了
create-react-app
)可以引入一个注释:
1
2
|
/** @jsx jsx */ // 对,就是这个
import { jsx } from "@emotion/core";
|
两种途径都是一个目的,用 emotion 的jsx
方法来解析 jsx 而不是用React.createElement
。
css 属性也可以用模板字符串:
1
2
3
4
5
6
7
8
9
|
/** @jsx jsx */
import { jsx, css } from "@emotion/core";
const baseBtnWithTag = css`
border-radius: 3px;
// ...
`;
return <button css={baseBtnWithTag}>Learn React</button>;
|
还可以用类似 styled-components
的方法(模板字符串或者 object 都可以):
1
2
3
4
5
6
7
8
|
import styled from "@emotion/styled";
const Button = styled.a`
border-radius: 3px;
// ...
`;
return <Button>Learn React</Button>;
|
全局样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import { jsx, css, Global } from "@emotion/core";
const global = {
div: {
margin: "20px",
},
};
return (
<>
<Global styles={css(global)} />
<div>
<h3> initial button </h3>
</div>
</>
);
// 或者是
return (
<>
<Global
styles={css`
div {
margin: 20px;
}
`}
/>
<div>
<h3> initial button </h3>
</div>
</>
);
|
为什么同样的样式规则,展示出来的却不一样呢!
自我感觉是因为1em
是相对根元素的尺寸,用 css 属性注入的样式保留了浏览器给 button 的原生样式,但是生成新 Button 的方法没有保留,所以他们相对的根元素是不一样的,样式就不一样啦!
基本用法:codeSandbox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import jss from "jss";
import preset from "jss-preset-default";
jss.setup(preset());
const styles = {
button: {
borderRadius: "3px",
// ...
},
};
function App() {
const { classes } = jss.createStyleSheet(styles).attach();
return <button className={classes.button} />;
}
|
全局样式:
1
2
3
4
5
6
7
|
const styles = {
"@global": {
div: {
margin: "20px",
},
},
};
|
别的资料