html盒子模型元素占位高度,利用css属性padding或margin的百分比值实现元素的高度自适应...

外边距属性margin和内边距属性padding取百分比值的时候,无论是left、right或top、bottom,都是以其父元素的宽值(width)作为参照物(即分母top/width),这是W3C的规范,官方原文如下:

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).

既然如此,就可以利用padding或margin的百分比值实现高度自适应了,在响应式网站中可以解决许多问题。(也可用于占位,避免元素闪烁),完美地弥补了元素高度无法和宽度自适应保持一致性的缺陷。

一、高度自适应占位

假设有这么个场景:

e6ceae431b27a01109024689c98e8f96.png

如上图所示,图片都是正方形(为了方便举例用正方形,实际上只要固定长宽比例即可)。

在PC端图片的容器的宽高都固定多少像素即可,即使图片加载不出来容器都不会变型或者排版都不会乱。但是在移动端,由于各机型分辨率相差太大,固定px是绝对不可能的,终究还得靠百分比来实现自适应。

宽度的百分比没有什么缺陷,值设置为百分比即可,但是容器高度height没法设置,因为容器宽高的参照物不一样,而且需求是高度与宽度一致,所以无法通过为容器高度设置百分比来达成,那就只能靠内容高度撑开。

容器的内容高度就是图片的高度,若图片是正方形,则图片高度与图片宽度一致,也即与容器宽度一致,看起来没什么问题,但实际上,在浏览器把图片加载出来以前,图片的高度是零,就不会把容器撑开,如下图所示:

8c78230597521c2f8048f4eb5f2ecf60.png

即使图片加载速度很快,容器在图片加载前后都会有一个变型的过程,也就是俗称的“闪烁”,而如果图片加载不出来,整体布局就更加是难看。那么要如何做到不靠图片本身就能把容器的高度撑开?方法是利用padding属性。

二、设置容器的padding-bottom/top

使用margin/padding的百分比值来解决自适应高度的关键在于:容器margin/padding的百分比参照物是父元素的宽度,而容器的width的百分比参照物也是父元素的宽度,俩属性参照物一致,那么想要把这俩属性的值统一起来就很简单了,只要把想要获取的高度值除以父元素的宽度,得出来的百分比就是padding-top/padding-bottom的百分比值。

CSS代码:

#container {

width: 50%; //父元素宽度的一半

background-color: red; //仅为了方便演示

}

.placeholder {

padding-top: 50%; //与width: 50%;的值保持一致,也就是相当于父元素宽度的一半。

}

HTML代码:

结果,容器的视觉效果如下:

5078d262d9f275b795d729077c989412.png

容器的盒子模型如下:

87b15ff041810ebfd6fe731e7983bbf3.png

从盒子模型可以看出,虽然容器的内容高度为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)来实现此方案。

CSS代码:

#container {

width: 50%;

position: relative;

background-color: red;

overflow: hidden; //需要触发BFC消除margin折叠的问题

}

.placeholder:after {

content: '';

display: block;

margin-top: 100%; //margin 百分比相对父元素宽度计算

}

HTML代码:

此时视觉效果上与上一方案无异,重点来看看此时容器的盒子模型:

0c7a42267609947fdd709c8f2c857476.png

可以看出,此时容器的内容高度与内容宽度一致,实现了通过max-height来限制容器高度。另外,使用margin的话需要考虑margin折叠的问题(参考),padding则无此烦恼。

四、容器内部如何添加内容

上述方案只提及如何不依赖容器内容来撑开容器,那么,在撑开容器后,如何给容器添加内容(图片、文本等)?可以给子元素添加position: absolute;实现。

CSS代码:

#container {

width: 50%;

position: relative;

background-color: red;

overflow: hidden; //需要触发BFC消除margin折叠的问题

}

.placeholder:after {

content: '';

display: block;

margin-top: 100%; //margin 百分比相对父元素宽度计算

}

img {

position: absolute;

top: 0;

width: 100%;

}

HTML代码:

1x.jpg

效果如下:

089e046ea8cced1e7ad7c797202f401f.png

五、宽高不一致的自适应怎么做?

嗯...不知道。

六、其它的宽高自适应方案

css3新推出的长度单位vw,就是以屏幕宽度为参照物的,只要给元素的width和height都用上vw单位,那width跟height就可以轻易设成一样的了,vw的浏览器兼容性如下:

18aea4d2fd157db55f022bc99133996d.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值