標籤:

關於CSS[可能]沒人知道的3件事

譯序:參加完測試的同學可以在本專欄下面討論哦!友情提示下,CSS Core 部分的測試確實沒有答案,不過後面的 CSS Core (practice) 有答案哦!

你了解 CSS 嗎?在六個月前,我提供了一個在線免費 CSS 測試系統。測試結果表明很多一線開發者並沒有如他們所想的那樣了解 CSS。目前有超過 3,000 人參加了該項測試,平均成績只有 55 分。

但是,嘿,平均分本身並沒有什麼意思。我更加關心大家都栽到了哪些問題上。這篇文章中,按照出錯的程度將其中三個問題列出來。我會和你討論每個問題,告訴你哪個答案被選擇的最多,然後解釋正確答案。

可以肯定地說,如果你讀完這篇文章後參加測試,將會有不公平的優勢!

Q1:設置 line-height 的最佳方式

第一個問題對於有文本樣式常規操作經驗的開發者來說應該很簡單:

想要讓站點內文字默認為雙倍行距。下面哪個 line-height 值是最佳實現方式?

  • 200%
  • 2em
  • 2
  • double

對於這4個答案,你可能覺得僅僅憑運氣也會有 25% 的人會答對,但僅僅 31% 的人回答正確!花上一分鐘時間選擇你認為的正確答案,然後繼續。

首先排除,double 只是用來混淆你。 line-height 接受的唯一關鍵字是 normal。我很高興地說,僅僅有 9% 被這個選項蒙蔽。儘管,剩下的三個答案都非常得普遍。

大多數測試者選擇了 2em(39%)。實際上,2em 確實會將它所應用的元素內的文本渲染為雙倍行距;不過 200% ,僅僅有 21% 選擇了這個答案!或者 em 相比百分數更加流行, 又或者人們根本就沒有理解它們。

然而,正確答案是 2。

這是一個很久以前的一個教訓,那時我第一次學習 CSS。確保將 line-height 指定為一個無單位的數值;這樣一來,指定了不同 font-size 的子元素將會繼承這個數值而不是一個固定的高度。

我們假設頁面默認的 font-size 是 12pt ,不過它也會包含了一個 font-size 為 24pt 的頭部。如果你將 body 的 line-height 設置為2em 或者 200%,那樣在文檔中(當然也包括頭部)就會得到一個 24pt 的行高(body 的 font-size 的 2 倍)。因而,頭部就是單倍行距,而不是雙倍!

相反,將 line-height 設置為 2 會告知瀏覽器保持 font-size/line-height 比例,即便文字的尺寸發生變化。body 的行高將是 24pt,而頭部的文字為 24pt,行高也將自動增長為 48pt。

Q2:如何讓元素部分重疊

這個問題有一點棘手。需要一些 CSS 布局常用到的「奇技淫巧」:

僅僅藉助下面的哪個 CSS 屬性,可以實現 HTML 元素部分重疊?

  • z-index
  • margin
  • overflow
  • background

請選擇一個你認為的正確答案?OK,我們深入看一下。

同樣,有一個很容易排除的選項: background。除了 2% 的測試者外都避開了它,知道它控制背景顏色和圖像。

很不幸,很多測試者直接選擇了 z-index。幾乎有 46% 栽倒在這個選項上。我猜測是因為他們沒有真正地理解 z-index的工作原理。實際上,自身設置 z-index 屬性根本無濟於事;你還需要設置元素的 position 屬性讓 z-index 起作用。簡而言之, z-index 控制了部分重疊元素間的堆放順序,不過前提是它們要重疊。MDN 上有一篇非常棒的文章叫做《理解 CSS z-index》,非常值得仔細閱讀。

如果你曾用到過,overflow 同樣也很容易排除。它用來在一個固定尺寸的盒子內控制內部元素的行為:是否被遮蓋,是否在盒子邊框外部展示,等等。而且,這會需要一些其他 CSS 屬性所控制的盒子尺寸;僅僅通過它是不會導致部分遮蓋的。然而,22% 的測試者認為它可以。

剩下的就是 margin,也就是正確答案。僅僅 30% 的測試者選擇了它。你可能好奇究竟一個屬性如何做到元素間的相互遮蓋。如果你具備一些 CSS 布局的經驗,答案應該很明顯:負值 margin 讓它們相互遮蓋。

為了演示這個,我創建了一個僅有兩個 div 元素的頁面。將第二個 div 的 margin-top 值設置成負值,比如 -100px。砰!現在第二個 div 覆蓋了第一個 div 100 像素。

實際上,你幾乎不會有意地這樣覆蓋一個區塊,不過負值 margin 在處理外層空間小於 HTML 元素大小的情況時出奇地好用。

對 web 設計歷史愛好者來講,在 2005 年負值 margin 實現的部分覆蓋元素使得三列頁面布局成為可能,比如所謂的One True Layout(以及後來的聖杯布局)。

Q3:偽元素 VS 偽類

最後一個問題有一點卑劣,我承認。不過只有 23% 的測試者回答正確(比碰運氣還糟糕!)。毫無疑問,它挖出了一個疑點。

下面哪個效果可以通過偽元素很好地實現?

  • 當用戶將滑鼠懸停在超鏈接上時,為其添加一個投影;

  • 當複選框選中時,在其對應的 label 上顯示一種不同的顏色;
  • 為表格的偶數行和奇數行添加不同的背景色;
  • 在彈性布局中,將段落的第一行加粗顯示。

其中三個效果需要藉助偽類實現;僅僅有一個需要偽元素。你能區分出不同嗎?

偽類是一個真實 HTML 元素上的一個特殊的狀態。可以認為是瀏覽器在特定條件下將一個虛擬的類自動應用於某個元素。

偽元素是 HTML 文檔的一部分,儘管它不是真實的 HTML 元素,但是 CSS 允許你為它設置樣式。就像是虛擬的 HTML 元素——儘管它沒有真實的 HTML 標籤,但你仍可以為其添加樣式。

先記住這點,我們再來看看下面的選項:

當用戶將滑鼠懸停在超鏈接上時,為其添加一個投影

超鏈接是一個真是的 HTML 元素。僅僅在特殊情況下(滑鼠懸停)為其應用樣式,也就是說我們需要使用偽類。該情況下你應該使用 :hover 偽類。

22% 的測試者誤認為這是偽元素。

當複選框選中時,在其對應的 label 上顯示一種不同的顏色

一樣不對, label 是一個真實的 HTML 元素,不是虛擬的。當複選框被選中時,瀏覽器會將 :checked 偽類應用於它。然後,你就能夠在選擇器中使用它為複選框添加樣式,甚至和它相鄰的 label 元素(比如:使用相鄰元素選擇器 +)。

20% 的測試者認為這是一個偽元素。

為表格的偶數行和奇數行添加不同的背景色

這著實愚弄了很多人,不過重申一遍我們討論的是將樣式應用於真實的 HTML 元素(在本例中是 tr 元素)。在各自父元素包含的子元素中的偶數或者奇數行的 tr 只是另外一種符合偽類的情景。

在這個示例中,對於偶數行偽類是 :nth-child(even)(或者 :nth-child(2n)),對於奇數行則是 :nth-child(odd) (或者 :nth-child(2n+1))。

我猜測它僅僅因為 :nth-child 和偽元素聽起來都和真實的 CSS 特性很相似,但是 36% 的測試者將它選擇成偽元素。

在彈性布局中,將段落的第一行加粗顯示

很明顯,這是正確答案。現在,但願我們的討論足夠清晰。在彈性布局中,你無法看到頁面中的 HTML 代碼只能假想「裡面僅僅包含段落文本的第一行」。瀏覽器會根據段落的寬度進行換行,這在彈性布局中是你無法控制的。

:first-line 是允許你將樣式應用於文本塊第一行的偽元素,無論第一行是在何處換到第二行。

如果你正在想「OK,確實講得通,但是拜託——沒一個人知道偽元素和偽類之間有什麼區別」,確實 W3C 也同意你的觀點。CSS3 選擇器規範中,在區分二者上做了一次嘗試,改變了語法——偽元素選擇器使用兩個冒號(::first-line),而偽類依舊使用一個(:hover)。當然,為了向後兼容,瀏覽器必須支持這兩個版本。

是滴,如我所說:卑劣。不過,如果你和我一樣是一個 CSS 駭客,我確信你了解偽元素和偽類的區別。

你做的怎麼樣?

這就是測試中三個棘手的問題。如果你僅僅對一個有信心,還可以。兩個?做得不錯。答對了三個,我非常樂意聽到!現在,我已經公布了這些問題的答案,同樣也可以用這些觀點解決更棘手的 CSS 問題。請在評論中留言。

如果你享受這些問題,或許你可以嘗試一下測試的其他部分。請放心,其他的問題比這些要簡單許多許多!

Kevin Yank 於 1995 年接觸 Web 開發,是一位備受尊重的技術類作者。Kev 更是一位知名作家、演說家和 JavaScript 專家。他熱衷於讓每個人都能輕易地理解 Web 技術。是的,包括你!

原文:3 Things (Almost) No One Knows About CSS

外刊君推薦閱讀:

CSS Font Sizing

Responsive Design with Viewport Control

關注微博:前端外刊評論


推薦閱讀:

content"width=640,user-scalable=no" 然後再進行固定尺寸的px設計?
30 分鐘學會 Flex 布局
中國有沒有做的比較好的響應式設計的門戶網站?
css3 滑鼠:hover效果會平滑過渡,但滑鼠離開,效果消失的太生硬,能不能和:hover一樣平滑過渡?
CSS3 的按鈕怎麼快速實現樣式?

TAG:CSS3 |