成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

和BEM的戰(zhàn)斗:10個(gè)常見(jiàn)問(wèn)題及如何避免

dongfangyiyu / 2160人閱讀

摘要:我發(fā)現(xiàn)使用這些命名空間會(huì)使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個(gè)常見(jiàn)的問(wèn)題是組件的樣式和位置會(huì)受到父級(jí)容器的影響。

無(wú)論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個(gè)中熟手(作為web術(shù)語(yǔ)來(lái)說(shuō)),你可能已經(jīng)意識(shí)到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視?huì)假設(shè)你對(duì)這種CSS的方法有一個(gè)基礎(chǔ)的理解。

本文旨在對(duì)那些已經(jīng)是BEM的愛(ài)好者或是想要去更有效率的使用它或是非常好奇并且想去學(xué)習(xí)它的人有所幫助。

現(xiàn)在,我對(duì)BEM是一個(gè)優(yōu)雅的命名方式已經(jīng)不報(bào)有任何幻想。它完全不是。我曾經(jīng)很長(zhǎng)一段時(shí)間放棄接受它的原因之一就是它的語(yǔ)法看起來(lái)非常丑陋。我心中的設(shè)計(jì)因子不希望我優(yōu)雅的html結(jié)構(gòu)被丑陋的雙下劃線(xiàn)和連字符弄得一團(tuán)糟。

而我心中的開(kāi)發(fā)者因子讓我務(wù)實(shí)地看待它。最終,這種用來(lái)構(gòu)建用戶(hù)界面并且有邏輯性的、模塊化的方式戰(zhàn)勝了我右半邊大腦的抱怨:“但是它不夠漂亮!”我當(dāng)然不會(huì)建議你在像起居室這樣小的范圍內(nèi)使用這種方式,但是當(dāng)你需要一件救生衣(就像你遨游在CSS的大海中),我會(huì)選擇實(shí)用而不是形式。話(huà)題拓展的差不多了,以下是10種我已經(jīng)遇到過(guò)的困境和一些如何解決它們的技巧。

1. 如何使用子代甚至更深層次的選擇器?

首先來(lái)解釋這個(gè)問(wèn)題,當(dāng)你需要選擇一個(gè)嵌套超過(guò)兩層的元素,你就會(huì)需要用到子孫選擇器。這些選擇器簡(jiǎn)直就是我的夢(mèng)魘,而且我很確定他們的濫用是人們對(duì)BEM產(chǎn)生厭惡的原因之一,看下面這個(gè)例子:

Title text here

description

Lorem ipsum dolor sit amet, consectetur

Adipiscing elit. Pellentesque amet

就像你想的那樣,以這種方式命名會(huì)很快就會(huì)脫離控制,并且一個(gè)組件嵌套的越深,越丑陋也越不可讀的類(lèi)名就會(huì)出現(xiàn)。我已經(jīng)使用了一個(gè)短塊名稱(chēng)c-card和短元素名,比如:body,text,link,但是你可以想象當(dāng)塊和元素的初始部分被命名為c-drop-down-menu會(huì)有多么失控。

我認(rèn)為雙下劃線(xiàn)在選擇器名稱(chēng)中只應(yīng)該出現(xiàn)一次。BEM代表的是Block__Element--Modifier,而不是Block__Element__Element--Modifier。所以,避免多個(gè)元素級(jí)的命名。如果存在多級(jí)嵌套,你可能就需要重新審查一下你的組件結(jié)構(gòu)。

BEM命名和DOM沒(méi)有很?chē)?yán)格的聯(lián)系,所以無(wú)論子元素的嵌套程度有多深都沒(méi)有關(guān)系。命名約定只是用來(lái)幫助你識(shí)別子元素和頂層組件塊的關(guān)系,在這里就是c-card。

這是我對(duì)相同card組件的處理:

Title text here

description

Lorem ipsum dolor sit amet, consectetur

Adipiscing elit. Pellentesque amet

這意味著所有的子元素都僅僅會(huì)被card塊影響。所以,我們可以將文本和圖片移動(dòng)到c-card__header,甚至在不破壞語(yǔ)義結(jié)構(gòu)的情況下添加一個(gè)c-card__footer元素。

2. 我應(yīng)該使用命名空間嗎?

現(xiàn)在,你可能已經(jīng)注意到我的代碼示例中使用了c-。這代表“組件”和形成了我命名BEM類(lèi)名的規(guī)范。這個(gè)想法來(lái)自于致力于提升代碼可讀性的Harry Robert"snamespacing technique

這是我采用的規(guī)范,很多前綴會(huì)貫穿這篇文章的代碼示例。

TYPE PREFIX EXAMPLES
Component c- c-card c-checklist
Layout module l- l-grid l-container
Helpers h- h-show h-hide
States is- has- is-visible has-loaded
JavaScript hooks js- js-tab-switcher

我發(fā)現(xiàn)使用這些命名空間會(huì)使我的代碼非常具有可讀性。即使我不能強(qiáng)求你使用BEM,這也絕對(duì)是一個(gè)值得你使用的關(guān)鍵點(diǎn)。

你可以采用很多其它的命名空間,像qa-可以用作質(zhì)量保證測(cè)試,ss-用作服務(wù)器端的鉤子,等等。但是上面的列表是一個(gè)好的開(kāi)始,當(dāng)你覺(jué)得這項(xiàng)技術(shù)還不錯(cuò),你可以把它介紹給其他人。

在下個(gè)問(wèn)題中,會(huì)有一個(gè)比較實(shí)用的關(guān)于樣式命名空間的示例。

3. 我該如何命名包裹容器?

一些組建需要一個(gè)掌控子元素布局的容器。在這種情況下,我通常會(huì)嘗試把布局抽象到一個(gè)布局模塊中,比如l-grid,并且將每一個(gè)組件作為l-grid__item的內(nèi)容插入。
在我們card的示例中,如果我們想要去生成擁有四個(gè)c-card的列表,我會(huì)使用下面的html結(jié)構(gòu):

  • […]
    […]
  • […]
    […]
  • […]
    […]
  • […]
    […]

你現(xiàn)在應(yīng)該理解布局模塊和組件的命名空間是如何一起工作的。

不要害怕使用一些額外的標(biāo)記會(huì)非常令人頭痛。沒(méi)有人會(huì)拍拍你的背然后告訴你去把

標(biāo)簽移除掉的。

在一些情景下,布局模塊是不可能的完全滿(mǎn)足要求的。比如說(shuō)你的網(wǎng)格沒(méi)有能給你想要的結(jié)果,或者你只是想要去語(yǔ)義化的命名一個(gè)父元素,你應(yīng)該怎么做?在不同的場(chǎng)景我傾向去選擇contaniner或者list。還是我們card的例子,我可能會(huì)用

[…]
?or?
    […]
或者是
    […]
,這取決于使用的條件。關(guān)鍵是要和你的命名約定保持一致。

4. 跨組件的組建?

我們面臨的另一個(gè)常見(jiàn)的問(wèn)題是組件的樣式和位置會(huì)受到父級(jí)容器的影響。就這個(gè)問(wèn)題Simurai有很多詳細(xì)的解決辦法。我這里說(shuō)一個(gè)拓展性最好的方式。

假設(shè)我們想要在之前的示例的card__body中加入一個(gè)c-button。這個(gè)按鈕本身已經(jīng)是一個(gè)組件并且結(jié)構(gòu)如下:

`` 

如果和常規(guī)的按鈕組件沒(méi)有樣式差別,那么就沒(méi)有問(wèn)題。我們只要像下面這樣直接使用:

Title text here

Lorem ipsum dolor sit amet, consectetur

Adipiscing elit. Pellentesque.

舉個(gè)例子,如果我們想要讓按鈕變小一點(diǎn)并且完全是圓角,而這些樣式只是c-card組件的一部分。也就是說(shuō),當(dāng)它有一些微小的不同時(shí)我們應(yīng)該怎么辦?

之前我說(shuō)過(guò),我找到一個(gè)最好用的跨組件類(lèi)名的解決方式。

Title text here

Lorem ipsum dolor sit amet, consectetur

Adipiscing elit. Pellentesque.

這就是BEM官網(wǎng)上著名的“mix”。但是,參考了一些從Esteban Lussich的評(píng)價(jià)之后,我改變了對(duì)這種方式的看法。

在上面的例子中,c-card__c-button類(lèi)嘗試去改變一個(gè)或多個(gè)c-button中存在的屬性,但是成功應(yīng)用這些樣式取決于他們的源順序(或者特殊的指定)。c-card__c-button類(lèi)只會(huì)當(dāng)它在源代碼里聲明在c-button類(lèi)之后才會(huì)生效。在你構(gòu)建更多跨組件的組件時(shí)會(huì)很快失控。(當(dāng)然,使用!important也是一種選擇,但是我不建議你這樣做)

一個(gè)真正模塊化的UI元素的父元素應(yīng)該是完全不可知的-無(wú)論你在何處使用它,效果都應(yīng)該是一致的。像“mix”方式那樣為另一個(gè)組件添加具有特定樣式的類(lèi)名,違反了組件驅(qū)動(dòng)設(shè)計(jì)的開(kāi)/關(guān)原則,即樣式在各模塊之間不應(yīng)該有依賴(lài)關(guān)系。

最好的辦法就是在這些微小的樣式差別中使用同一個(gè)類(lèi),因?yàn)槟銜?huì)發(fā)現(xiàn)隨著項(xiàng)目的增長(zhǎng)你會(huì)在別的地方對(duì)它進(jìn)行復(fù)用。

``

即使你不會(huì)再使用這些類(lèi),為了應(yīng)用這些修改,至少也不能把他們和父容器、特殊屬性和源順序耦合在一起。

當(dāng)然,另一個(gè)選擇就是回到你的設(shè)計(jì)師崗位,告訴他們這個(gè)按鈕應(yīng)該和網(wǎng)站上的其他按鈕保持一致,這樣就可以完全避免這個(gè)問(wèn)題。但這是另一碼事了。

5. 修飾器還是新組件?

決定組件的起止是一個(gè)大問(wèn)題。在c-card這個(gè)示例里,你可能之后會(huì)創(chuàng)建另一個(gè)叫c-panel的組件,他們兩個(gè)樣式相仿,只有一些細(xì)微的差別。

但是是什么決定他們應(yīng)該是兩個(gè)組件呢?c-panelc-card這個(gè)塊名,或者僅僅是因?yàn)橐粋€(gè)修飾器在c-card里應(yīng)用了特殊的樣式。

這樣很容易過(guò)度模塊化并且讓一切都變成一個(gè)組件。我建議從修飾器開(kāi)始,但是如果你發(fā)現(xiàn)你特定組件的CSS文件正變得很難維護(hù),這時(shí)候就可以停止使用修飾器。當(dāng)你發(fā)現(xiàn)你為了適應(yīng)你新的修飾器而不得不去重置這個(gè)“塊”所有的CSS時(shí),就是需要新組件的好時(shí)機(jī)-起碼對(duì)我來(lái)說(shuō)是這樣的。

如果你和其它開(kāi)發(fā)者或者設(shè)計(jì)師協(xié)作,最好的方式是去詢(xún)問(wèn)他們的意見(jiàn)并且花幾分鐘去討論。我知道這樣可能有點(diǎn)逃避責(zé)任,但是對(duì)于一個(gè)大型項(xiàng)目來(lái)說(shuō),理解哪些模塊是可復(fù)用的并且在組件的構(gòu)成上達(dá)成一致是至關(guān)重要的。

6. 如何處理狀態(tài)?

這是一個(gè)常見(jiàn)的問(wèn)題,特別是當(dāng)你給一個(gè)活躍狀態(tài)的組件編寫(xiě)樣式的時(shí)候。讓我們假設(shè)cards有一個(gè)活躍狀態(tài),當(dāng)我們點(diǎn)擊它時(shí),它們會(huì)被添加上一個(gè)好看的邊框。你會(huì)怎么去命名這個(gè)類(lèi)?

在我看來(lái)你有兩種選擇:獨(dú)立的狀態(tài)鉤或者是一個(gè)在組件級(jí)類(lèi)似BEM方式命名的修飾器。


[…]
[…]

盡管我更傾向于保持一致性的類(lèi)似BEM的命名方式,獨(dú)立類(lèi)名的好處是使用JavaScript來(lái)在任意一個(gè)組件中應(yīng)用一般的狀態(tài)鉤更容易。當(dāng)你不得不使用腳本去應(yīng)用特定的基于修飾器的狀態(tài)類(lèi)時(shí),類(lèi)BEM的方式就很讓人頭疼了。這當(dāng)然是完全可行的,但是意味著你需要為每種可能性去編寫(xiě)更多的JavaScript代碼。

堅(jiān)持使用一系列標(biāo)準(zhǔn)的狀態(tài)鉤是有意義的。Chris Pearece有一個(gè)編譯好的列表,我推薦你去了解一下。

7. 什么時(shí)候可以不在元素上添加類(lèi)?

我可以理解很多人在需要構(gòu)建一個(gè)復(fù)雜UI的時(shí)候面臨的痛苦,特別是他們不習(xí)慣去在每個(gè)標(biāo)簽上添加一個(gè)類(lèi)。

通常,我會(huì)在需要特殊樣式的部分上下文添加類(lèi)名。我會(huì)把p標(biāo)簽級(jí)的舍棄,除非在這個(gè)組件中有特殊的需求。

可以預(yù)見(jiàn),這意味著你的html中會(huì)包括非常多類(lèi)名。最終,你的組件可以獨(dú)立運(yùn)行并且在沒(méi)有副作用的條件下在任何地方使用。

由于CSS的全局特性,在所有部分都添加類(lèi)讓我們可以完全控制我們組件的渲染。最初的心理不適在一整個(gè)模塊化的系統(tǒng)完成后是完全值得的。

8. 如何嵌套組件?

假設(shè)我們想要在c-card組件中展示一個(gè)選項(xiàng)列表,下面這是一個(gè)反面教材:

Title text here

I would like to buy:

這里有很多問(wèn)題。第一個(gè)是我們?cè)诘谝稽c(diǎn)里提到的子孫選擇器。第二點(diǎn)是所有應(yīng)用c-card__checklist__item樣式都被限定使用,不能復(fù)用。

我更傾向于這里需要打破在這個(gè)布局模塊中的列表本身,而是應(yīng)該把選項(xiàng)列表多帶帶抽象成一個(gè)組件,這樣就可以在其它地方獨(dú)立使用它們。這里我們使用l-命名空間。

Title text here

I would like to buy:

這樣你就不用重復(fù)哪些樣式,同時(shí)也意味著我們可以在項(xiàng)目中的其它地方使用l-listc-checkbox??赡苓@意味著更多的標(biāo)記,但是對(duì)于可讀性,封裝性和可復(fù)用性來(lái)說(shuō)代價(jià)可以忽略。你可能已經(jīng)注意到這些是共同的主題!

9. 組件會(huì)不會(huì)最終有無(wú)數(shù)個(gè)類(lèi)名?

有些人認(rèn)為每個(gè)元素有大量類(lèi)名是不好的,--modifiers會(huì)越積越多。就我個(gè)人而言,我不認(rèn)為這是個(gè)問(wèn)題,因?yàn)檫@意味著代碼更具有可讀性,我也能更清楚的知道它是用來(lái)實(shí)現(xiàn)什么的。

舉個(gè)例子,這是一個(gè)具有四個(gè)類(lèi)的按鈕:

`` 

我第一眼看到的時(shí)候覺(jué)得語(yǔ)法不是最簡(jiǎn)潔的,但是非常清晰。

如果這讓你非常頭痛,你可以查看Sergey Zarouski提出的拓展技術(shù),我們可以在樣式表中使用.className [class^="className"][class*=" className"]來(lái)效仿vanilla CSS的拓展功能。如果語(yǔ)法看起來(lái)很眼熟,可能是因?yàn)楹虸comoon處理它的icon選擇器的方式非常類(lèi)似。

使用這種技術(shù),你的代碼可能會(huì)看起來(lái)像下面這樣:

`` 

我不知道使用class^=class*=選擇器是否比獨(dú)立的類(lèi)名表現(xiàn)更好,但是理論上來(lái)說(shuō)這是一個(gè)不錯(cuò)的選擇。我喜歡使用復(fù)合類(lèi)名,但我覺(jué)得這值得那些傾向于尋找替代品的人注意一下。

10. 我們可以響應(yīng)式的改變組件的樣式嗎?

這是Arie Thulank給我提出的問(wèn)題,我花費(fèi)了很多心思去想出一個(gè)100%具體具體的解決辦法。

一個(gè)例子就是下拉菜單在給定斷點(diǎn)處轉(zhuǎn)換為選項(xiàng)卡或者是隱式導(dǎo)航在給定斷點(diǎn)處轉(zhuǎn)換為菜單欄。本質(zhì)上是一個(gè)組件在媒體查詢(xún)的控制下有兩種不同的樣式表現(xiàn)。

我傾向于給這兩個(gè)例子去構(gòu)建一個(gè)c-navigation組件,因?yàn)樗麄冊(cè)趦蓚€(gè)斷點(diǎn)處的行為本質(zhì)是相同的。但這讓我陷入沉思,如果是圖片列表在大屏幕上轉(zhuǎn)化為輪播圖呢?這對(duì)我來(lái)說(shuō)是一個(gè)邊緣情況,只要它有可行的文檔及評(píng)論,我認(rèn)為這是合理的??墒鞘褂妹鞔_的命名(像c-image-list-to-carousel)來(lái)為這種類(lèi)型的UI構(gòu)造一次性的獨(dú)立組件。

Harry Roberts寫(xiě)過(guò)一篇響應(yīng)式后綴來(lái)解決這個(gè)問(wèn)題。他的做法是為了適應(yīng)更多布局和樣式的變化,而不是整個(gè)組件的變化。但我不明白為什么這項(xiàng)技術(shù)不能被應(yīng)用在這里。所以,你會(huì)發(fā)現(xiàn)作者寫(xiě)的樣式像下面這樣:

`
    `

對(duì)于不同的屏幕尺寸,這些類(lèi)就會(huì)保留各自的媒體查詢(xún)。提示:在CSS中你需要在@前加上來(lái)進(jìn)行轉(zhuǎn)義,像下面這樣:

.c-image-list@small-screen {
    /* styles here */
} 

我沒(méi)有太多構(gòu)造這種組件的示例,但是如果你需要構(gòu)造這種組件,這將是一個(gè)對(duì)開(kāi)發(fā)者非常友好的方式。下一個(gè)加入的人應(yīng)該可以輕松理解你的想法。我不提倡你使用像small-screenlarge-screen這樣的命名,他們只是單純?yōu)榱丝勺x性。

總結(jié)

BEM在我創(chuàng)建一個(gè)模塊化和組件驅(qū)動(dòng)的應(yīng)用時(shí)幫了大忙。我已經(jīng)使用它大概有三年了,上面的這些問(wèn)題是我在探索時(shí)遇到的阻礙。我希望你認(rèn)為這篇文章是有用的。如果你還沒(méi)有想要體驗(yàn)BEM,我非常鼓勵(lì)你去嘗試一下。

本文根據(jù)@David Berner的《Battling BEM (Extended Edition): 10 Common Problems And How To Avoid Them》所譯,整個(gè)譯文帶有我自己的理解與思想,如果譯得不好或有不對(duì)之處還請(qǐng)多多指點(diǎn)。如需轉(zhuǎn)載此譯文,需注明英文出處:https://www.smashingmagazine....

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/111413.html

相關(guān)文章

  • BEM戰(zhàn)斗10個(gè)常見(jiàn)問(wèn)題如何避免

    摘要:我發(fā)現(xiàn)使用這些命名空間會(huì)使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個(gè)常見(jiàn)的問(wèn)題是組件的樣式和位置會(huì)受到父級(jí)容器的影響。 無(wú)論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個(gè)中熟手(作為web術(shù)語(yǔ)來(lái)說(shuō)),你可能已經(jīng)意識(shí)到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視?huì)假設(shè)你對(duì)這種CSS的方法有一個(gè)基礎(chǔ)的理解。 本文旨在對(duì)那...

    mumumu 評(píng)論0 收藏0
  • BEM戰(zhàn)斗10個(gè)常見(jiàn)問(wèn)題如何避免

    摘要:我發(fā)現(xiàn)使用這些命名空間會(huì)使我的代碼非常具有可讀性??缃M件的組建我們面臨的另一個(gè)常見(jiàn)的問(wèn)題是組件的樣式和位置會(huì)受到父級(jí)容器的影響。 無(wú)論你是剛剛發(fā)現(xiàn)BEM或者已經(jīng)是個(gè)中熟手(作為web術(shù)語(yǔ)來(lái)說(shuō)),你可能已經(jīng)意識(shí)到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續(xù)閱讀這篇文章之前去BEM website了解一下它,因?yàn)槲視?huì)假設(shè)你對(duì)這種CSS的方法有一個(gè)基礎(chǔ)的理解。 本文旨在對(duì)那...

    荊兆峰 評(píng)論0 收藏0
  • CSS方法論(一)

    摘要:由于年提出,這基于她在雅虎的工作。但是這很難做到解決的問(wèn)題樣式全局性造成的樣式?jīng)_突問(wèn)題多人協(xié)作的命名問(wèn)題解決層疊問(wèn)題,使的優(yōu)先級(jí)保持相對(duì)扁平的模塊化,使更具有復(fù)用的能力于年由提出,當(dāng)時(shí)他在雅虎工作。 編寫(xiě)CSS會(huì)遇到什么問(wèn)題? 其實(shí)CSS很好寫(xiě),只要知道css語(yǔ)法,你就可以寫(xiě)出來(lái),通過(guò)各種學(xué)習(xí),你也可以做出一個(gè)很美麗的頁(yè)面。對(duì)能熟練編寫(xiě)網(wǎng)頁(yè)的人來(lái)說(shuō),可以很簡(jiǎn)單的將設(shè)計(jì)圖變成網(wǎng)頁(yè)。但是在...

    haoguo 評(píng)論0 收藏0
  • CSS Modules詳解React中實(shí)踐

    摘要:上例中打印的結(jié)果是對(duì)中的名都做了處理,使用對(duì)象來(lái)保存原和混淆后的對(duì)應(yīng)關(guān)系。結(jié)合實(shí)踐在處直接使用中名即可。如因?yàn)橹粫?huì)轉(zhuǎn)變類(lèi)選擇器,所以這里的屬性選擇器不需要添加。 showImg(http://gtms01.alicdn.com/tps/i1/TB15w0HLpXXXXbdaXXXjhvsIVXX-600-364.png); CSS 是前端領(lǐng)域中進(jìn)化最慢的一塊。由于 ES2015/201...

    wemall 評(píng)論0 收藏0
  • CSS命名規(guī)范

    摘要:本篇介紹幾種命名規(guī)范。使用的網(wǎng)站四其他命名規(guī)范等減少對(duì)結(jié)構(gòu)的依賴(lài)增加重復(fù)性的使用幾種命名規(guī)范比較與在命名上相反的點(diǎn)可以放心使用,以為都是在模塊內(nèi)但不推薦當(dāng)前我們的網(wǎng)站略有思想更概括,中的,相當(dāng)于的,相當(dāng)于的,相當(dāng)于的中文 本篇介紹幾種CSS命名規(guī)范。 (規(guī)范詳細(xì)請(qǐng)參考底部References) 一、NEC (nice easy css) 網(wǎng)易前端CSS開(kāi)源項(xiàng)目 1.1 樣式分類(lèi) 重...

    includecmath 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<