写在前面,本文会发表在Blog、掘金、segmentfault、知乎等,如果本文对你有帮助,记得获取我的个人技术博客项目我哦星。指出错误观念许多开发人员认为元素的包含块是其父元素的内容区域,这是错误的(至少不完全正确)!元素的大小和位置通常受其包含块的影响。在大多数情况下,包含块是该元素最近的祖先块元素的内容区域,但并非总是如此。让我们看一下盒子模型:当浏览器显示文档时,它会为每个元素生成一个盒子。每个框分为四个区域:内容区内边距区边框区外边距区什么是包含块?包含块分为用于根元素的包含块和用于其他元素的包含块。根元素包含块。根元素html的包含块是一个称为初始包含块的矩形。可以看出html之外还有空间。这个包含html的块称为初始包含块(initialcontainingblock),作为元素绝对定位和固定定位的参考。对于连续媒体设备(continuousmedia),初始包含块的大小等于viewport视口的大小,基点在画布的原点(viewport的左上角);对于分页媒体(pagedmedia),初始包含块是页面区域(pagearea)。初始包含块的方向属性与根元素的方向属性相同。其他元素的包含块大多数情况下,包含块是该元素最近的祖先块元素的内容区域,但也不总是这样。让我们学习如何确定这些元素的包含块。如何确定元素的包含块?确定包含块的过程完全取决于包含块的position属性,大致可以分为以下几种情况:如果position属性是static或者relative,则包含块由其最近的祖先块元素定义(比如作为内联块、块或列表项元素)或格式化上下文BFC(例如表容器、弹性容器、网格容器或块容器本身)内容的边缘面积.如果position属性是absolute,则包含块由其position值非静态(fixed、absolute、relative或sticky)组成。如果position属性是固定的,则包含块由视口(在连续媒体的情况下)或页面区域(在分页媒体的情况下)组成。如果position属性是绝对的或固定的,则包含块也可能由最近父元素的填充区域的边缘组成:一个变换或透视值不是noneAwill-changevalueoftransformorperspectiveAfiltervaluethannoneorawill-changevalueoffilter(onlyworksonFirefox).元素包含块有什么作用?元素的大小和位置通常受其包含块的影响。对于一个绝对定位的元素(其position属性设置为absolute或fixed),如果其width、height、padding、margin、offset是比例值(如百分比等),则这些值的计算值由其包含块计算。简单来说,如果给某个属性赋了一个百分比值,它的计算值就是由这个元素的包含块来计算的。这些属性包括盒模型属性和偏移属性:height、top、bottom这些属性根据包含块的高度属性的值计算其百分位值。如果包含块的高度值取决于其内容,并且包含块的位置属性的值是相对的或静态的,则这些值的计算结果为0。width,left,right,padding,margin,text-indent(修改于2018-05-27)这些属性是根据包含块的width属性的值来计算它的百分比值。让我们看一些例子。下面示例常见的HTML代码宽度:400px;高度:160px;背景:浅灰色;}p{宽度:50%;/*==400px*.5=200px*/高度:25%;/*==160px*.25=40px*/边距:5%;/*==400px*.05=20px*/padding:5%;/*==400px*.05=20px*/background:cyan;}这里P标签位置默认是静态的,所以它的包含块是一个Section标签,由我们的判断规则1决定。例2CSS代码主体{背景:米色;}部分{显示:内联;背景:浅灰色;}p{宽度:50%;/*==body宽度的一半*/height:200px;/*注意:百分比为0*/background:cyan;}这里P标签position默认是静态的,其父标签Section的显示是内联的,所以P标签的包含块是body标签,这是由我们的判断规则1决定的。例3CSS代码body{background:beige;}section{transform:rotate(0deg);宽度:400px;高度:160px;背景:浅灰色;}p{位置:绝对;左:80px;顶部:30px;宽度:50%;/*==200px*/高度:25%;/*==40px*/边距:5%;/*==20px*/填充:5%;/*==20px*/background:cyan;}这里P标签的位置是绝对的,其父标签Section的transform不是none,所以P标签的包含块是一个Section标签,这是确定的根据我们的判断规则4。例4CSS代码body{background:beige;}section{position:absolute;左:30px;顶部:30px;宽度:400px;高度:160px;填充:30px20px;背景:浅灰色;}p{位置:绝对;宽度:50%;/*==(400px+20px+20px)*.5=220px*/height:25%;/*==(160px+30px+30px)*.25=55px*/margin:5%;/*==(400px+20px+20px)*.05=22px*/padding:5%;/*==(400px+20px+20px)*.05=22px*/背景:青色;}这里,这个P标签的位置是绝对的,其父标签Section的位置不是静态的,所以P标签的包含块是从Section标签的padding边缘算起的(前提是box-sizing不能设置为border-box),通过我们的判断规则二、确定。例5CSS代码body{background:beige;}section{width:300px;高度:300px;边距:30px;填充:15px;背景:浅灰色;}p{位置:固定;宽度:50%;/*==(50vw-(垂直滚动条的宽度))*/height:50%;/*==(50vh-(水平滚动条的高度))*/margin:5%;/*==(5vw-(垂直滚动条的宽度))*/padding:5%;/*==(5vw-(widthofverticalscrollbar))*/background:cyan;}这里P标签的位置是固定的,所以P标签的包含块是初始包含块(viewport),确定根据我们的判断规则三。