前端css、less、sass編碼規范---BEM

前言

為什么要使用css的編碼規范?

  • 編輯一個 class 是否安全,會不會干擾其他 CSS。這是最重要的。
  • 想知道一個 class 放在大工程中的什么地方,以防止大腦過載。
  • class 盡可能少,因為看到一長串的 class 時會很頭暈。
  • 如果一個組件是否使用了 JavaScript,當改變了它的 CSS,不會意外地破壞任何組件。

BEM命名空間 符合諸上所有的標準

什么是 BEM

BEM 是一個規范的總稱縮寫,它代表 blockelementmodifier。當第一次接觸它時,它看起來是那么的難看。但是它很規范。

.block { /* styles */ } 
.block__element { /* styles */ } 
.block--modifier { /* styles */ }

一個塊就是一個組件。這有點抽象,所以讓我們用示例來學習。

假設您正在建立一個聯系表單。在這種情況下,這個表單可以是一個塊。在 BEM 中,塊被寫為像 class 的名字一樣,如下所示:

.form { /* styles */ }

BEM 使用 .form 而不是 <form> 元素的原因是因為 類允許無限的可重用性,而即使是最基本的元素也可能改變樣式。

按鈕很好地闡釋了可以包含不同樣式的塊。如果將 <button> 元素的背景顏色設置為紅色,則所有 <buttons> 都將被強制繼承紅色背景。接下來,你必須通過覆蓋你的 <button> 元素來修復代碼(并且可能會在修復中“傷及無辜” )。

button { 
    background-color: red; 
} 

.something button { 
    background-color: blue;
}

如果設置了一個 .button 類的按鈕,則可以在任何 <button> 元素上選擇是否使用 .button 類。那么,如果你需要一個不同的背景顏色,你所做的就是改成一個新的 class,比如說 .button--secondary,很舒服吧!

.button { 
    background-color: red; 
}

.button--secondary { 
    background-color: blue;
}

這給我們引入了 BEM 的下一部分 —— 修飾符。

修飾符

修飾符是改變某個塊的外觀的標志。要使用修飾符,可以將 --modifier 添加到塊中。

從上面的按鈕示例繼續,修改的按鈕將被命名為 .button--secondary

在傳統的 BEM 中,當你使用修飾符時,你應該 將塊和修飾符添加 到 HTML 中,以便在新的 .button--secondary 中不重寫 .button 樣式。

<button class="button">Primary button</button>
<button class="button button--secondary">Secondary button</button>

.button { 
    padding: 0.5em 0.75em; 
    background-color: red; 
} 
.button--secondary { 
    background-color: green; 
}

注意為什么沒有必要在 .button--secondary 中重新聲明 padding,因為它已經在 .button 中聲明了。這很棒,因為 BEM 確保你編寫簡潔的 CSS,而不需要付出大量的工作。

但是,我并不喜歡在HTML中再加一個 .button,因為 .button--modifier 已經告訴我,它是一個帶有 --secondary 標志的 .button 。理想情況下,我的 HTML 應該是這樣的:

<button class="button">Primary button</button>
<button class="button--secondary">Secondary button</button>

這更簡潔,不是嗎?

不幸的是,如果 HTML 中沒有 .button,我們必須回到非簡潔的 CSS:

.button { 
    padding: 0.5em 0.75em; 
    background-color: red; 
} 
.button--secondary { 
    padding: 0.5em 0.75em; 
    background-color: green; 
}

呃,這么繁瑣的東西好惡心。 但是有種方法可以編寫簡潔的 CSS,而不需要額外的 class,那就是使用less、sass中的使用 mixin ,下面是sass的實例:

如果使用 Sass 或任何其他預處理器,則 使用mixin來封裝 需要重用的 所有代碼。在我們的按鈕示例中,我們只需要將 padding 寫入 mixin。 在這里,我在塊中調用這個 mixin:

@mixin button {
    padding: 0.5em 0.75em; 
} 
.button { 
    @include button;
    background-color: red;
} 
.button--secondary { 
    @include button;
    background-color: green; 
} 

元素

元素是塊的子節點。為了表明某個東西是一個元素,你需要在塊名后添加 __element。所以,如果你看到一個像那樣的名字,比如 form__row ,你將立即知道 .form 塊中有一個 row 元素。

<form class="form" action=""> 
    <div class="form__row"> 
        <!-- ... --> 
    </div> 
</form>

.form__row { 
    /* styles */ 
}

BEM 元素有兩個優點

  • 你可以讓 CSS 的優先級保持相對扁平。
  • 你能立即知道哪些東西是一個子元素。

為了解釋以上兩點,考慮使用兩個單獨的 class 的替代方法(許多框架這么做的)。你可能會用這樣的東西:

<form class="form" action=""> 
    <div class="row"> 
        <!-- ... --> 
    </div>
</form> 

.form .row { 
    /* styles */ 
}

如果你使用 BEM 元素,則可以使用優先級為 10 而不是 20 的的選擇器來為 .form__row 提供樣式。此外,你可以立即分辨出(不論是在 HTML 還是 CSS 中).form__row.form__row的子節點。

有一件事你需要了解。永遠不應該鏈式命名 BEM 元素。 如果你的 class 最終像這樣 .form__row__input,你做的事情是非常錯誤的。

有兩種方法可以繞過長長的 BEM 鏈式命名。 他們是:

  • 只把子子元素鏈接到有意義的塊
  • 創建新的塊來保存元素

鏈接孫元素到塊

雖然 BEM 建議你將 BEM 元素寫作 .block__element ,但它不會規定你的 HTML 應如何。所以,只要有意義的話,你可以把你的孫元素連在一起。

接下來是一個例子。在下面的代碼中,你將看到 .article__header.article 的子元素。.article__titlearticle 的孫元素(或者說是 .article__header 的子元素,如果你將它們同時表示為 .article 的子元素,就沒有沖突,因為這個表單同時只有他們存在。

<article class="article"> 
    <header class="article__header"> 
        <h1 class="article__title"></h1> 
    </header> 
</article>

雖然這樣有效,你也會遇到無意義的鏈接孫元素的情況。舉個例子:

<section class="comments"> 
    <h2 class="comments__title"></h2> 
    <article class="comments__comment"> 
        <h3 class="comments__comment-title"></h3> 
    </article> 
    <article class="comments__comment"> 
        <h3 class="comments__comment-title"></h3> 
    </article> 
    <!-- ... --> 
</section>

呃?

此時你需要創建新塊來保存孫元素。

創建新的塊來保存孫元素

在上述情況下,你可以輕松地將 .comments__comment 拆為 .comments.comment

<section class="comments"> 
    <h2 class="comments__title"></h2> 
    <article class="comment"> 
        <h3 class="comment-title"></h3> 
    </article> 
    <article class="comment"> 
        <h3 class="comment-title"></h3> 
    </article> 
    <!-- ... --> 
</section>

這更有意義,不是嗎?如果你這樣做,請確保將 .comments.comment塊放在同一個文件中,以方便參考。

接下來,還有一件事,在我的用例中添加為 BEM 添加的 —— 命名空間。

命名空間

  • .l-: 布局(layouts)
  • .o-: 對象(objects)
  • .c-: 組件(components)
  • .js: js的鉤子(JavaScript hooks)
  • .is-|.has-: 狀態類(state classes)
  • .t1|.s1: 排版大小(typography sizes)
  • .u-: 實用類(utility classes)著作權歸作者所有。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,792評論 1 92
  • 基本原則 結構、樣式、行為分離 統一縮進(建議 兩個空格) 文件編碼統一 不帶BOM的UTF-8 一律使用小寫字母...
    KeKeMars閱讀 3,109評論 12 144
  • CSS通用類和“關注點分離” - 眾成翻譯http://www.zcfy.cc/article/css-utili...
    葡萄喃喃囈語閱讀 746評論 0 6
  • 1 我今年二十歲,我只愛過一個人。 這幾日天都是黑壓壓、陰沉沉的,因為臺風的影響,時不時地又來一場暴雨,氣勢洶洶。...
    今夜又棲閱讀 272評論 1 2
  • 一 閨蜜們聚會時,一向開心果的LINDA卻少言寡語。PANO打趣道:“呦,LINDA變...
    以讀攻獨閱讀 774評論 4 13