巧用margin/padding的百分比值實現高度自適應(多用於占位,避免閃爍)

来源:http://www.cnblogs.com/dehua-chen/archive/2016/03/27/5326797.html
-Advertisement-
Play Games

一個基礎卻又容易混淆的css知識點 本文依賴於一個基礎卻又容易混淆的css知識點:當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的! 也許你會說,left/right以父元素的width為參照物好理解,但是t ...


一個基礎卻又容易混淆的css知識點

本文依賴於一個基礎卻又容易混淆的css知識點:當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!

 也許你會說,left/right以父元素的width為參照物好理解,但是top/bottom為什麼也是以父元素的width為參照物的呢?

1、高度自適應占位

假設有這麼個場景:

 

如上圖所示,有這麼一種用來放圖片的容器,圖片都是正方形(為了方便舉例用正方形,實際上只要固定長寬比例即可)。

在PC端好辦,容器的寬高都寫死是多少px,這樣即使圖片載入不出來容器都不會變型。但是在移動端,由於各機型解析度相差太大,寫死px是絕對不可能的,終究還得靠百分比來實現自適應:

  1. 容器寬度設個50%吧,這樣一行放倆容器,各占屏幕寬度一半,沒問題。

  2. 圖片寬度設個100%取容器的寬度,沒問題。

  3. 容器高度沒法設置啊,因為容器寬高的參照物不一樣,而且需求是高度與寬度一致,所以無法通過為容器高度設置百分比來達成,那就只能靠內容高度撐開了。

  4. 容器的內容高度就是圖片的高度,若圖片是正方形,則圖片高度與圖片寬度一致,也即與容器寬度一致,看起來沒問題是吧?實際上,在瀏覽器把圖片載入出來以前,圖片的高度是零,那可就沒辦法把容器撐開了, 這樣一來,即使圖片載入速度很快,容器在圖片載入前後都會有一個變型的過程,也就是俗稱的“閃爍”,而如果圖片載入不出來,整體佈局就更是難看了。

現在問題已經出來了,就是如何做到不靠圖片本身就能把容器的高度撐開。

設置容器的padding-bottom/top

使用margin/padding的百分比值來解決自適應高度的關鍵在於:容器margin/padding的百分比參照物是父元素的寬度,而容器的width的百分比參照物也是父元素的寬度,倆屬性參照物一致,那麼想要把這倆屬性的值統一起來就很簡單了。

優化方案是這樣的:給容器設置padding-top/padding-bottom跟width一致的值(百分比)。

1 <div id="container" class="placeholder"></div>
1 #container {
2   width: 50%;  //父元素寬度的一半
3   background-color: red;  //僅為了方便演示}
4 .placeholder {
5   padding-top: 50%; //與width: 50%;的值保持一致,也就是相當於父元素寬度的一半。
6 }

結果,容器的視覺效果如下:

容器的盒子模型如下:

從盒子模型可以看出,雖然容器的內容高度為0,但由於有了跟內容寬度一致的padding,因此整體視覺效果上像是被撐開了。此方案瀏覽器相容性很不錯,唯一的缺陷是無法給容器設置max-height屬性了,因為max-height只能限制內容高度,而不能限制padding(我原以為設置box-sizing: border-box;可以讓max-height限制padding,不過親測無效)

給子元素/偽元素設置margin/padding撐開容器

從上面的方案看出max-height失效的原因是容器的高度本來就是padding撐的,而內容高度為0,max-height無法起作用。那想要優化這一點,唯一的方法就是利用內容高度來撐開而非padding,這個方案跟消除浮動所用的方案非常相似:給容器添加一個子元素/偽元素,並把子元素/偽元素的margin/padding設為100%,使其實際高度相當於容器的寬度,如此一來,便能把容器的高度撐至與寬度一致了。由於添加子元素與HTML語義化相悖,因此更推薦使用偽元素(:after)來實現此方案。

1 <div id="container" class="placeholder"></div>
#container {
  width: 50%;
  position: relative;
  background-color: red;
  overflow: hidden;  //需要觸發BFC消除margin摺疊的問題
}
.placeholder:after {
  content: '';
  display: block;
  margin-top: 100%; //margin 百分比相對父元素寬度計算
}

此時視覺效果上與上一方案無異,重點來看看此時容器的盒子模型:

可以看出,此時容器的內容高度與內容寬度一致,媽媽再也不用擔心我無法通過max-height來限制容器高度了。

另外,使用margin的話需要考慮margin摺疊的問題(參考),padding則無此煩惱。

 容器內部如何添加內容

 上述方案只提及如何不依賴容器內容來撐開容器,那麼,在撐開容器後,如何給容器添加內容(圖片、文本等)呢?

答案很簡單,那就是利用position: absolute;

1 <div id="container" class="placeholder">
2   <img src="http://img.arrayhuang.cn/product/miya-1060079/multiple/0.jpg@1e_415w_415h_1c_0i_1o_1x.jpg" />
3 </div>
 1 #container {
 2   width: 50%;
 3   position: relative;
 4   background-color: red;
 5   overflow: hidden;  //需要觸發BFC消除margin摺疊的問題
 6 }
 7 .placeholder:after {
 8   content: '';
 9   display: block;
10   margin-top: 100%; //margin 百分比相對父元素寬度計算
11 } 
12 img {
13   position: absolute;
14   top: 0;
15   width: 100%;
16 }

後補

 寬高不一致的自適應怎麼做?

 有朋友可能會問,上面提到的都是寬度與高度一致的情況,如果不一致那怎麼辦呢?其實自適應的重點在於,元素的寬高必須維持一個固定的比例,比如說寬高一致比例就是1:1,寬是高的兩倍那就是2:1,只要這個比例是明確而且固定的,那麼只需要相應地修改margin/padding的百分比值即可適應不同的寬高比例。

 還有其它的寬高自適應方案嗎?

 當然有,比如說css3新推出的長度單位vw,就是以屏幕寬度為參照物的,只要給元素的width和height都用上vw單位,那width跟height就可以輕易設成一樣的了,不過既然是css3,瀏覽器相容性肯定成問題:

總結

 自適應的精髓在於寬度,margin/padding設置百分比彌補了元素高度無法自適應地與元素寬度保持一致的缺陷。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原型模式(Prototype) 類圖 描述 原型模式: 提供一個克隆自身的介面--Clone方法。 應用場景 定義一個學生類,包含一個值類型(int)的Age屬性、兩個引用類型Name(string)和Course屬性。 輸出: student:Jim 20 C++ student:Jim 20 C ...
  • css垂直居中屬性設置vertical-align: middle對div不起作用,例如: 運行後按鈕沒有在DIV中垂直居中: 解決思路:如果div和按鈕的寬高都確定為具體像素值,可以直接設定按鈕的css屬性:position:relative; top為(div.height - button.h ...
  • 在Codewars上面練習,現在到6級的題目了(數字越小越難) 這道題叫Harshad or Niven numbers, 原題http://www.codewars.com/kata/54a0689443ab7271a90000c6/train/javascript (可以先自己做做看哦) Har ...
  • 這裡和搜集了前端開發者必備的20個線上工具和指南。新的一周,你需要計劃學習新的東西或者能夠提升你的能力。在平常的搜索中,我碰到過很多實用的工具,應用程式和參考文檔,我把它們整理在下麵這個列表。相信你會在這個列表中發現對你很有用的資料。 您可能感興趣的相關文章 Web 前端開發人員和設計師必讀文章集錦 ...
  • div、h1 或 p 元素常常被稱為塊級元素。這意味著這些元素顯示為 一塊內容,即“塊框”。與之相反,span 和 strong 等元素稱為“行 內元素”,這是因為它們的內容顯示在行中,即“行內框”。 CSS 有三種基本的定位機制:普通流、浮動和絕對定位。 除非專門指定,否則所有框都在普通流中定位。 ...
  • BFC 定義 BFC(Block formatting context)直譯為"塊級格式化上下⽂文"。它是⼀一個獨⽴立的渲染區域,只有Block-level box參 與, 它規定了內部的Block-level Box如何佈局,並且與這個區域外部毫不相干。 BFC佈局規則:內部的Box會在垂直⽅方向 ...
  • 在我們學習css時,利用浮動可以為我們的的佈局樣式提供很大的便利,但是隨著而來,我們也會遇到清除浮動的問題,關於清除浮動,我談一談我的一些簡單看法。 首先,我們為什麼要清除浮動,因為浮動會使該標簽脫離文檔流,對前後的元素,還有父元素(邊框,內容)都會造成影響。 下麵說一說清除浮動的方法: 1 定義h ...
  • 這隻是部分題,答案為個人觀點如有錯誤歡迎指出,感覺考點都挺基礎,但是很註重考細節方面,通過整理也知道自己在CSS3和HTML5,網路知識等方面的不足還是得多學多練多思考。攢rp,希望自己在明天360筆試中能輕鬆答過~css 1.多選 添加以下哪些樣式可以使超出部分文字變為"..."。 A.white ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...