最好的CSS方式——OOCSS+ Sass

Bench 12年前發布 | 1K 次閱讀 CCleaner Flatic

面向對象的CSS很不錯,但是讓非語義化的詞標識你的類是很不明智的。這些類散布在你的HTML里面等著去做調整,會變得很沒意思。但是如果你把OOCSS和Sass結合就讓未經渲染的模塊化CSS和難以維護的HTML變得兩全其美了。

OOCSS導致HTML難以維護

首先是簡單的聲明,其次是一大把可能嚇壞你的非語義化的詞語。這里,實際上我不關心它們被非語義化,我關心的是它們可維護的意義。非語義化的類不需要描敘成那些可能會變成的組件名。

用單純的CSS建模的唯一方式是定義非語義化的類,然后你把這些類應用到HTML元素中。這就是接觸模型的OOCSS方式。但是,問題來了:

1、我不想每次改變樣式都得帶上HTML。從一開始,事情就在一直變。

2、我甚至不想接觸那些我要增加類的那些DOM元素.如果你正在使用Javascript組件渲染頁面元素,那你就不能給組件里面的元素增加類(除非你在做一些無法描敘的事情)。

除了那些不可維護的HTML,OOCSS其他方面還是完全可行的。抽象重復的代碼到模塊的唯一方法是讓CSS在大型項目中變得可維護。那怎樣我們才可以做到百利而無一害呢?

解放OOSass!

OOCSS和Sass的結合給了你超強力量。Sass上的@extent指令讓你從另外的選擇器上繼承樣式而不需要復制所有的代碼,像一個代碼塊(@mixin)。如果你內嵌他們或和內嵌選擇器一起使用他們,即便那些讓人感覺親切的@extent調用也能導致代碼臃腫。

幸運的是Sass3.2增加了一個叫占位符(Placeholder)的新特性。占位符是那種除非他們被擴展否則什么也不輸出的選擇器。下面是個占位符的例子:
%separator
    border-top: 1px solid black

hr @extend %separator

.separator @extend %separator</pre> 它會生成下面這樣的CSS:

hr,
.separator {
    border-top: 1px solid black
}
占位符不會導致像混合類型或@extent調用有的那種代碼臃腫的問題。這使得占位符完美適用在那些非語義化CSS模塊。我叫這些模塊為“模式”。他們是那種小段的樣式,可以通過你的樣式進行混合搭配。

真實樣例展示

采用OOCSS黃金產物作為例子: .media模塊。你可能想應用.media模式到你組件的一個分支: .status 、.profile等等。

情況就是這樣的,你不想再HTML里面重復.media類,但你想把它的樣式復制到.status和.profile類上。使用占位符很容易就可以實現。 下面是我們給出的%media模式。
%media
    overflow: hidden
    &:first-child
        float: left
    &:last-child
        overflow: hidden
現在你不需要復制media類的代碼,你只要擴展 %media 模式到你任何想要使用的地方就可以了。
.status
    @extend %media
    // Status-specific styles here...

.profile @extend %media // Profile-specific styles here...</pre> 這意味著在HTML里面你只需要增加一些語義化的類:.status和.profile——這些你不用在意類型因為你只在<article>元素中用到它了。
這東西很靈活。如果你要改變狀態顯示方式讓.media模式不再應用只要移除@extend調用就可以了,而不用刪除.media類。
眼尖的話應該注意到了 這里我使用了稍稍修改過的.media模式版本。這是因為當使用Javascript組件時不能使用DOM...

OOSass讓給Javascript組件定義樣式變得容易。

OOCSS的最大問題是它已經假設你對DOM和增加的類完全控制。那是不可能的。當你渲染Javascript組件或其他一些操作時,你只可能拿到組件最頂端的元素。

如果你要將.user-dropdown類應用到下拉視圖上,你可以擴展一個.media類到.user-dropdown類上。但是要增加類到下拉菜單的按鈕上或它的任一餐單項上是不可能的,因為你不能控制組件里面的DOM元素。

不過有了Sass占位符,這不是問題:
.dropdown
    // Normal styles for every dropdown...

.user-dropdown // Extra styles for user-specific dropdowns... .menu-item @extend %media</pre> 要是你想用純粹CSS類你就不得不做些粗俗的事情:進入組件里面破壞它們的分裝,或使用一些可怕的基于字符串的類名API。使用Sass模式你很容易就增加了DOM元素而不需要直接控制它。

好了,看了例子吧。

我喜歡讀別人的CSS模式,就好像已經分享了我自己的一些代碼。下面是我在整個Segment.io上使用到得一些模式。

Lip

這是一個蘋果風格的分隔符,在它下面創建了一個在內容上面的lip類(注意我也用了%reversed-lip來控制在向反方向的lip)
%lip
    clear: both
    display: block
    height: 5px
    background: url('/public/images/patterns/lip/lip.png') no-repeat
    background-size: 100% 100%

%reversed-lip @extend %lip background-image: url('/public/images/patterns/lip/reversed-lip.png')</pre>

Valley

這里只是增加兩個lip到元素的頂部和底部,讓它感覺像是嵌入進去的。
%valley
    position: relative
    overflow: hidden

&::before,
&::after
    content: ''
    position: absolute
    left: 0
    right: 0
&::before
    @extend %lip
    top: 0
&::after
    @extend %reversed-lip
    bottom: 0</pre> <h4> Plane </h4>

一個非常簡單的圓角盒子。這是在Segment.io上所有色塊的基礎。

%plane
    box-shadow: 0 2px 5px rgba($black, .1)
    border-radius: $border-radius-medium

%white-plane @extend %plane background-color: $white

%off-white-plane @extend %plane background-color: $off-white

...</pre>

Seam

你知道那些人們通過把黑線和白線放在一起做成半透明的邊框不?我叫它seam。
%seam
    clear: both
    display: block
    height: 0px
    border-top: 1px solid rgba($black, .12)
    border-bottom: 1px solid rgba($white, .15)

Well

和valley差不多,它只是頁面的一塊洼地,對于像<code>這樣的例子。(它和這個博客的代碼例子很相似。)
%well
    box-shadow: inset 0 1px 5px rgba($black, .14)
    border-radius: $border-radius-medium

%off-white-well @extend %well background-color: $off-white

%light-gray-well @extend %well background-color: $light-gray

...</pre>

準備開始吧

希望上面這些能給你一些啟示——什么事模式能做的及怎樣在你的CSS組件中使用他們。它們無處不在。

它們應該只做一件事情并把它們做好。Harry Roberts提到應該給它們一個模糊的非語義化的名稱。這樣促使你把它們抽象出來,以便在任何地方使用。你還可以每次都在最前面建一些模式,就像我在valley的例子中做的一樣。

如果你自己也擁有一些類似的模式那就更好了。


 本文由用戶 Bench 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!