为组件添加样式的方法主要有两种:外部CSS样式表和 style内联样式
- Grid栅格
- Flexbox
- style行内样式
- 全局样式
- css module
- css in js
- styled-component
- less & sass
css in js增加了成本复杂性
css样式的层叠性和灵活性,是 css in js 没有的
请停止 css in js https://zhuanlan.zhihu.com/p/26878157
组件样式如何覆盖
- 组件样式覆盖全局的样式 > index.less
全局样式
- /index.css, import引入样式文件
- /index.js 直接引入整个 css文件
- 缺点:造成css 样式的全局污染 ```jsx import ‘./index.css’
组件中使用全局样式
<a name="CsB78"></a>
### 全局样式规范
1. 命名规则: xxx.css
2. 引入方式 import ‘xxx.css’
3. 用法:<div className='styleName'>
把样式表文件当作一个模块,在使用该样式表的组件中,像导入其他组件一样导入样式表文件
1. 基础样式表,公共的全局样式
```jsx
import './style.css'; // 要保证相对路径设置正确
覆盖 antd的样式
需要覆盖 Ant Design 样式的,都放在 overwrite-antd.css里面
在 antd的样式后面加上 __ow__
.ant-treee._ow_ { background-color: #96f }
.ant-card-head._ow_, .ant-card-body._ow_ { padding: 16px }
方法的覆盖(override)重载(overload)和重写(overwrite)
css module
- css 模块化
有自己的作用域
模块化的结构处理css文件,把 css转换为 对象
- 有个这个对象之后,就可以通过引用对象属性的方式去定义样式
- 样式用小驼峰命名
- 如果样式有:横线,要用括号来获取,类似于 js的变量
- 好处:更符合模块化的开发原则
- 解决了全局污染的问题
- 解决了命名混乱的问题
- 没有依赖管理。CSS Module 可以让整个工程不使用 saas 或者 less 这样的第三方库
- create-react-app自从2.0.版本就已经开始支持CSS Modules
// 是 css modules
import styled from './index.less';
import styled from './index.module.less';
// 不是 css modules
import './index.css';
import './index.less';
css-module命名规范
- 命名规则: xxx.module.css
- 引入方式 import xxx from ‘xxx.module.css’
- 用法:
import styled from './app.module.less'
function App() {
return (
<div className={styled.card}>
<ul className={styled.cardList}>
<li className={styled.cardItem}>01</li>
<li className={styled['card-item']}>02</li>
</ul>
</div>
)
}
/app.mobule.less
.app {
border: 1px solid #ddd;
&-List {
margin-bottom: 16px;
list-style-type: none;
&:last-child {
margin-bottom: 0
}
}
&-Item {}
.card-item {}
}
样式模块的引用
用 composes 关键字可以在 title 样式里应用 link 样式,,类似于继承
.link {
text-decoration: underline;
text-indent: 2em;
}
.title{
composes: link;
color: red;
font-size: 20px;
}
配置 d.ts自动转化 css
- tsx无法识别 css格式的文件,解决:给 css加上 TS的类型声明
- *.d.ts
- src/ 目录下,新建 custom.d.ts
custom.d.tsimport styled from './app.module.css'
declare module "*.css" {
const css: {[key: string]: string}
export default css
}
typescript-plugin-css-modules
- 让编辑器对 css代码有智能提示
https://www.npmjs.com/package/typescript-plugin-css-modules
npm install typescript-plugin-css-modules -D
tsconfig.json配置 plugins插件,vscode需要配置下 settings.json
"plugins": [
{
"name": "typescript-plugin-css-modules"
}
]
vscode配置
- 项目根目录新建 .vscode文件夹,并进入
- 新建 settings.json,让 vscode可以识别
- settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
inline-style
行内样式,类似于 style的行内样式
行内样式实际上就是 React 元素上的一个属性,属性的值是对象,所有对象的属性名均为 CSS属性
需要注意的是, CSS 属性写法遵循小驼峰命名法
最终生成的是 HTML的 style行内样式
内联样式实际上是一种CSS in JS的写法:将CSS样式写到JS文件中,用JS对象表示CSS样式
style使用了两个大括号,这可能会让你感到迷惑
- 其实,第一个大括号表示 style的值是一个JavaScript表达式
- 第二个大括号表示这个JavaScript表达式是一个对象 ```jsx
const style = {width: 100, height: 300, backgroundColor: ‘red’} function App() { return
}
<a name="b2sMa"></a>
## classnames
可以在同一个标签上使用更多的 CSS 名称
```bash
npm install classnames --save
classnames的用法
import classnames from 'classnames'
import styled from './list.module.css';
function App() {
const [count, setCount] = useState(10)
const cls = classnames('col-2', {
'grid-6': count > 12
})
return (
<div className={ cls('title', 'list-title') }>
<p className={`col-2 ${count ? 'grid-6' : ''}`}/>
// 全局样式和局部样式混用
<div className={`col-2 ${styled['styleName']}`} />
</div>
)
}
bind
引入 classnames
定义 cls 方法,使用 bind 方法,绑定 style 对象
import styled from './list.module.css';
import classnames from 'classnames/bind'
// 定义 cls,使用bind方法绑定 style样式
const cls = classnames.bind(styled)
function App() {
return (
<div className={ cls('title', 'list-title') }>
<p className={`col-2 ${count ? 'grid-6' : ''}`}/>
</div>
)
}
css in js JSS
- jss https://cssinjs.org
- 请停止 css-in-js 的行为 https://zhuanlan.zhihu.com/p/26878157
- css in js 通过 JS 来声明、抽象样式从而提高组件的可维护性
- 从组件的层面对 CSS 进行封装
- 在组件加载时动态的加载样式,动态生成类名从而避免全局污染
jss
styled-components
style-components css-in-js https://styled-components.com/
style-components高级功能:
- 变量
- 循环
- 函数
npm install --save styled-components
styled-components用法
// 创建一个 Title 组件,它将渲染一个附加了样式的 <h1> 标签
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// 创建一个 Wrapper 组件,它将渲染一个附加了样式的 <section> 标签
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
react组件中使用样式
function App() {
return (
<Wrapper>
<Title>
Css也是一个组件
</Title>
</Wrapper>
)
}