CSS世界(张鑫旭)系列学习总结 (三)width和height作用的具体细节
元素最基本最常用的两个属性就是width和height了,他们虽然很普通很常见,却有着我不了解的东西。
先看看width属性,默认值是auto,意思就是自动计算宽度,具体怎么自动计算是有一个计算规则的,而且对于块级和内联元素这个规则还不一样。
假如,我在页面中写了一个元素,且没有设置width属性时,会有什么表现呢?
如果这个元素是div、p等块级元素,则它的width表现为父容器的宽度,随着容器的变化变化,始终和父容器宽度一致;(流特性)
如果这个元素是inline-block、浮动、绝对定位等内联元素,则它的宽度取决于元素包含内容的多少,内容为空的话宽度就是0,随着内容增加宽度增加;(包裹性)
对于以上两种情况,当元素中的内容多到快要超出父容器边界时,内容都会自动换行。
换个说法就是,块级元素的尺寸由外部尺寸也就是父容器尺寸决定,内联元素的尺寸由内部尺寸也就是由包含的内容或子元素尺寸决定。
width属性auto的这种表现,正是为了满足布局需要产生的,我们可以合理利用这种特性可以轻松实现自适应布局。
绝对定位元素一般情况下宽度表现的是包裹性,即由内容决定,但是有一种情况下会表现出流特性,比如:
div {position:absolute;left:20px;right:20px;}
可以这样理解,当对立方位属性值都存在,如left、right 或 top、bottom,此时该元素的尺寸已经可以确定了,因此就确定出来了。
1.width的作用细节
先来了解下“盒尺寸“概念,上篇说了,元素由外在盒子和内在盒子构成,外在盒子决定能不能换行,长啥样我也不知道,内在盒子就是我们耳熟能详的盒模型了。
这个盒模型从内到外依次是 content box、padding box、border box、margin box,简单明了。
前辈们设计了这个模型,也相应地定义了一堆属性来控制模型具体表现,而width、height这两个普通的属性就是作用在content box上的。
因此,我们看到的元素实际尺寸是content+padding+border的总和,这很容易理解,但实际中我们布局需要控制的是这个实际的总尺寸,往往有些麻烦。
麻烦在于,假如想让元素占据100px宽度,设置width为100px后,再调整padding、border的话,最终的宽度就不符合预期了,当然也可以直接设置一个减掉paddng、border之后的宽度值,如此再想调整布局,代码改动较多。
针对此问题,css3给出了解决方案 box-sizing,我们也可以使用宽度分离原则来处理,
.father{ width:180px } .son{ margin:0 20px; padding:20px; border:1px solid; }
2.height的作用细节
height的默认值也是auto,但它的计算规则却没有width那么复杂,只是简单的把子元素高度相加。
为什么如此简单呢?因为犯不上搞那么复杂。因为css默认流是水平方向的,宽度是稀缺的,而高度是无限的,所以关于宽度如何分配的规则就比较复杂。
2.1 width、 height:100%
对于width而言,无论父元素width是否为auto,子元素100%有效。
对于height而言,如果父元素height为auto,则100%会被忽略。
比如,直接在页面中插入div,代码如下:
div { width:100%; /*这是多余的*/ height:100%; /* 这是无效的*/ background:url(bg.jpg); }
因为,div属于块级元素,width默认auto,具有自适应性,不用设置100%,宽度始终自动充满父元素空间;height无效是因为父元素body宽度目前默认是auto;
想要生效,还需要这样操作一下:
html,body{ height:100%; }
这就是我们经常在项目,index.css文件中看到的代码。
做是这样做了,可是为什么呢?
官网解释:如果包含块的高度没有显示指定(即高度由内容决定),并且该元素不是绝对定位,则计算值为auto。
宽度的解释:如果包含块的宽度取决于该元素的宽度,即取决于子元素,则行为未定义。
但是各浏览器对此情况下宽度100%的表现行为一致,而高度由于是auto,该值无法和百分比进行计算,‘auto’*100/100=NaN,因此此情况下高度百分比无效。
父元素宽度auto,子元素宽度百分比的表现可以看这段代码:
<div class="box"> <img src="1.jpg"> <span class="text">红色背景是父级</span> </div> .box{ display:inline-block; white-space:nowrap; background-color:#cd0000; } .text{ display:inline-block; width:100%; background-color:#34538b; color:#fff; }
浏览器如何渲染呢,最终父元素多宽,子元素多宽?
浏览器的渲染顺序是自上而下、由外到内渲染DOM内容,因此在这里,会先渲染父元素,宽度是图片宽度加文字宽度,此时文字宽度是文字本身的宽度,没有被width 100%渲染,等父元素渲染完成,父元素宽度确定,子元素width 100%才会计算。
因此,height 100%生效的代码如下:
1. 设定显式高度值,600px,或可以生效的100%,比如我们从html一层层设置下来的height:100%
html,body{ height:100%; }
2.使用绝对定位
div{ height:100%; position:absolute; }
大概,按照规范的意思,绝对定位的时候,子元素百分比的计算值就不是auto了,父元素已经渲染结束了,height已经确定了。