36

面试官:你怎么优雅写 CSS?

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA5NzkwNDk3MQ%3D%3D&%3Bmid=2650590930&%3Bidx=1&%3Bsn=80a47e9ebd8c86c7042ea12423490b15
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

面试官灵魂发问:你是如何组织管理你的 CSS 代码的? 

答:先写类名, 然后写样式。 

卒,享年18. 

借由这个面试题目, 我们来了解 css 管理方式一共有几种。 

首先写列个大纲: 

  1. 佛性选手, 复制粘贴一把梭. 

  2. 命名空间

  3. 命名空间 + BEM 规范

  4. CSS module 

  5. css in js 

方案一.  命名空间 + BEM 规范

原理:强行增加一个最外层的命名空间将底部样式包裹起来。

A.less

.componentA {

.title {

color : red ;

}

.des {

...

}

}

B.less

.componentB {

.title {

color : red ;

}

.des {

...

}

}

样式名遵循  BEM 规范 , 让维护者可以从类名就分辨出 dom 上的嵌套情况。方便维护, 如下代码:

.componentA {
    &__title {
        font-size: 14px;
    }
}
<div class="componentA">
    <h1 class="componentA__title">组件A的title</h1>
</div>

该方案适用于组件库的编写。作为一个规范的 BEM ,使用者更容易使用。但是如果在一个庞大的业务中, 如果我们只用 BEM + 命名空间来控制样式不重叠, 就有点力不从心了。你不可能每开始一个需求, 就查一下目前有多少命名空间。维护变得很困难。

所以, 基于这种方案之下, 又延伸了 2种 CSS 管理方案

  • 方案二:CSS in JS

  • 方案三:CSS Modules

方案二.  CSS in JS

使用 js 语言写 css ,目前比较受欢迎的:   styled-components. 

语法如下:

import React from 'react' ;

import styled from 'styled-components' ;

const Title = styled .h1 `

font-size : 1.5em ;

text-align : center ;

color : palevioletred ;

`;

< Title >

Hello World, this is my first styled component!

</ Title >

emmm, 仁者见仁, 智者见智。如果喜欢这种方式,可以尝试使用。作者没有采用这种方案, 比较喜欢 js 跟 css 隔离的感觉。没有实践没有发言权, 所以就不赘述了.

方案三.  CSS Modules 

原理:利用 webpack 等构建工具自动将类名转换成局部。

详细配置: https://webpack.docschina.org/loaders/css-loader/

比如, 配置样式名规则: 

{

loader: 'css-loader' ,

options: {

importLoaders: 2 ,

modules: isModules ,

localIdentName: '[name]__[local]__[hash:base64:5]'

}

}

代码如下:

import React from 'react' ;

import style from './App.css' ;

export default () => {

return (

< h1 className = { style . title } >

Hello World

</ h1 >

);

};

在 app.css 中

.title {

color : red ;

}

可是这种方法有很多限制, 如下: 

  • 无论何时构造类名,都必须使用styles对象。

  • 混合CSS模块和全局CSS类是很麻烦的。

  • 对未定义的CSS模块的引用解析为未定义,没有警告。

基于上面的问题,  react 有一个插件   react-css-modules . 它可以让你直接写 styleName 或者 className 来区分是本地类名还是全局类名. 且通通解决上面的问题. 

< div styleName = "lock-item" className = "lock-global" >

老师列表

</ div >

编译后的 CSS,classname 根据配置的规则生成了对应的名字。

可以看到, className 的并不会根据 webpack 的 配置生成对应的类名, styleName 则会. 

在书写样式时, 也可方便的使用 :global 和 :local 来区分是全局.  :local 是默认注入的, 因此只需要对全局样式标明即可. 

.lock-item {

line-height : 24px ;

margin-bottom : 8px ;

}

:global .lock-global {

color : red ;

}

在 babel-plugin-react-css-modules  中配置如下:

Q3Iniij.png!web

至此, 我们总结一下上面的内容: 

1、 命名空间方案 

编写组件库使用 BEM 规范 + 命名空间方案来. 这样第三方在调用的时候, 有规范可言, 且不会随着打包每次的样式名都发生改变. 

2、css in js / css module 方案

大型业务场景中使用 css modules 或者 css in js。毕竟让工具来解决问题才是最彻底的解决问题。我们不可能去 diff 每一个地方, 控制大家样式名不冲突.

好, 看完上面的内容, 大概可以回答一下面试官的灵魂发问了. 时间回溯, 重来一遍. 

面试官: 你是如何组织管理你的 CSS 代码的?  

答:分场景. 一. 在编写公共组件库的时候, 使用 BEM + 命名空间 ……  二. …… 

面试官:  那 css module 中, 你们如何处理引入的第三方库样式? 

答: css module 中有可以开启 module 和关闭module的选项. 对于第三方库样式, 关闭 module 选项 即可. 配置如下: 

QBN3Qvj.png!web

面试官:  如果有一个场景, 基于 antd 封装了一个自己公司风格的组件样式库. 怎么确保在 antd 样式后加载? 

答: 因为 css-loader 实际上只是会解析生成对应的类名, 最后我们还得根据 style-loader 插入 html 中, 那这里可以控制它插入的顺序. 根据文档的配置信息, 控制 css 的插入顺序. 即可控制先后加载顺序. 

2uuqimV.png!web

借助面试这个场景, 来巩固下知识. 系统地学习下 优雅管理 CSS 的各种方式.  希望对你有帮助~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK