面試官:你怎麼優雅管理 CSS?

面試官靈魂發問:你是如何組織管理你的 CSS 代碼的?css

答:先寫類名, 而後寫樣式。html

卒,享年18.前端

藉由這個面試題目, 咱們來了解 css 管理方式一共有幾種。react

首先寫列個大綱:webpack

  • 佛性選手, 複製粘貼一把梭.
  • 命名空間
  • 命名空間 + BEM 規範
  • CSS module
  • css in js

方案一. 命名空間 + BEM 規範

原理:強行增長一個最外層的命名空間將底部樣式包裹起來。 A.lessweb

.componentA {
   .title {
       color: red;
   }
   .des {
       ...
   }
}
複製代碼

B.less面試

.componentB {
   .title {
       color: red;
   }
   .des {
       ...
   }
}
複製代碼

樣式名遵循 BEM 規範, 讓維護者能夠從類名就分辨出 dom 上的嵌套狀況。方便維護, 以下代碼:bash

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

該方案適用於組件庫的編寫。做爲一個規範的 BEM ,使用者更容易使用。可是若是在一個龐大的業務中, 若是咱們只用 BEM + 命名空間來控制樣式不重疊, 就有點力不從心了。你不可能每開始一個需求, 就查一下目前有多少命名空間。維護變得很困難。babel

因此, 基於這種方案之下, 又延伸了 2種 CSS 管理方案antd

  • 方案二: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 等構建工具自動將類名轉換成局部。 詳細配置: webpack.docschina.org/loaders/css… 好比, 配置樣式名規則:

{
    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 中配置以下:

至此, 咱們總結一下上面的內容:

  1. 命名空間方案 編寫組件庫使用 BEM 規範 + 命名空間方案來. 這樣第三方在調用的時候, 有規範可言, 且不會隨着打包每次的樣式名都發生改變.

  2. css in js / css module 方案 大型業務場景中使用 css modules 或者 css in js。畢竟讓工具來解決問題纔是最完全的解決問題。咱們不可能去 diff 每個地方, 控制你們樣式名不衝突.

好, 看完上面的內容, 大概能夠回答一下面試官的靈魂發問了. 時間回溯, 重來一遍.

  • 面試官:你是如何組織管理你的 CSS 代碼的?
  • 答:分場景. 一. 在編寫公共組件庫的時候, 使用 BEM + 命名空間 …… 二. ……
  • 面試官: 那 css module 中, 大家如何處理引入的第三方庫樣式?
  • 答: css module 中有能夠開啓 module 和關閉module的選項. 對於第三方庫樣式, 關閉 module 選項便可. 配置以下:

  • 面試官: 若是有一個場景, 基於 antd 封裝了一個本身公司風格的組件樣式庫. 怎麼確保在 antd 樣式後加載?
  • 答: 由於 css-loader 實際上只是會解析生成對應的類名, 最後咱們還得根據 style-loader 插入 html 中, 那這裏能夠控制它插入的順序. 根據文檔的配置信息, 控制 css 的插入順序. 便可控制前後加載順序.

固然, 除了以上2種方式,還有不少方案。 關於 css 管理方案, 業界一直沒有統一。 你們都處於我努力說服你,你努力說服個人場景。 不過,只要能解決問題的, 都是好工具~

藉助面試這個場景, 來鞏固下知識. 系統地學習下優雅管理 CSS 的各類方式. 但願對你有幫助~

  • 歡迎關注「前端加加」,認真學前端,作個有專業的技術人...

相關文章
相關標籤/搜索