要罵就罵的爽快---CSS篇

Tech In Pieces發表於2020-12-31

轉自知乎
@Ivony

為什麼CSS那麼難學?

其實有這種感覺並不奇怪,因為你把CSS當作了一門程式設計語言一樣的東西。
而事實上他只不過是一群醉漢拍腦袋胡亂發明出來的語焉不詳的亂碼的拼湊。
近年已經好太多了,早期的程式設計師甚至要通過除錯瞭解瀏覽器會如何處理CSS並試圖用這個玩意兒去控制瀏覽器的處理行為得到自己想要的結果。
這是一種極其高階的程式設計技巧,就像通過你的計算器的一些Bug寫個遊戲出來一樣。
唯一的好訊息是,CSS實現的Bug實在太多了,使得你真的可以用這些Bug來編寫程式。反對所有認為CSS是一種正兒八經的程式語言的說法,CSS事實上是這樣一種程式語言,其中佔絕大多數的組成部分是UB(未定義的行為)。(至少在2.x之前的版本就是這樣的)剛去W3C網站上去看了下,似乎CSS 2.x以前的版本都已經被美化或者刪除了,如果你能找到原始的文件去看一下,你就會知道沒搞懂這玩意兒怎麼會造成各種奇怪的效果,壓根兒不是你的錯。
CSS這玩意兒完全就是搞排版的那群人弄出來的玩意兒,毋庸置疑的是,他們的思維模式和寫程式的完全不一樣。舉個簡單的栗子,作為程式設計師,當我們看到width的時候,我們會本能的詢問,which width?是框的?內容的?實際展現的?設定的?包含填充的?父元素的?而對於CSS的設計者而言,他覺得width is just width,這是很顯然的事情……有個好訊息是,現在終於有程式設計師加入CSS工作組了。他們終於知道程式設計師要的是tell me behavior,而不是width is just width。還有很多人非要槓width的問題,這樣吧,我直截了當的問你:

<table width="100px" cellspacing="0" border="1"><tbody><tr><td>a</td></tr></tbody></table>
  <img width="100px" height="20px" border="1">
  <div style="width: 100px"></div>
  <table style="width: 100px; border: 1px;padding: 5px;" border="1"><tbody><tr><td>a</td></tr></tbody></table>
  <img style="width: 100px; height: 20px; border: 1px;">

你能畫出來這五個元素的正確的寬度嗎?
不問清楚width到底是什麼東西能達到我們想要的效果嗎?
說CSS標準系統規範的,你能畫出來下面這段HTML實際的顯示樣式嗎?

<div style=" border: solid 1px;">
  <span style="font-size: 20px">fptABC</span>
  <span style="font-size: 40px">fptABC</span>
  <span style="font-size: 80px">fptABC</span>
  <img style="height: 50px; width: 50px; border: 1px; padding: 5px; margin: 5px;">
  <span style="height: 50px; width: 50px; border: 1px; padding: 5px; margin: 50px; font-size: 40px;">fptABC</span>
</div>

多麼簡單的程式碼。所以,img的基線在哪裡?span的又在哪裡?margin會不會衝出外框?下一行的元素又怎麼對齊?
你說這是個描述性語言,好啊,你告訴我這樣描述出來的玩意兒唯一的符合標準的行為是什麼?
我們要的是唯一確定的行為,不是TMD什麼TMD描述。

另一個可以體現CSS設計狗血的地方在於預設樣式。我們知道事實上HTML元素都有自己的預設樣式行為,在沒有任何CSS樣式設定的時候,他們就會呈現出這種預設樣式行為。但是,在漫長的時間裡面,CSS壓根兒就沒有覆蓋這些原本就有的預設樣式行為。這就帶來了大量的面向行為程式設計,例如table佈局。並不是程式設計師喜歡用table來佈局,而是table的預設樣式行為(製造一個可以垂直居中的盒子)壓根兒沒有辦法用CSS來表示(直到flexible box的加入)。為了達到這樣的效果,我們不得不搞一個table來控制瀏覽器的行為……
就拿評論中的最常見的垂直居中的問題來說吧,在CSS裡面我們怎麼讓一個塊元素在頁面居中呢?
我們得寫成這樣:

<body style="display: flex; height: 100vh; box-sizing: border-box; margin: 0px; align-items: center; justify-content: center;">
  <div>
  </div>
</body>

這麼多樣式到底是幹啥的?
一個個來解釋:box-sizing: border-box,用於定義後面設定的的高度為邊框盒子高度而不是匪夷所思的內容高度,這幾乎是佈局所必需的。
margin: 0px,因為margin在邊框盒子外面,所以還得把這個幹掉。
height: 100vh,這三個屬性加一起才能真正實現body元素的外框高度與瀏覽器視窗的高度一致。
display: flex,用於把body變成一個用於佈局的彈性盒子
align-items: center,垂直居中
justify-content: center,水平居中

事實上我們用了三個屬性才完成了這一件創舉,讓我們的body的高度與瀏覽器視窗的高度一致,這就是CSS設計者的腦回路。
再用了三個屬性才使得我們的內容在水平和垂直兩個方向都居中。
更別提這裡面的box-sizing、flex和vh單位都是HTML5之後才出現的。說白了,整個flex體系都是微軟和谷歌的程式設計師介入後才真正搞出來的。
在沒有這些東西之前,唯一的方法就是做個table,然後那些大師們還叫囂著,不要用table,用盒子,用盒子……
在沒有flex和grid之前,盒你!@&^&!……

相關文章