摘要:我發現使用這些命名空間會使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。
無論你是剛剛發現BEM或者已經是個中熟手(作為web術語來說),你可能已經意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續閱讀這篇文章之前去BEM website了解一下它,因為我會假設你對這種CSS的方法有一個基礎的理解。
本文旨在對那些已經是BEM的愛好者或是想要去更有效率的使用它或是非常好奇并且想去學習它的人有所幫助。
現在,我對BEM是一個優雅的命名方式已經不報有任何幻想。它完全不是。我曾經很長一段時間放棄接受它的原因之一就是它的語法看起來非常丑陋。我心中的設計因子不希望我優雅的html結構被丑陋的雙下劃線和連字符弄得一團糟。
而我心中的開發者因子讓我務實地看待它。最終,這種用來構建用戶界面并且有邏輯性的、模塊化的方式戰勝了我右半邊大腦的抱怨:“但是它不夠漂亮!”我當然不會建議你在像起居室這樣小的范圍內使用這種方式,但是當你需要一件救生衣(就像你遨游在CSS的大海中),我會選擇實用而不是形式。話題拓展的差不多了,以下是10種我已經遇到過的困境和一些如何解決它們的技巧。
1. 如何使用子代甚至更深層次的選擇器?首先來解釋這個問題,當你需要選擇一個嵌套超過兩層的元素,你就會需要用到子孫選擇器。這些選擇器簡直就是我的夢魘,而且我很確定他們的濫用是人們對BEM產生厭惡的原因之一,看下面這個例子:
Title text here
Lorem ipsum dolor sit amet, consectetur
Adipiscing elit. Pellentesque amet
就像你想的那樣,以這種方式命名會很快就會脫離控制,并且一個組件嵌套的越深,越丑陋也越不可讀的類名就會出現。我已經使用了一個短塊名稱c-card和短元素名,比如:body,text,link,但是你可以想象當塊和元素的初始部分被命名為c-drop-down-menu會有多么失控。
我認為雙下劃線在選擇器名稱中只應該出現一次。BEM代表的是Block__Element--Modifier,而不是Block__Element__Element--Modifier。所以,避免多個元素級的命名。如果存在多級嵌套,你可能就需要重新審查一下你的組件結構。
BEM命名和DOM沒有很嚴格的聯系,所以無論子元素的嵌套程度有多深都沒有關系。命名約定只是用來幫助你識別子元素和頂層組件塊的關系,在這里就是c-card。
這是我對相同card組件的處理:
Title text here
Lorem ipsum dolor sit amet, consectetur
Adipiscing elit. Pellentesque amet
這意味著所有的子元素都僅僅會被card塊影響。所以,我們可以將文本和圖片移動到c-card__header,甚至在不破壞語義結構的情況下添加一個c-card__footer元素。
2. 我應該使用命名空間嗎?現在,你可能已經注意到我的代碼示例中使用了c-。這代表“組件”和形成了我命名BEM類名的規范。這個想法來自于致力于提升代碼可讀性的Harry Robert"snamespacing technique
這是我采用的規范,很多前綴會貫穿這篇文章的代碼示例。
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 |
我發現使用這些命名空間會使我的代碼非常具有可讀性。即使我不能強求你使用BEM,這也絕對是一個值得你使用的關鍵點。
你可以采用很多其它的命名空間,像qa-可以用作質量保證測試,ss-用作服務器端的鉤子,等等。但是上面的列表是一個好的開始,當你覺得這項技術還不錯,你可以把它介紹給其他人。
在下個問題中,會有一個比較實用的關于樣式命名空間的示例。
3. 我該如何命名包裹容器?一些組建需要一個掌控子元素布局的容器。在這種情況下,我通常會嘗試把布局抽象到一個布局模塊中,比如l-grid,并且將每一個組件作為l-grid__item的內容插入。
在我們card的示例中,如果我們想要去生成擁有四個c-card的列表,我會使用下面的html結構:
你現在應該理解布局模塊和組件的命名空間是如何一起工作的。
不要害怕使用一些額外的標記會非常令人頭痛。沒有人會拍拍你的背然后告訴你去把 在一些情景下,布局模塊是不可能的完全滿足要求的。比如說你的網格沒有能給你想要的結果,或者你只是想要去語義化的命名一個父元素,你應該怎么做?在不同的場景我傾向去選擇contaniner或者list。還是我們card的例子,我可能會用 我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。就這個問題Simurai有很多詳細的解決辦法。我這里說一個拓展性最好的方式。 假設我們想要在之前的示例的card__body中加入一個c-button。這個按鈕本身已經是一個組件并且結構如下: 如果和常規的按鈕組件沒有樣式差別,那么就沒有問題。我們只要像下面這樣直接使用: Lorem ipsum dolor sit amet, consectetur Adipiscing elit. Pellentesque. 舉個例子,如果我們想要讓按鈕變小一點并且完全是圓角,而這些樣式只是c-card組件的一部分。也就是說,當它有一些微小的不同時我們應該怎么辦? 之前我說過,我找到一個最好用的跨組件類名的解決方式。 Lorem ipsum dolor sit amet, consectetur Adipiscing elit. Pellentesque. 這就是BEM官網上著名的“mix”。但是,參考了一些從Esteban Lussich的評價之后,我改變了對這種方式的看法。 在上面的例子中,c-card__c-button類嘗試去改變一個或多個c-button中存在的屬性,但是成功應用這些樣式取決于他們的源順序(或者特殊的指定)。c-card__c-button類只會當它在源代碼里聲明在c-button類之后才會生效。在你構建更多跨組件的組件時會很快失控。(當然,使用!important也是一種選擇,但是我不建議你這樣做) 一個真正模塊化的UI元素的父元素應該是完全不可知的-無論你在何處使用它,效果都應該是一致的。像“mix”方式那樣為另一個組件添加具有特定樣式的類名,違反了組件驅動設計的開/關原則,即樣式在各模塊之間不應該有依賴關系。 最好的辦法就是在這些微小的樣式差別中使用同一個類,因為你會發現隨著項目的增長你會在別的地方對它進行復用。 即使你不會再使用這些類,為了應用這些修改,至少也不能把他們和父容器、特殊屬性和源順序耦合在一起。 當然,另一個選擇就是回到你的設計師崗位,告訴他們這個按鈕應該和網站上的其他按鈕保持一致,這樣就可以完全避免這個問題。但這是另一碼事了。 決定組件的起止是一個大問題。在c-card這個示例里,你可能之后會創建另一個叫c-panel的組件,他們兩個樣式相仿,只有一些細微的差別。 但是是什么決定他們應該是兩個組件呢?c-panel和c-card這個塊名,或者僅僅是因為一個修飾器在c-card里應用了特殊的樣式。 這樣很容易過度模塊化并且讓一切都變成一個組件。我建議從修飾器開始,但是如果你發現你特定組件的CSS文件正變得很難維護,這時候就可以停止使用修飾器。當你發現你為了適應你新的修飾器而不得不去重置這個“塊”所有的CSS時,就是需要新組件的好時機-起碼對我來說是這樣的。 如果你和其它開發者或者設計師協作,最好的方式是去詢問他們的意見并且花幾分鐘去討論。我知道這樣可能有點逃避責任,但是對于一個大型項目來說,理解哪些模塊是可復用的并且在組件的構成上達成一致是至關重要的。 這是一個常見的問題,特別是當你給一個活躍狀態的組件編寫樣式的時候。讓我們假設cards有一個活躍狀態,當我們點擊它時,它們會被添加上一個好看的邊框。你會怎么去命名這個類? 在我看來你有兩種選擇:獨立的狀態鉤或者是一個在組件級類似BEM方式命名的修飾器。 盡管我更傾向于保持一致性的類似BEM的命名方式,獨立類名的好處是使用JavaScript來在任意一個組件中應用一般的狀態鉤更容易。當你不得不使用腳本去應用特定的基于修飾器的狀態類時,類BEM的方式就很讓人頭疼了。這當然是完全可行的,但是意味著你需要為每種可能性去編寫更多的JavaScript代碼。 堅持使用一系列標準的狀態鉤是有意義的。Chris Pearece有一個編譯好的列表,我推薦你去了解一下。 我可以理解很多人在需要構建一個復雜UI的時候面臨的痛苦,特別是他們不習慣去在每個標簽上添加一個類。 通常,我會在需要特殊樣式的部分上下文添加類名。我會把p標簽級的舍棄,除非在這個組件中有特殊的需求。 可以預見,這意味著你的html中會包括非常多類名。最終,你的組件可以獨立運行并且在沒有副作用的條件下在任何地方使用。 由于CSS的全局特性,在所有部分都添加類讓我們可以完全控制我們組件的渲染。最初的心理不適在一整個模塊化的系統完成后是完全值得的。 假設我們想要在c-card組件中展示一個選項列表,下面這是一個反面教材: I would like to buy: 這里有很多問題。第一個是我們在第一點里提到的子孫選擇器。第二點是所有應用c-card__checklist__item樣式都被限定使用,不能復用。 我更傾向于這里需要打破在這個布局模塊中的列表本身,而是應該把選項列表多帶帶抽象成一個組件,這樣就可以在其它地方獨立使用它們。這里我們使用l-命名空間。 I would like to buy: 這樣你就不用重復哪些樣式,同時也意味著我們可以在項目中的其它地方使用l-list和c-checkbox。可能這意味著更多的標記,但是對于可讀性,封裝性和可復用性來說代價可以忽略。你可能已經注意到這些是共同的主題! 有些人認為每個元素有大量類名是不好的,--modifiers會越積越多。就我個人而言,我不認為這是個問題,因為這意味著代碼更具有可讀性,我也能更清楚的知道它是用來實現什么的。 舉個例子,這是一個具有四個類的按鈕: 我第一眼看到的時候覺得語法不是最簡潔的,但是非常清晰。 如果這讓你非常頭痛,你可以查看Sergey Zarouski提出的拓展技術,我們可以在樣式表中使用.className [class^="className"]和[class*=" className"]來效仿vanilla CSS的拓展功能。如果語法看起來很眼熟,可能是因為和Icomoon處理它的icon選擇器的方式非常類似。 使用這種技術,你的代碼可能會看起來像下面這樣: 我不知道使用class^=和class*=選擇器是否比獨立的類名表現更好,但是理論上來說這是一個不錯的選擇。我喜歡使用復合類名,但我覺得這值得那些傾向于尋找替代品的人注意一下。 這是Arie Thulank給我提出的問題,我花費了很多心思去想出一個100%具體具體的解決辦法。 一個例子就是下拉菜單在給定斷點處轉換為選項卡或者是隱式導航在給定斷點處轉換為菜單欄。本質上是一個組件在媒體查詢的控制下有兩種不同的樣式表現。 我傾向于給這兩個例子去構建一個c-navigation組件,因為他們在兩個斷點處的行為本質是相同的。但這讓我陷入沉思,如果是圖片列表在大屏幕上轉化為輪播圖呢?這對我來說是一個邊緣情況,只要它有可行的文檔及評論,我認為這是合理的。可是使用明確的命名(像c-image-list-to-carousel)來為這種類型的UI構造一次性的獨立組件。 Harry Roberts寫過一篇響應式后綴來解決這個問題。他的做法是為了適應更多布局和樣式的變化,而不是整個組件的變化。但我不明白為什么這項技術不能被應用在這里。所以,你會發現作者寫的樣式像下面這樣: 對于不同的屏幕尺寸,這些類就會保留各自的媒體查詢。提示:在CSS中你需要在@前加上來進行轉義,像下面這樣: 我沒有太多構造這種組件的示例,但是如果你需要構造這種組件,這將是一個對開發者非常友好的方式。下一個加入的人應該可以輕松理解你的想法。我不提倡你使用像small-screen和large-screen這樣的命名,他們只是單純為了可讀性。 BEM在我創建一個模塊化和組件驅動的應用時幫了大忙。我已經使用它大概有三年了,上面的這些問題是我在探索時遇到的阻礙。我希望你認為這篇文章是有用的。如果你還沒有想要體驗BEM,我非常鼓勵你去嘗試一下。 本文根據@David Berner的《Battling BEM (Extended Edition): 10 Common Problems And How To Avoid Them》所譯,整個譯文帶有我自己的理解與思想,如果譯得不好或有不對之處還請多多指點。如需轉載此譯文,需注明英文出處:https://www.smashingmagazine.... 文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。 轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90845.html 摘要:我發現使用這些命名空間會使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。
無論你是剛剛發現BEM或者已經是個中熟手(作為web術語來說),你可能已經意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續閱讀這篇文章之前去BEM website了解一下它,因為我會假設你對這種CSS的方法有一個基礎的理解。
本文旨在對那... 摘要:我發現使用這些命名空間會使我的代碼非常具有可讀性。跨組件的組建我們面臨的另一個常見的問題是組件的樣式和位置會受到父級容器的影響。
無論你是剛剛發現BEM或者已經是個中熟手(作為web術語來說),你可能已經意識到它是一種有用的方法。如果你還不知道BEM是什么,我建議你在繼續閱讀這篇文章之前去BEM website了解一下它,因為我會假設你對這種CSS的方法有一個基礎的理解。
本文旨在對那... 摘要:上例中打印的結果是對中的名都做了處理,使用對象來保存原和混淆后的對應關系。結合實踐在處直接使用中名即可。如因為只會轉變類選擇器,所以這里的屬性選擇器不需要添加。
showImg(http://gtms01.alicdn.com/tps/i1/TB15w0HLpXXXXbdaXXXjhvsIVXX-600-364.png);
CSS 是前端領域中進化最慢的一塊。由于 ES2015/201... 摘要:本篇介紹幾種命名規范。使用的網站四其他命名規范等減少對結構的依賴增加重復性的使用幾種命名規范比較與在命名上相反的點可以放心使用,以為都是在模塊內但不推薦當前我們的網站略有思想更概括,中的,相當于的,相當于的,相當于的中文
本篇介紹幾種CSS命名規范。 (規范詳細請參考底部References)
一、NEC (nice easy css)
網易前端CSS開源項目
1.1 樣式分類
重...[…]
或者是[…]
,這取決于使用的條件。關鍵是要和你的命名約定保持一致。``
Title text here
Title text here
``
Title text here
Title text here
``
``
`
`
.c-image-list@small-screen {
/* styles here */
}
相關文章
和BEM的戰斗:10個常見問題及如何避免
和BEM的戰斗:10個常見問題及如何避免
CSS Modules詳解及React中實踐
CSS命名規范
發表評論
0條評論
閱讀 1317·2021-10-27 14:14
閱讀 3574·2021-09-29 09:34
閱讀 2477·2019-08-30 15:44
閱讀 1715·2019-08-29 17:13
閱讀 2569·2019-08-29 13:07
閱讀 867·2019-08-26 18:26
閱讀 3342·2019-08-26 13:44
閱讀 3210·2019-08-26 13:37