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已经确定了。

--------学习 交流 提升-----------
原文地址:https://www.cnblogs.com/blogNYGJ/p/14141615.html