本篇內(nèi)容主要講解“如何理解CSS中的屬性模塊”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何理解CSS中的屬性模塊”吧!
建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁設(shè)計師等,應(yīng)用各種網(wǎng)絡(luò)程序開發(fā)技術(shù)和網(wǎng)頁設(shè)計技術(shù)配合操作的協(xié)同工作。成都創(chuàng)新互聯(lián)公司專業(yè)提供成都網(wǎng)站建設(shè)、做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站制作(企業(yè)站、響應(yīng)式網(wǎng)站建設(shè)、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗的提升,我們力求做到極致!
更多 vs 更少 - 簡單比較
神奇的是,雖然在標(biāo)簽里面放那么多類讓我非常不爽,可是人們愛哈利,因為他太特么能說了。提倡的某些東西,比如說 OOCSS 和單一責(zé)任原則,從我自己創(chuàng)建的一系列日益復(fù)雜的網(wǎng)站來看,我可以說這確實值得對樣式行為進(jìn)行解耦,不過直到最近我才找到一種讓我覺得滿意的方式來實現(xiàn)它。
我原先有做過一個 BEM 的版本,它強(qiáng)調(diào)了獨立高于重用 ‐ 每個新的塊默認(rèn)是沒有樣式繼承的,允許組件獨立開發(fā)并且可以避免打亂頁面其它樣式的風(fēng)險。不過代價就是碎片化(fragmentation) ‐ 忽然你會發(fā)現(xiàn)你有了 10 種不同的樣式鏈接,12 種不同的藍(lán)色,18 種差別細(xì)小的按鈕樣式等。妮可?沙利文,OOCSS 的作者,去年在墨爾本做了一個超贊的演示,講到了這個問題是有多普遍,以及怎么解決它。
對我來說,我覺得可以接受的解決方案是,深入 CSS 的預(yù)處理機(jī)能,從而取得 BEM 的獨立性以及 OOCSS 的一致性。比如說,下面這樣的:
CSS Code復(fù)制內(nèi)容到剪貼板
.btn { /* button styles */ }
.large { /* global large-type modifier */ }
.rounded { /* global rounded-border modifier */ }
應(yīng)該改成這樣:
CSS Code復(fù)制內(nèi)容到剪貼板
.btn { /* button styles */ }
.btn--large { @extend %large-type;}
.btn--rounded { @extend %rounded-borders;}
我成功終結(jié)了充滿了占位符的文件,比如滿眼都是那些_typography.scss 和 _brand.scss,這不但讓我有能力控制碎片化,同時還能默認(rèn)保持了樣式的對每個新組件的獨立性。所有的東西都挺好的,起碼有那么一段時間是這樣。
修飾符: M 是怎樣破壞 BEM 的
只要你做關(guān)于 CSS 類的命名 & 維護(hù)方面的任何研究,你一定會要看到尼古拉斯.加拉格爾的杰作"關(guān)于 HTML 的語義和前端架構(gòu)"。其中一部分特別吸引我,他稱之為修飾符的 '單類模式' vs '多類模式'。簡單的說,你的 HTML 會有兩個版本,看起來像這樣:
這通過兩個備選的 CSS 模式實現(xiàn):
CSS Code復(fù)制內(nèi)容到剪貼板
/* Single class */
.btn, .btn--large { /* base button styles */ }
.btn--large { /* large button styles */ }
/* Multi class */
.btn { /* base button styles */ }
.btn--large { /* large button styles */ }
這兩個模式的差別在于 btn--large 是否只要它自己就足夠了,還是說它需要依賴類 btn 。單類模式說”可以”,它看起來更簡單而且可以避免有人忘記把 btn 包含進(jìn)來的情況。而且它也不啰嗦,配合 SASS 的 @extend 方法,它對 CSS 來說不像一個負(fù)擔(dān),只不過它有一個致命傷。
上下文重寫
我們假設(shè)你的所有按鈕都有背景色,除了你頂部導(dǎo)航欄那些沒有。在多類模式下,所有的按鈕,大的小的,圓的方的,等等之類,都會包含類 btn,所以你可以這樣寫:
CSS Code復(fù)制內(nèi)容到剪貼板
header > nav > .btn { background: none; }
而在單類模式中,我們不知道哪種按鈕會被重寫,所以你只好這樣:
CSS Code復(fù)制內(nèi)容到剪貼板
header > nav { .btn, .btn--large, .btn--rounded { background: none; }}
很顯然,這不理想 - 追加一個按鈕變體也就意味著要檢查所有地方的按鈕樣式重寫以及添加一個新類。用屬性前綴選擇器 ^=,可以檢查你的屬性是否以特殊字符串開頭,比如:
CSS Code復(fù)制內(nèi)容到剪貼板
[class^='btn'] { /* base button styles */ }
.btn--large { /* large button styles */ }
header > nav > [class^='btn'] { /* Overrides for all buttons */ }
這實現(xiàn)了單類模式下的簡單的上下文重寫,不過它還是太弱了,不是一個可以托付的選擇。最致命的是,如果另一個類在 btn--large 出現(xiàn),而且前綴選擇器還沒匹配到它,那么之后的所有的都完蛋了。而且,它還沒有顯式的方法來指定多個變種,比如說 btn--large--rounded。
我很欣賞這種創(chuàng)造性的方式,不過還是死路一條。好吧,到這里我特么操蛋了,吐,直到忽然某天我靈光一閃。
為什么要用類?
不要在意我那么直接這種小問題,不過給我個理由先,為什么類是我們放樣式信息的唯一位置?HTML生存守則如是說:
3.2.5.7 類屬性
屬性,如果要指定,就必須有一個用來標(biāo)記該元素屬于不同類的值,該值用一組空格分隔符來表示。
而開發(fā)者在類屬性中怎樣使用該標(biāo)記是沒有任何限制的,但是鼓勵開發(fā)者使用描述該內(nèi)容的屬性性質(zhì)的表達(dá),而不是描述該內(nèi)容所期待呈現(xiàn)何種結(jié)果的表達(dá)。
所以對吧,我們用類來描述"內(nèi)容的屬性性質(zhì)"是很有道理的,但是好像我們對類需求過度了吧。一個屬性就包括了所有的東西,從巨大的 BEM-風(fēng)格 命名,比如說 primary-nav__sub-nav--current 到像 u-textTruncate 或者 left 或者 clearfix,到 JavaScript 用的比如說 js-whatevs,然后我們花了巨多時間來解決命名沖突的問題,然后還希望他們有很好的可讀性。
通過約定 & 習(xí)慣這是可控的,而且還有像文章前面說到的哈利的那種技術(shù)也挺有用的,不過,有一個事實是,我們所有的操作都是基于一個全局命名空間(global namespace)的,不管有多少規(guī)約都無法改變的事實。這讓我們下面出場的 AM 就有那么一點不同了。
在我們正式開始討論它之前,我們來復(fù)習(xí)一下 CSS 一個鮮為人知的特點。
歡迎 ~= 登場,神奇的選擇器
從 IE7 開始,瀏覽器開始支持一種超厲害的 CSS 規(guī)則,叫做空格分隔屬性選擇器(space-separated attribute selector)。它可以匹配任何屬性值,通過空格分隔,就像它們是類一樣。下面兩行的 CSS 是等價的:
CSS Code復(fù)制內(nèi)容到剪貼板
.dat-class { /* dem styles */ };
[class~='dat-class'] { /* dem styles */ };
和
屬性模塊(Attribute Modules)
屬性模塊,或者叫 AM,它的核心是如何為你的樣式定義命名空間。讓我們從一個簡單的例子開始,一個網(wǎng)格,首先用類的方式描述:
CSS Code復(fù)制內(nèi)容到剪貼板
.row { /* max-width, clearfixes */ }
.column-1 { /* 1/12th width, floated */ }
.column-2 { /* 1/6th width, floated */ }
.column-3 { /* 1/4th width, floated */ }
.column-4 { /* 1/3rd width, floated */ }
.column-5 { /* 5/12th width, floated */ }
/* etc */
.column-12 { /* 100% width, floated */ }
好了,然后我們用屬性模塊方式來做。我們有兩個模塊,行(rows) 和 列(columns) 。行,現(xiàn)在還沒有變化,列有 12 列。
CSS Code復(fù)制內(nèi)容到剪貼板
[am-Row] { /* max-width, clearfixes */ }
[am-Column~="1"] { /* 1/12th width, floated */ }
[am-Column~="2"] { /* 1/6th width, floated */ }
[am-Column~="3"] { /* 1/4th width, floated */ }
[am-Column~="4"] { /* 1/3rd width, floated */ }
[am-Column~="5"] { /* 5/12th width, floated */ }
/* etc */
[am-Column~="12"] { /* 100% width, floated */ }
首先你肯定會注意到了它們的 am前綴(am-prefix)。這是 AM 核心的一部分,它確保了屬性模塊不會和現(xiàn)有屬性沖突。你也可以用任意你喜歡的 ‐ 我試過用 ui- ,css- 還有其它一些,不過這個例子里面我們約定用 am-。如果 HTML 校驗對你的或者你項目來說很重要,那你就選個 data-,意思也是一樣的。
第二個你會注意到應(yīng)該就是那些值了,什么 "1","4" 還是 "12" 的,看起來非常糟糕 的類名 ‐ 它們太普通所以有太高的沖突幾率了。不過因為我們已經(jīng)定義了我們的命名空間,它只在我們規(guī)定的地方起作用,所以我們可以隨便用那些我么你覺得最簡明最有意義的字符。
靈活的屬性
到目前為止,差別相當(dāng)細(xì)微。不過因為每個模塊都有它自己的命名空間,讓我們拿我們的值做個不一樣的嘗試:
CSS Code復(fù)制內(nèi)容到剪貼板
[am-Row] { /* max-width, clearfixes */ }
[am-Column] { /* 100% width, floated */ }
[am-Column~="1/12"] { /* 1/12th width */ }
[am-Column~="1/6"] { /* 1/6th width */ }
[am-Column~="1/4"] { /* 1/4th width */ }
[am-Column~="1/3"] { /* 1/3rd width */ }
[am-Column~="5/12"] { /* 5/12ths width */ }
/* etc */
現(xiàn)在我們可以用命名來讓我們的作用域看起來更有意義了 ‐ 一個寬是 1/3 標(biāo)記讓我們立刻能想起我們需要有 4 列,因為我們用的是一個 12-列 的網(wǎng)格。我們還為所有的列定義了一個默認(rèn)樣式 ‐ 也就是屬性 column ,沒有值的列將會被視為全寬的列。此外,我們還可以把一些重復(fù)的邏輯 (事實上列是左對齊的)移到了這個屬性規(guī)則里面。
格式化所有的屬性和值
這是這種方法的核心優(yōu)點之一。存在一個基礎(chǔ)屬性,比如 am-Button,可以并且應(yīng)該定義樣式。這個屬性的每個擴(kuò)展值則應(yīng)該繼承或者重寫這個基礎(chǔ)樣式。
在上面的網(wǎng)格例子中,我們正是這樣做的:標(biāo)簽 am-Column="1/3" 匹配到了兩個屬性[am-Column] 和 [am-Column~="1/3"],因此結(jié)果就是基礎(chǔ)樣式 + 改變。它給我們提供了一種方式來實現(xiàn) 所有的列都是columns 而不需要用重復(fù)的類或者用 SASS 的 @extend方法。
BEM 的零類(zero-class)模式
回到我們的 BEM 中的單類模式 vs 多類模式上來,AM 給了我們一個零類模式選項。比如說上面的按鈕的例子,標(biāo)記看起來是這樣的:
CSS Code復(fù)制內(nèi)容到剪貼板
[am-Button] { /* base button styles */ }
[am-Button~="large"] { /* large button styles */ }
[am-Button~="rounded"] { /* round button styles */ }
通過創(chuàng)建一個新的屬性模塊 am-Button,我們可以分離出適用于所有按鈕的樣式,比如那些大按鈕,還有那些圓角按鈕。我們不僅可以自由的組合這些變化(比如 am-Button='large rounded'),我們還可以針對這些屬性本身做任何的上下文覆蓋:
現(xiàn)在不管你選什么樣式的按鈕,或者你選多少種樣式的按鈕都不是問題了,關(guān)鍵是,所有的按鈕都會適用選擇器[am-Button],這樣我們就知道我們的覆蓋是有效的了。
到此,相信大家對“如何理解CSS中的屬性模塊”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!