參考文獻:www.w3cplus.com/css/aspect-…
你肯定已經知道,對於一個 img 元素而言,你可以單獨地修改它的 width
或者 height
屬性來設定它的大小,同時圖片的比例還能夠保持不變。
如下圖所示,最上面是原始大小的圖片,下面兩張則分別是設定了 width: 50%
和 height: 50%
屬性後的樣子。
可以看到把寬度設定為了原來的一半的同時,圖片的高度並不是保持原來的大小,而是相應的也變成了原來的一半,使得圖片仍能夠保持原有的比例。同理把高度設成原來的一半也如此。
作為對照,我們看看單獨修改其他元素的寬和高會產生什麼樣的效果:
上圖最左邊的藍色矩形是原始的 div 元素,之後兩個分別是對其設定了 width: 50%
和 height: 50%
屬性後的樣子。可見與 img 元素不同,單獨設定 div 元素的寬度(高度)時,對應的高度(寬度)並不會改變,從而導致元素的比例發生變化。這一結果相信每個稍微對前端有些瞭解的同學都能猜到。但是究竟是什麼導致了同樣的屬性用於 img 和 div 後會產生不同的結果呢?
img 在元素分類中屬於 replaced (被替換的)元素。replaced 元素表示這個元素內容的顯示不是由 CSS 控制的。換句話說,對於 img 元素而言,圖片的內容並不是由 CSS 定義的,而是通過其 src
屬性指向的資源決定的。很多 replaced 元素來都會有自己的固有尺寸(Intrinsic dimension),img 也不例外1。當 img 的高度改變後,瀏覽器會計算出其縮放比例,而當元素的寬度是 auto
(即預設值)時,瀏覽器則以原始寬度 * 縮放比例
來作為元素的新寬度。從而使得 img 元素的比例始終保持一致。
然而這都並不是這篇文章討論的重點。(那位同學請不要說髒話,不文明
重點是什麼?重點就是題目:實現等比例縮放的盒子。
在響應式設計逐漸成為主流的今天,流式佈局這個詞即使放在一兩年前也絕算不得是個新鮮詞彙。下面是一個佈局例項:
上圖中每個藍色的矩形分別對應一個 div 元素,每個元素的寬度佔視窗寬度的四分之一(圖示中為了演示方便給每個元素加了邊距效果)。如果不做額外處理,當視窗寬度變小時上圖的頁面會變為如下所示:
可見每個元素的寬度進行了縮放,但高度並沒有變化,看起來並不是很協調。所以有些場景下我們需要實現當視窗寬度縮放時,使得元素寬度自適應的同時,保證每個元素的寬高比例不變。
很多同學在我話還沒講完時,就已經紛紛掏出 JavaScript 大錘著手實現了起來。然而這個系列文章的標題是《你不知道的 CSS》,自然不會介紹 CSS 實現不了這種打自己臉的需求,而且就此例而言,使用 JavaScript 實現效果並不好,繫結 onresize
事件後在拖拽時某些星座的朋友會察覺出來些許卡頓(你試試便知),而且在 JavaScript 載入完成前是看不出效果的。
其實用 CSS 可以很容易地實現這樣的效果,用的屬性也是我們每個工作日和週末(如果加班的話)都會用到的:padding-bottom
。padding-bottom
有一個讓人很容易忽略的特性是當它的值是百分比形式時,百分比的基數是其所在元素的父元素的寬度而不是高度(同 padding-left
和 padding-right
一樣)。這樣解決方案也就非常明顯了:
- 將元素的
height
設成0
,使得元素的高度等於padding-bottom
; - 合理設定
padding-bottom
的值。比如每個元素的width
是25%
,現在想讓元素的高度始終保持為其寬度的兩倍,則padding-bottom
的值應該設定為50%
。
結果如下圖所示:
相應的程式碼可以參見:jsfiddle.net/luin/25BbH/…。
然而至此,這篇文章還沒完。肯定會有很多同學疑惑既然 height
被設成了 0
,那麼如果元素的 overflow
為 hidden
,裡面的文字會不會因為超出了元素高度而被隱藏呢?
答案是不會。根據 CSS 2.1 規範2,overflow
只會對處於 padding edge 外面的內容生效,即只有超出了 padding 區域的內容才會被 overflow
屬性隱藏掉。
- 其實有一點例外的情況是當 img 的圖片是 svg 時,它是沒有固有尺寸的。 ↩
- www.w3.org/TR/CSS2/vis…↩
掃碼關注w3ctech微信公眾號