CSS 中的分離、抽象和層疊
摘要:LESS和Sass(或者類似方案)從三個方面解決了css存在的問題:分離,抽象和層疊。當我在接受他們時,我發現css還有一些其他問題需要解決。在這裡我提出些解決方案。 |
介紹有很多充分的理由說明LESS和Sass的用途。css很難做到可維護性。LESS和Sass(類似工具)使css變成了一個更加易用的語言。 但是,當人們談論到為什麼他們如此強大時,往往都失去了主見。的確,你的樣式檔案更簡潔和易讀了,然而,這裡還有比純粹的節省程式碼量和命名更深層次的東西。 |
|
在這篇文章中,我將從一個開發者和程式語言愛好者的直覺感受到的,儘可能圖文並茂的解釋下為什麼css天生難以維護,並且沒有達到他自身的設計目的;為什麼LESS和Sass使這個糟糕的語言變得更加可用。我也將提出具體的解決方案,這些將使LESS和Sass提高到更高的一個層次。 |
零度分離在以前,人們用HTML tables來設計頁面的樣式,檔案看起來像醬紫: CSS出現時,人們討論了很多關於頁面內容和樣式的分離的問題。CSS基本上幫助你把樣式從HTML檔案中脫離出來。 |
|
樣式仍然與你的樣式檔案定義的樣式結構相關。他們沒有自己的分組,如果你想重複利用一段樣式,那麼你可以複製貼上,或者通過逗號分隔方式公用一段樣式。但是兩種方式都很糟糕! 還有一種更糟糕的解決方式,也是最常見的一種方式,那就是按照命名給定樣式,我們可以看到在很多號稱讓你的html中寫更少樣式資訊的糟糕的“css框架”中,應用的非常多。網格系統(grid)就是個很典型的例子。 |
但是這些問題出現的原因,不在於這些css框架的作者,很多web開發者也都在尋求解決這些問題的方案。歸根到底,這些都是css作者的責任。使用css,的確能做到頁面內容和樣式分離,但是實現起來很費勁。 HTML和CSS的獨立性是不一樣的。HTML可以沒有CSS,但是CSS沒有了HTML,狗屁不是! |
如果你真的想實現頁面內容從樣式分離,你必須把html和css放在同等的基礎上設定,像這樣(譯註:圖裂了): 頁面內容放到html檔案,樣式寫到css檔案中,然後通過第三種語言建立他們之間的關係。 |
LESS的 LESS Elements讓其成為可能。人們在討論LESS時,往往關注的是它減少了樣式的定義和重複性,或者隱藏了依賴於瀏覽器的css特性。但是,這些都不是問題的本質。之前所有的討論都試圖實現通過定義一個獨立於HTML檔案的mixin樣式,然後只需根據定義的名稱繫結到一個或者多個HTML元素。 |
這是LESS讓HTML樣式更加易用的一個方面,除此之外,你可以定義個包含大小和顏色的變數,這也是把樣式繫結到HTML的另外一種方式. |
抽象 如果你對混合類和變數有了進一步的認識,你會發現他們可以任意組合。我可以定義一個混合類,然後在另一個混合類裡面引用它。我也可以用他們組合出第三種樣式,紅色邊框,黃色字型,綠色背景。這類的組合表明我們可以對css做進一步的抽象。 這在單純的HTML+CSS裡面是不可能辦到的。 |
好吧,雖然我說了不可能辦到,但是也不是沒有辦法,只是有點2x罷了。諾,你可以複製貼上嘛,這TM雖然根本不是個解決方案,但是也能得到你想要的樣式。或者你可以像網格框架(blech!)一樣重複使用沒有語義的類名。最後,你可以做個“倒置樣式”(inverted-style):把所有樣式的優先順序看做最高,其他的選擇器都是從屬。這個需要解釋下。
|
層疊 對於層疊問題LESS和SASS提出了一種很好的解決方案,但是有一定的侷限性。層疊是複雜性中最基本的一個問題。對於一個特定元素的特定的屬性,有很多地方的值是需要設定的。然而確定這些所有地方的優先權的規則是很複雜的。 |
一個元素的最終CSS屬性值是由以下因素決定的:
|
內容和樣式的分離聽起來像聖盃一樣響亮! 通過使用巢狀的LESS規則和子選擇器,我們能夠避免大多數的層疊帶來的痛。聯合其他的一些技巧,我們能夠將我們的樣式混合到一塊(或者是混合中巢狀混合),並將這些樣式和通過模仿html結構的巢狀規則繫結到一塊。 這是完美的,最終的解決方案嗎?不一定! |
將來 也有其他一些嘗試解決層疊問題的方法,LESS和Sass被用來作為css的父集,這就意味著你可用的css檔案就自動的成為LESS檔案,同時也意味著你一開始就得用LESS編譯器。 在這種情況下,LESS將會同事擁有所有css沒有解決的問題,我建議在下一步可以嘗試採用css子集並加以實踐,同時,也非常希望聽到大家的意見! |
是的,巢狀規則確實可以處理層疊問題,但是也有其他關於層疊的問題。樣式的混合不能真的幫你解決盒模型,再多的變數和演算法也不能讓兩個DIV的寬度相同。 接下來,我將一個一個的解決這些問題。 |
有的時候,你可能會想用層疊,例如,你想要設定整個文件的字型,所以, 你設定 body{ font-family:'Comic Sans';},0K,間接的利用font-famiy屬性的繼承性便將整個文件的字型搞定了。事實上,如果你想每個標籤都有同樣的屬性,可以這樣寫:* {font-family:'Comic Sans';},其實這和css reset 有異曲同工之妙,都是為樣式設定預設樣式 。
|
常見錯誤 我把他們叫做常見錯誤是因為找不到更好的詞來表達了,但實在是他們存在於CSS中。 盒子模式 盒子模式的引入可以使我們避免犯一些簡單錯誤。 其中一個錯誤是發生在你定義左間距而不是右間距的時候。在這種情況下,右間距該怎麼定義呢?級聯。 |
結論CSS從未完全實現樣式與內容的分離。LESS(和Sass)終於能使這種分離實現。而且,使用LESS,我們可以開始磨圓CSS中尖銳的邊角部份。但是,我們應該去尋找CSS的一個子集並用mixins替換有問題的CSS屬性,而不是將LESS做為CSS的超集使用。該子集可以用一個linter工具強制執行。 這些建議是一個很好的開始,但仍有很長的路要走。 |
後記 最後我想提一個關於CSS層疊的反思,但在上文中沒有找到一個合適的地方,主要因為它不是一個問題而只是個不便。我經常疑惑為什麼在CSS中,元素樣式(定義在HTML標籤的樣式屬性中)的優先順序高於所有其他樣式。同樣,為什麼在HTML(style標籤)中定義的樣式優先於那些通過連線引入的外部樣式?我認為應該是完全相反的才更有意義。 HTML頁面可以為其元素定義預設樣式,這應該是在頁面中指定並用外部樣式表進行覆蓋。
|