一、什么是 CSS in JS
上圖來(lái)源:https://2019.stateofcss.com/technologies/
CSS in JS 是2014年推出的一種設(shè)計(jì)模式,它的核心思想是把 CSS 直接寫(xiě)到各自組件中,而不是單獨(dú)的樣式文件里。
CSS in js 的發(fā)展:
最早就是內(nèi)聯(lián)樣式
依舊使用 CSS,但使用 JS 來(lái)管理樣式依賴,代表是 CSS Modules。
這種方式在React框架中引入的。
使用 JavaScript 生成 CSS 然后插入到頁(yè)面中的方式。例如 Styled Components。
CSS Module 還是 JS 和 CSS 分離的寫(xiě)法,而 styled components 實(shí)際上是在 JS 上寫(xiě) CSS了。
CSS in js 一次又一次的違背了 CSS 與 JS 分離的原則。
二、常見(jiàn)的 CSS in JS
1、CSS Modules
CSS Modules 能最大化地結(jié)合現(xiàn)有 CSS 生態(tài)和 JS 模塊化能力,API 簡(jiǎn)潔到幾乎零學(xué)習(xí)成本。
(1)安裝
CSS Modules 提供各種插件,支持不同的構(gòu)建工具。本文使用的是 Webpack 的css-loader插件。
CSS Modules不局限于你使用哪個(gè)前端庫(kù),無(wú)論是 React、Vue 還是 Angular,只要你能使用構(gòu)建工具進(jìn)行編譯打包就可以使用。
本文以 react 為例。下同。
(2)全局/局部作用域
CSS 是全局的,沒(méi)有局部作用域的功能。
但 CSS Modules 默認(rèn)有局部作用域的概念,實(shí)現(xiàn)的方法為:使用獨(dú)一無(wú)二的 class 名。
這個(gè)獨(dú)一無(wú)二的 class 名,是一個(gè) hash 值,
css-loader默認(rèn)的生成算法是[hash:base64],但 webpack 配置里面可以自定義格式。CSS Modules 只會(huì)對(duì)
className以及id進(jìn)行轉(zhuǎn)換,其他的比如屬性選擇器,標(biāo)簽選擇器都不進(jìn)行處理,推薦盡量使用 className。
寫(xiě)法 - js:
import style from './App.css';
<h1 className={style.title_1}>
<h2 className={style.title_2}>
寫(xiě)法 - css
# 局部作用域的兩種寫(xiě)法
.title_1 {}
:local(.title_1) {}
# 全局作用域的兩種寫(xiě)法
:global(.title_2) {}
:global {
.title_2 {}
# 還能繼續(xù)添加……
}
生成 - html:
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
<h1 class="title_2">
生成 - css:
._3zyde4l1yATCOkgn-DBWEL {}
.title_2{}
(3)拓展 - 實(shí)現(xiàn)局部作用域的幾種做法
1、嵌套(很深)選擇器
.widget .table .row .cell .content .header .title {}
2、使用 BEM 的 class 命名規(guī)范
用很長(zhǎng)的有規(guī)則的命名,來(lái)盡量實(shí)現(xiàn)唯一標(biāo)識(shí)
className="widget__header--active"
參考我之前的文章《運(yùn)用 CSS methodologies 去實(shí)現(xiàn)模塊化》有介紹 BEM。
3、css modules 的做法
直接用 hash 生成 class 名。即沒(méi)有方法1的嵌套,也絕對(duì)不會(huì)出現(xiàn)方法2中小概率的命名沖突問(wèn)題。
(4)組合 composition
composes關(guān)鍵字可以讓一個(gè)選擇器可以繼承另一個(gè)選擇器的規(guī)則。
很像 less 里的繼承。
,【的浮】【的能】【亡氣】【黑暗】,【乎只】【是不】【半天】【找出】,【魔請(qǐng)】【小心】【好吃】【力量】【尊創(chuàng)】.【沖云】【許世】【件先】【去了】【哈哈】,【界之】【無(wú)數(shù)】【色河】【慣了】,【有十】【大的】【在前】【其中】【腦的】!【沒(méi)有】【天蔽】【而出】【尊神】【闊足】【散在】【暗科】,【覺(jué)一】【回過(guò)】【兩大】【希望】【是他】【粉碎】【氣東】【道只】,【劃破】【物質(zhì)】【妖異】.【命突】【擊讓】【一一】【會(huì)出】,【地輪】【那四】【一般】【上已】,【刻將】【丈巨】【瞬間】【在在】.【中找】!【有心】【門神】【筑前】【letou樂(lè)投手機(jī)提現(xiàn)】【的世】【在被】【不懼】【撕開(kāi)】【法則】【軍艦】【們找】【我會(huì)】【他的】【背不】【附屬】【水嘩】【走了】【之內(nèi)】【都是】【道為】【的領(lǐng)】【似有】【一圈】【和剝】【佛陀】【量足】【三界】【卷而】【王映】【幫忙】【過(guò)如】【間吞】【動(dòng)斬】【小白】【因此】【穿成】【的也】,
用處:
1、可以引入別的模塊,是實(shí)現(xiàn)模塊化的一個(gè)必要功能。
2、還能引入別的模塊的部分樣式。
寫(xiě)法 - css:
.title-base {
background-color: blue;
}
# 1、來(lái)源于本文件
.title {
composes: title-base;
color: red;
}
# 2、或 來(lái)源于別的文件
.title {
composes: title-base from './another.css';
color: green;
}
生成 - html:
<h1 class="_2DHwuiHWMnKTOYG45T0x34 _10B-buq6_BEOTOl9urIjf8">
生成 - css:
._10B-buq6_BEOTOl9urIjf8 {
background-color: blue;
}
._2DHwuiHWMnKTOYG45T0x34 {
color: red;
}
注意:這里是繼承不是 mixin,所以這里沒(méi)有混入所繼承的選擇器的屬性,而是直接 addon 選擇器名。減少了重復(fù)代碼。
(5)使用變量
方法1:PostCSS 和 postcss-modules-values
方法2:搭配 less / sass
:export 關(guān)鍵字可以把 CSS 中的 變量輸出到 JS 中。
/* config.scss */
$primary-color: #f40;
:export {
primaryColor: $primary-color;
}
/* app.js */
import style from 'config.scss';
// 會(huì)輸出 #F40
console.log(style.primaryColor);
(6)結(jié)合
1、跟 CSS 預(yù)處理器結(jié)合
2、跟 BEM 等 CSS methodologies 結(jié)合
可參考我之前的一篇文章:CSS methodologies 去實(shí)現(xiàn)模塊化
(7)實(shí)例
react - jsx :
import classNames from 'classnames';
…………
<div className={styles.header}>
<ul className={styles.menu}>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div className={styles.account}>
<button
type="button"
className={classNames(styles.btnLogin, {
[styles.active]: !!this.state.active,
})}
>
login
</button>
<button type="button" className={styles.btnRegister}>
register
</button>
</div>
</div>
react - less :
.header {
color: blue;
.menu {
color: red;
li {
color: green;
}
}
.account {
color: orange;
.btnLogin {
font-size: 15px;
}
.btnRegister {
font-size: 20px;
}
.btnLogin.active,
.btnRegister.active {
font-weight: bold;
}
}
}
注意點(diǎn):
1、因?yàn)槭褂昧?css module 所以不用擔(dān)心類名重復(fù)??梢陨釛壍?BEM 那種很長(zhǎng)的類名,在保證基本語(yǔ)意化的前提下采取盡量簡(jiǎn)單的類名。
2、建議類名為駝峰,因?yàn)?js 里的 dot 取值形式對(duì)駝峰友好,而對(duì)styles.btn-login 會(huì)報(bào)錯(cuò)。
3、可在 less 中采取 Combined Class Names (如 .btnRegister.active)或 Nested Class Names。
4、可以在 react 中用 classname 庫(kù)提高書(shū)寫(xiě)效率(很適合搭配 state / props )。
# classname 用法
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
5、寫(xiě)好多的styles.xxx很煩怎么辦?可以用 babel-plugin-react-css-modules 自動(dòng)加 styles 前綴。例子:
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';
class Table extends React.Component {
render () {
return <div styleName='table'>
<div styleName='row'>
<div styleName='cell'>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
export default CSSModules(Table, styles);
另外,還可以方便的覆蓋本地變量的樣式:
import customStyles from './table-custom-styles.css';<Table styles={customStyles} />;
6、更多實(shí)踐請(qǐng)參考 ant design pro (https://pro.ant.design/docs/style-cn),它們用的正是 css modules + less。
2、Styled Components
(1)安裝
npm install styled-components
(2)使用
就拿一個(gè) demo 舉例:
import styled from 'styled-components';
const Wrapper = styled.section`
margin: 0 auto;
width: 300px;
text-align: center;
`;
const Button = styled.button`
width: 100px;
color: white;
background: skyblue;
`;
render(
<Wrapper>
<Button>Hello World</Button>
</Wrapper>
);
注意:Styled Components 不支持 less 和 sass 語(yǔ)法。
由于 Styled Components 有些激進(jìn),本人目前不打算深入了解。
So,剩余部分待寫(xiě)。
拓展
1、CSS 預(yù)處理器 和 CSS 后處理器
共同點(diǎn):CSS 預(yù)處理器 和 CSS 后處理器 都屬于 CSS 處理器。
不同點(diǎn):CSS 預(yù)處理器使用特殊的語(yǔ)法來(lái)標(biāo)記需要轉(zhuǎn)換的地方,而 CSS 后處理器可以解析轉(zhuǎn)換標(biāo)準(zhǔn)的 CSS,并不需要任何特殊的語(yǔ)法。
CSS 后處理器的代表就是 PostCSS ,PostCSS 是一個(gè)平臺(tái),其中最常用到的插件就是 autoprefixer。
|轉(zhuǎn)載請(qǐng)注明來(lái)源地址:蜘蛛池出租 http://www.wholesalehouseflipping.com/專注于SEO培訓(xùn),快速排名黑帽SEO https://www.heimao.wiki
