巧用margin/padding的百分比值實(shí)現(xiàn)高度自適應(yīng)(多用于占位,避免閃爍)

本文依賴于一個(gè)基礎(chǔ)卻又容易混淆的css知識(shí)點(diǎn):當(dāng)margin/padding取形式為百分比的值時(shí)再芋,無(wú)論是left/right辜伟,還是top/bottom氓侧,都是以父元素的width為參照物的!

也許你會(huì)說(shuō)导狡,left/right以父元素的width為參照物好理解约巷,但是top/bottom為什么也是以父元素的width為參照物的呢?網(wǎng)上眾說(shuō)紛紜旱捧,關(guān)鍵還是看W3C的規(guī)范:

Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).
Note that percentages on ‘padding-top’ and ‘padding-bottom’ are relative to the width of the containing block, not the height (at least in a horizontal flow; in a vertical flow they are relative to the height).

權(quán)威一出独郎,記住就好,科科枚赡。

高度自適應(yīng)占位

假設(shè)有這么個(gè)場(chǎng)景:


如上圖所示氓癌,有這么一種用來(lái)放圖片的容器,圖片都是正方形(為了方便舉例用正方形贫橙,實(shí)際上只要固定長(zhǎng)寬比例即可)贪婉。

在PC端好辦,容器的寬高都寫死是多少px卢肃,這樣即使圖片加載不出來(lái)容器都不會(huì)變型疲迂。

但是在移動(dòng)端,由于各機(jī)型分辨率相差太大莫湘,寫死px是絕對(duì)不可能的尤蒿,終究還得靠百分比來(lái)實(shí)現(xiàn)自適應(yīng):

1.容器寬度設(shè)個(gè)50%吧,這樣一行放倆容器逊脯,各占屏幕寬度一半优质,沒(méi)問(wèn)題。

2.圖片寬度設(shè)個(gè)100%取容器的寬度,沒(méi)問(wèn)題巩螃。

3.容器高度沒(méi)法設(shè)置啊演怎,因?yàn)槿萜鲗捀叩膮⒄瘴锊灰粯樱倚枨笫歉叨扰c寬度一致避乏,所以無(wú)法通過(guò)為容器高度設(shè)置百分比來(lái)達(dá)成爷耀,那就只能靠?jī)?nèi)容高度撐開(kāi)了。

4.容器的內(nèi)容高度就是圖片的高度拍皮,若圖片是正方形歹叮,則圖片高度與圖片寬度一致,也即與容器寬度一致铆帽,看起來(lái)沒(méi)問(wèn)題是吧咆耿?實(shí)際上,在瀏覽器把圖片加載出來(lái)以前爹橱,圖片的高度是零萨螺,那可就沒(méi)辦法把容器撐開(kāi)了,如下圖所示:


這樣一來(lái)愧驱,即使圖片加載速度很快慰技,容器在圖片加載前后都會(huì)有一個(gè)變型的過(guò)程,也就是俗稱的“閃爍”组砚,而如果圖片加載不出來(lái)吻商,整體布局就更是難看了。
現(xiàn)在問(wèn)題已經(jīng)出來(lái)了糟红,就是如何做到不靠圖片本身就能把容器的高度撐開(kāi)艾帐。

設(shè)置容器的padding-bottom/top

使用margin/padding的百分比值來(lái)解決自適應(yīng)高度的關(guān)鍵在于:容器margin/padding的百分比參照物是父元素的寬度,而容器的width的百分比參照物也是父元素的寬度改化,倆屬性參照物一致掩蛤,那么想要把這倆屬性的值統(tǒng)一起來(lái)就很簡(jiǎn)單了。
優(yōu)化方案是這樣的:給容器設(shè)置padding-top/padding-bottomwidth一致的值(百分比)陈肛。

   #container {   width: 50%;  //父元素寬度的一半   
                  background-color: red;  //僅為了方便演示 
               } 
   .placeholder {   padding-top: 50%; 
                   //與width: 50%;的值保持一致,也就是相當(dāng)于父元素寬度的一半兄裂。 }
   <div id="container" class="placeholder"></div>

結(jié)果句旱,容器的視覺(jué)效果如下:

容器的盒子模型如下:

從盒子模型可以看出,雖然容器的內(nèi)容高度為0晰奖,但由于有了跟內(nèi)容寬度一致的padding谈撒,因此整體視覺(jué)效果上像是被撐開(kāi)了。此方案瀏覽器兼容性很不錯(cuò)匾南,唯一的缺陷是無(wú)法給容器設(shè)置max-height屬性了啃匿,因?yàn)閙ax-height只能限制內(nèi)容高度,而不能限制padding(我原以為設(shè)置box-sizing: border-box;可以讓max-height限制padding,不過(guò)親測(cè)無(wú)效溯乒,明白的朋友麻煩告知一下原因)夹厌。

給子元素/偽元素設(shè)置margin/padding撐開(kāi)容器

從上面的方案看出max-height失效的原因是容器的高度本來(lái)就是padding撐的,而內(nèi)容高度為0裆悄,max-height無(wú)法起作用矛纹。那想要優(yōu)化這一點(diǎn),唯一的方法就是利用內(nèi)容高度來(lái)?yè)伍_(kāi)而非padding光稼,這個(gè)方案跟消除浮動(dòng)所用的方案非常相似:給容器添加一個(gè)子元素/偽元素或南,并把子元素/偽元素的margin/padding設(shè)為100%,使其實(shí)際高度相當(dāng)于容器的寬度艾君,如此一來(lái)采够,便能把容器的高度撐至與寬度一致了。由于添加子元素與HTML語(yǔ)義化相悖冰垄,因此更推薦使用偽元素(:after)來(lái)實(shí)現(xiàn)此方案蹬癌。

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

此時(shí)視覺(jué)效果上與上一方案無(wú)異,重點(diǎn)來(lái)看看此時(shí)容器的盒子模型:

可以看出播演,此時(shí)容器的內(nèi)容高度與內(nèi)容寬度一致冀瓦,媽媽再也不用擔(dān)心我無(wú)法通過(guò)max-height來(lái)限制容器高度了。
另外写烤,使用margin的話需要考慮margin折疊的問(wèn)題(參考)翼闽,padding則無(wú)此煩惱。

容器內(nèi)部如何添加內(nèi)容

上述方案只提及如何不依賴容器內(nèi)容來(lái)?yè)伍_(kāi)容器洲炊,那么感局,在撐開(kāi)容器后,如何給容器添加內(nèi)容(圖片暂衡、文本等)呢询微?
答案很簡(jiǎn)單,那就是利用position: absolute;

  #container {   width: 50%;   
                 position: relative;   
                 background-color: red;   
                 overflow: hidden;  
                 //需要觸發(fā)BFC消除margin折疊的問(wèn)題 
             }

  .placeholder:after {   content: '';   
                         display: block;   
                         margin-top: 100%; 
                         //margin 百分比相對(duì)父元素寬度計(jì)算 
                     }  
   img {   position: absolute;   
           top: 0;   
           width: 100%;
        }

   <div id="container" class="placeholder">  
      [站外圖片上傳中……(8)]
   </div>

效果如下:

后補(bǔ)

寬高不一致的自適應(yīng)怎么做狂巢?

有朋友可能會(huì)問(wèn)撑毛,上面提到的都是寬度與高度一致的情況,如果不一致那怎么辦呢唧领?其實(shí)自適應(yīng)的重點(diǎn)在于藻雌,元素的寬高必須維持一個(gè)固定的比例,比如說(shuō)寬高一致比例就是1:1斩个,寬是高的兩倍那就是2:1胯杭,只要這個(gè)比例是明確而且固定的,那么只需要相應(yīng)地修改margin/padding的百分比值即可適應(yīng)不同的寬高比例受啥。

還有其它的寬高自適應(yīng)方案嗎做个?

當(dāng)然有鸽心,比如說(shuō)css3新推出的長(zhǎng)度單位vw,就是以屏幕寬度為參照物的居暖,只要給元素的widthheight都用上vw單位顽频,那widthheight就可以輕易設(shè)成一樣的了,不過(guò)既然是css3膝但,瀏覽器兼容性肯定成問(wèn)題:

總結(jié)

自適應(yīng)的精髓在于寬度冲九,margin/padding設(shè)置百分比彌補(bǔ)了元素高度無(wú)法自適應(yīng)地與元素寬度保持一致的缺陷。

原網(wǎng)頁(yè)地址:http://www.kuqin.com/shuoit/20160113/350025.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跟束,一起剝皮案震驚了整個(gè)濱河市莺奸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冀宴,老刑警劉巖灭贷,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異略贮,居然都是意外死亡甚疟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門逃延,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)览妖,“玉大人,你說(shuō)我怎么就攤上這事揽祥》砀啵” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵拄丰,是天一觀的道長(zhǎng)府树。 經(jīng)常有香客問(wèn)我,道長(zhǎng)料按,這世上最難降的妖魔是什么奄侠? 我笑而不...
    開(kāi)封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮载矿,結(jié)果婚禮上垄潮,老公的妹妹穿的比我還像新娘。我一直安慰自己闷盔,他們只是感情好魂挂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著馁筐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坠非。 梳的紋絲不亂的頭發(fā)上敏沉,一...
    開(kāi)封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼盟迟。 笑死秋泳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的攒菠。 我是一名探鬼主播迫皱,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼辖众!你這毒婦竟也來(lái)了卓起?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凹炸,失蹤者是張志新(化名)和其女友劉穎戏阅,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體啤它,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奕筐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了变骡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片离赫。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塌碌,靈堂內(nèi)的尸體忽然破棺而出渊胸,到底是詐尸還是另有隱情,我是刑警寧澤誊爹,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布蹬刷,位于F島的核電站,受9級(jí)特大地震影響频丘,放射性物質(zhì)發(fā)生泄漏办成。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一搂漠、第九天 我趴在偏房一處隱蔽的房頂上張望迂卢。 院中可真熱鬧,春花似錦桐汤、人聲如沸而克。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)员萍。三九已至,卻和暖如春拣度,著一層夾襖步出監(jiān)牢的瞬間碎绎,已是汗流浹背螃壤。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留筋帖,地道東北人奸晴。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像日麸,于是被迫代替她去往敵國(guó)和親寄啼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容