前言
1针余、分析 Class
Class 類(lèi)似于簡(jiǎn)單的 js 對(duì)象仔蝌,由鍵值對(duì)組成(property & value)沙热。
層疊樣式表( Cascading Stylesheet 博烂,簡(jiǎn)稱(chēng)CSS )木西, 其基本目標(biāo)是讓瀏覽器以指定的特性去繪制頁(yè)面元素,比如顏色找筝,定位蹈垢,裝飾。CSS的語(yǔ)法反映了這個(gè)目標(biāo)袖裕,由下面兩個(gè)部分構(gòu)建:
- 屬性( property)是一個(gè)標(biāo)識(shí)符曹抬,用可讀的名稱(chēng)來(lái)表示其特性。
- 值(value)則描述了瀏覽器引擎如何處理該特性急鳄。每個(gè)屬性都包含一個(gè)有效值的集合谤民,它有正式的語(yǔ)法和語(yǔ)義定義,被瀏覽器引擎實(shí)現(xiàn)疾宏。
一個(gè) Class 所擁有的 property张足,表明了該 Class 所擁有的樣式屬性, value 則代表了該 Class 所擁有的樣式屬性的具體表現(xiàn)坎藐。
.Class {
property: value;
}
CSS 樣式有一個(gè)覆蓋的規(guī)則为牍,默認(rèn)遵循的是后來(lái)者居上。
.Class1 {
width: 100px;
width: 50px;
}
.Class2 {
width: 100px;
}
.Class2 {
width: 50px;
}
此時(shí)岩馍, Class1 和 Class2 實(shí)際表現(xiàn)出來(lái)的樣式都是width: 50px;
碉咆。
不過(guò),凡事總會(huì)有特殊情況蛀恩,
.Class1 {
width: 100px !important;
width: 50px;
}
.Class2 {
width: 100px !important;
}
.Class2 {
width: 50px;
}
在這種情況下疫铜, Class1 和 Class2 實(shí)際表現(xiàn)出來(lái)的樣式都是width: 100px;
。
由于
!important
的壓倒性實(shí)力双谆,以及對(duì) CSS 樣式表現(xiàn)的破壞性壳咕, 不可隨意使用!important
,需要嚴(yán)格注意使用的場(chǎng)景以及使用的方式佃乘。
- Never 永遠(yuǎn)不要在全站范圍的 css 上使用
!important
- Only 只在需要覆蓋全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定頁(yè)面中使用
!important
- Never 永遠(yuǎn)不要在你的插件中使用
!important
- Always 要優(yōu)化考慮使用樣式規(guī)則的優(yōu)先級(jí)來(lái)解決問(wèn)題而不是
!important
2囱井、分析 property & value
首先,需要明確幾個(gè)概念:初始值趣避,繼承,計(jì)算值新翎,應(yīng)用值程帕。
Property
TODO
Value
在 js 中,有多種數(shù)據(jù)類(lèi)型地啰,比如:String
類(lèi)型愁拭,Object
類(lèi)型,Number
類(lèi)型亏吝。
在 CSS 中岭埠,同樣也有數(shù)據(jù)類(lèi)型,通常稱(chēng)之為數(shù)據(jù)格式,即 Data types 惜论。
常用的 CSS 數(shù)據(jù)格式许赃,有如下幾種。
<number>
表示數(shù)字馆类,整數(shù)或小數(shù)混聊。
10, 0.5, -1
<length>
表示距離尺寸。
100vw, 100vh, 16px, 1em, 1rem
<color>
表示顏色乾巧。
#f03, #F03, #f03f03, #F03F03
rgb(255,0,0), rgba(255,0,0,1)
hsl(0,100%,50%), hsla(0,100%,50%,1)
其他的就不列舉了句喜,可參照 MDN
組件樣式庫(kù)的設(shè)計(jì)
1、如何解構(gòu)組件沟于,如何規(guī)劃組件咳胃,如何分析組件)
從 HTML 標(biāo)簽的角度來(lái)考量,組件是可以分成兩種的旷太,分別是: 多標(biāo)簽組件 和 單標(biāo)簽組件展懈。
- 對(duì)于單標(biāo)簽組件來(lái)說(shuō),結(jié)構(gòu)實(shí)際上更多指的是泳秀,組件的樣式構(gòu)成标沪。
- 對(duì)于多標(biāo)簽組件來(lái)說(shuō),結(jié)構(gòu)則更多指的是 HTML 標(biāo)簽結(jié)構(gòu)嗜傅。
單標(biāo)簽組件
<!-- 單標(biāo)簽組件 -->
<button class="btn btn-primary">I am primary button</button>
<button class="btn btn-outline-primary">I am outline primary button</button>
/* 基本樣式 .block */
.btn {
/* ... */
color: black;
/* ... */
}
/* 修飾樣式 .block-modifier */
.btn-primary {
/* ... */
color: blue;
/* ... */
}
/* 修飾樣式 .block-modifier */
.btn-outline-primary {
/* ... */
color: blue;
background-color: transparent;
/* ... */
}
多標(biāo)簽組件
<!-- 多標(biāo)簽組件 -->
<ul class="sidenav">
<li class="sidenav-item">
<a href="/nav1">nav1</a>
</li>
<li class="sidenav-item">
<a href="/nav2">nav2</a>
</li>
<li class="sidenav-item">
<a href="/nav3">nav3</a>
</li>
<li class="sidenav-item">
<a href="/nav4">nav4</a>
</li>
</ul>
從組件的直觀表現(xiàn)上來(lái)看金句,組件則可以按照四個(gè)部分來(lái)解構(gòu),分別是: 結(jié)構(gòu)吕嘀、 配色违寞、 尺寸、 狀態(tài)偶房。
a) 結(jié)構(gòu)
結(jié)構(gòu)是組件的根基趁曼,是組件的骨架。但 單標(biāo)簽組件 與 多標(biāo)簽組件 在結(jié)構(gòu)的表現(xiàn)上棕洋,是有一些不同的挡闰。
* 對(duì)于單標(biāo)簽組件來(lái)說(shuō),結(jié)構(gòu)實(shí)際上更多指的是掰盘,組件的樣式的構(gòu)成摄悯。
* 對(duì)于多標(biāo)簽組件來(lái)說(shuō),結(jié)構(gòu)則更多指的是 HTML 標(biāo)簽的結(jié)構(gòu)愧捕。
b) 配色
組件可以擁有不同的的配色奢驯,配色可以理解成是組件的樣貌。
<button class="btn btn-style1">style1 is my style</button>
<button class="btn btn-style2">style2 is my style too</button>
<button class="btn btn-style3">style3 is my style too</button>
c) 尺寸
人有高有矮次绘,組件會(huì)有不同的尺寸瘪阁。
<button class="btn">I am a button</button>
<button class="btn btn-small">I become a small button</button>
<button class="btn btn-medium">I become a medium button</button>
<button class="btn btn-large">I become large button</button>
d) 狀態(tài)
狀態(tài)可以理解為是用戶(hù)和組件互動(dòng)撒遣,使組件產(chǎn)生的狀態(tài)。
狀態(tài)可以大致分為兩類(lèi):enable state
和disabled state
管跺。
enable state
亦可稱(chēng)為 element state
.Class:active { property: value; }
.Class:focus { property: value; }
.Class:hover { property: value; }
.Class:visited { property: value; }
亦可用如下方式义黎,來(lái)表示 enable state
的持久化狀態(tài)
.Class.active { property: value; }
.Class.focus { property: value; }
.Class.hover { property: value; }
.Class.visited { property: value; }
disabled state
亦可稱(chēng)為 special state
.Class.disabled { property: value; }
.Class.loading { property: value; }
2、如何設(shè)計(jì)組件
組件樣式的 Class 命名依據(jù) BEM 方式命名伙菜,即 Block & Element & Modifier轩缤。
書(shū)寫(xiě)方式有兩種,如下所示:
下文中 .block & .block-element & .block-element-modifier 皆為代指贩绕。
/* 第一種寫(xiě)法 */
.block {}
.block--modifier {}
.block__element {}
.block__element--modifier {}
/* 第二種寫(xiě)法 */
.block {}
.block-modifier {}
.block-element {}
.block-element-modifier {}
第一種寫(xiě)法是標(biāo)準(zhǔn)寫(xiě)法火的,第二種寫(xiě)法算是簡(jiǎn)潔的寫(xiě)法。下面按照第二種寫(xiě)法進(jìn)行詳細(xì)說(shuō)明淑倾。
按照 BEM 方式書(shū)寫(xiě)的 Class 馏鹤,在單標(biāo)簽組件和多標(biāo)簽組件中,所代表的含義大部分都是相同娇哆,小部分有差異湃累。
BEM 之 .block
單標(biāo)簽組件
在單標(biāo)簽組件中,.block
多數(shù)情況是作為 基礎(chǔ)樣式 來(lái)存在碍讨。
<!-- 單標(biāo)簽組件 -->
<button class="btn btn-primary">I am component</button>
多標(biāo)簽組件
在多標(biāo)簽組件中治力,.block
更多是作為 容器 的存在。
<!-- 多標(biāo)簽組件 -->
<div class="modal">
<div class="modal-header">
<div class="modal-title">title</div>
</div>
<div class="modal-body">
<div class="modal-text">
<a href="#" class="modal-link">link</a>
</div>
</div>
<div class="modal-footer">
<div class="modal-text">
![](#)
</div>
</div>
</div>
BEM 之 .block-modifier
單標(biāo)簽組件
在單標(biāo)簽組件中勃黍,.block-modifier
與 .block
疊加使用宵统,作為 .block
的修飾。
<!-- 單標(biāo)簽組件 配色-->
<button class="btn btn-primary">I am component</button>
<button class="btn btn-primary-ghost">I am component</button>
<!-- 單標(biāo)簽組件 尺寸-->
<button class="btn btn-small">I am component</button>
<button class="btn btn-large">I am component</button>
<!-- 單標(biāo)簽組件 狀態(tài)-->
<button class="btn btn-primary btn-loading">I am component</button>
<button class="btn btn-primary btn-disabled">I am component</button>
這里的.btn-primary-ghost
實(shí)際上是作為.block-modifier
存在的覆获,這是一種比較特殊的情況马澈,也是用簡(jiǎn)潔方式書(shū)寫(xiě) BEM 可能會(huì)遇到的情況。
多標(biāo)簽組件
在多標(biāo)簽組件中弄息,.block-modifier
與 .block
疊加使用痊班,一般只會(huì)影響組件的容器 .block
。
<!-- 多標(biāo)簽組件 -->
<div class="modal modal-center">
<div class="modal-header">
<div class="modal-title">title</div>
</div>
<div class="modal-body">
<div class="modal-text">
<a href="#" class="modal-link">link</a>
</div>
</div>
<div class="modal-footer">
<div class="modal-text">
![](#)
</div>
</div>
</div>
BEM 之 .block-element
單標(biāo)簽組件
在單標(biāo)簽組件中摹量,實(shí)際上是沒(méi)有 .block-element
的涤伐。
多標(biāo)簽組件
在多標(biāo)簽組件中,.block-element
是位于 .block
之內(nèi)的缨称。
<!-- 多標(biāo)簽的組件废亭,.block-element 需在 .block 之內(nèi)。 -->
<div class="modal">
<div class="modal-header"></div>
<div class="modal-body">
<!-- .modal-text-right 將文字右對(duì)齊 -->
<div class="modal-text modal-text-right">
<a href="#" class="modal-link">link</a>
</div>
</div>
<div class="modal-footer"></div>
</div>
BEM 之 .block-element-modifier
單標(biāo)簽組件
皮之不存毛將焉附具钥。
多標(biāo)簽組件
在多標(biāo)簽組件中,.block-element-modifier
與 .block
疊加使用液兽,類(lèi)似于 .block-modifier
與 .block
的用法骂删。
<!-- 多標(biāo)簽的組件掌动,.block-element 需在 .block 之內(nèi)。 -->
<div class="modal">
<div class="modal-header"></div>
<div class="modal-body"></div>
<div class="modal-footer"></div>
</div>
3宁玫、組件的父容器布局
父容器并不是必須的粗恢。
組件一般來(lái)說(shuō),都是會(huì)被其他的容器包裹的欧瘪。用組件的父容器進(jìn)行頁(yè)面布局眷射,組件則作為內(nèi)容填充。
一般通過(guò)以下兩種方式來(lái)設(shè)置父容器佛掖。
a) 用組件的 .block
作為父容器的 .block
常用的容器命名有以下幾種妖碉。
.block-container { property: value; } /* 常用于只有一個(gè)直接子元素的組件 */
.block-list { property: value; } /* 常用于列表式的布局 */
.block-group { property: value; } /* 常用語(yǔ)包裹 inline 的組件 */
以下是示例:
<!-- .modal-container -->
<div class="modal-container">
<!-- .modal 應(yīng)是 .modal-container 的直接子元素。-->
<div class="modal">
<div class="modal-header">
<div class="modal-title">title</div>
</div>
<div class="modal-body">
<div class="modal-text">
<a href="#" class="modal-link">link</a>
</div>
</div>
<div class="modal-footer">
<div class="modal-text">
![](#)
</div>
</div>
</div>
</div>
<!-- .card-list -->
<!-- .card-list 的直接子元素只可以是 .card-->
<div class="card-list">
<!-- .card 應(yīng)是 .card-list 的直接子元素芥被。-->
<div class="card">
<div class="card-text"></div>
</div>
<div class="card">
<div class="card-text"></div>
</div>
<div class="card">
<div class="card-text"></div>
</div>
</div>
<!-- .image-group -->
<div class="image-group">
<!-- .image 應(yīng)是 .image-group 的直接子元素欧宜。-->
<a class="image">
![](#)
</a>
<a class="image">
![](#)
</a>
<a class="image">
![](#)
</a>
</div>
其實(shí)這里避免的是 .block-item
的出現(xiàn)。
在一些情況下拴魄,也可以使用 .block
作為父容器冗茸, .block-item
作為內(nèi)容體。
<div class="nav">
<div class="nav-item"><a href=""></a>nav-a</div>
<div class="nav-item"><a href=""></a>nav-b</div>
<div class="nav-item"><a href=""></a>nav-c</div>
</div>
不過(guò)匹中,推薦不用 .block-item
夏漱。
<div class="nav">
<div class="nav-link"><a href=""></a>nav-a</div>
<div class="nav-link"><a href=""></a>nav-b</div>
<div class="nav-link"><a href=""></a>nav-c</div>
</div>
b) 設(shè)置專(zhuān)用的布局容器,來(lái)進(jìn)行布局
定義專(zhuān)門(mén)的布局容器顶捷,來(lái)包裹組件挂绰。
/* 以下只是進(jìn)行舉例 */
/* container */
.container { property: value; }
/* list */
.list { property: value; }
.list-item { property:value; }
/* group */
.group { property: value; }
.group-item { property: value; }
<!-- .container -->
<div class="container">
<!-- .modal 應(yīng)是 .container 的直接子元素-->
<div class="modal">
<div class="modal-header"></div>
<div class="modal-body"></div>
<div class="modal-footer"></div>
</div>
</div>
<!-- .list -->
<div class="list">
<div class="list-item">
<!-- .card 是 .list-item 的直接子元素-->
<div class="card">
<div class="card-img"></div>
<div class="card-text"></div>
</div>
</div>
</div>
<!-- .group -->
<div class="group">
<!-- .image 應(yīng)是 .group 的直接子元素。-->
<div class="group-item">
<a class="image">
![](#)
</a>
</div>
<div class="group-item">
<a class="image">
![](#)
</a>
</div>
<div class="group-item">
<a class="image">
![](#)
</a>
</div>
</div>