如何编写优雅的css,我采用的方案是BEM+css module+classnames/bind,下面我们在react组件里面写个todo的例子:
import React from 'react';
import classnames from 'classnames/bind';
import styles from './app.less';
const cx = classnames.bind(styles);
// app.jsx
export default function App(){
return (
<div className={cx('todo')}>
<header className={cx('todo__header')}>this is a header</header>
<main>
<ul className={cx('todo__list')}>
<li className={cx('todo__list__item')}>to do item</li>
<li className={cx('todo__list__item--active')}>to do item in active</li>
</ul>
</main>
</div>
)
}
// app.less
.todo{
&__header{
font-weight:bold;
}
&__list{
font-size:12px;
&__item{
color:#666;
&--active{
color:red;
}
}
}
}
问题环节
- Q: 这里为什么要采用
classnames/bind? A:cx('todo')对比styles.todo,cx('todo__list__item--active')对比styles['todo__list__item--active'],使用cx的方法会简短和优雅许多。同时,如果不安装特殊插件的话,styles.todo会被编辑器识别成变量,在代码高亮上会对组件的状态变量造成视觉上的干扰,cx则不会有这个问题。 cx函数其实没有任何魔法,我们也可以自己简单写一个: function myBind(styles){ return function cx(className){ return styles[className] } } - Q: 为什么这里要采用BEM?
A: 一个是BEM对于团队协作本身的重要意义,可以提高className的可读性,通过className即可知道组件的层次和状态等信息。另一个是性能优化,
app.less里面编译出来的都是单个className,通过尽量减少className 的嵌套来优化css性能。 - Q: less写法上有什么特点:
A: 结合BEM的话,要大量利用
&字符来简化样式代码,这样可以让样式代码更优雅、层次更明确。