之前在写《个人常用的水平居中方法》这篇文章的时候,百分比问题涉及到了包含块(containing block)这个概念。

今天刷面试题的时候,又看到了containing block这个词,之前计算百分比考虑了几种情况(如那些属性值根据哪个元素计算的),但不知道所谓的‘哪个元素’就是包含块。系统的看了看MDN中的内容,感觉受益匪浅。大家可以移步去MDN看,我这篇仅仅是在原文基础上加了个小知识点——client相关值。

原文 MDN布局和包含块

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。

当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

内容区、内边距区、边框区、外边区

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。

包含块的影响

元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值 (比如 position 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

确定包含块

确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:

  1. static、relative、sticky:包含块可能由它的最近的祖先块元素的内容区的边缘组成。也可能会建立格式化上下文(比如说 table container, flex container, grid container, 或者是block container 自身)。

  2. absolute: 包含块就是由它的最近的 position 的值不是 static 的祖先元素的内边距区的边缘组成。

注意以上两个,一个是内容区、一个是内容边距区

  1. fixed:在连续媒体的情况下包含块是窗口视图(viewport),分页媒体下的情况下包含块是分页区域(page area)。

如果position值是absolute或fixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:

注意:根元素()所在的包含块是一个被称为初始包含块的矩形。

内边距区相关补充

在原来整理的一篇所有视图属性和方法中,提到了clientWidth和clientHeight,这就是本文所指的内边距区大小。

在chrome和firefox浏览器中f12,选取页面中的元素时,显示的数据就是内边距区的宽高。注意不要和元素内容区的width、height混淆。

根据包含块计算百分值

如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

  1. height、top、bottom:通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relative 或 static ,那么,这些值的计算值为 auto。

  2. width、left、right、padding、margin 这些属性由包含块的 width 属性的值来计算它的百分值。

    这里特别强调padding和margin讲的是上下左右四个都是根据包含块的width


看到这,我发现之前很零散的知识突然就全部联系起来了。这感觉太棒了,一个包含块,解决了我很多疑问,无论是百分比按照什么计算,还是元素视图的应用,都在这篇文章里清晰了起来。昨天还在敲定位元素的各个百分比属性值是根据什么计算的打算整理出来发文的,今天就看到这篇文章,太棒了!


示例

Example1

P 标签设置为静态定位,所以它的包含块为

,因为距离最近的父节点即是她的包含块。

body {
background: beige;
} section {
display: block;
width: 400px;
height: 160px;
background: lightgray;
} p {
width: 50%; /* == 400px * .5 = 200px */
height: 25%; /* == 160px * .25 = 40px */
margin: 5%; /* == 400px * .05 = 20px */
padding: 5%; /* == 400px * .05 = 20px */
background: cyan;
}

Example2

在这个示例中,P 标签的包含块为 元素,因为

不再是一个块容器,所以并没有形成一个格式上下文。

body {
background: beige;
} section {
display: inline;
background: lightgray;
} p {
width: 50%; /* == half the body's width */
height: 200px; /* Note: a percentage would be 0 */
background: cyan;
}

Example3

这个示例中,P 元素的包含块是

,因为
的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 box-sizing 值设置为 border-box ,就没有这个问题。

body {
background: beige;
} section {
position: absolute;
left: 30px;
top: 30px;
width: 400px;
height: 160px;
padding: 30px 20px;
background: lightgray;
} /* 再次强调,是根据包含块的内容区大小(包含padding)计算的。有疑问回上面看内容区表示什么那块 */ p {
position: absolute;
width: 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 */
background: cyan;
}

Example4

这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。

body {
background: beige;
} section {
width: 400px;
height: 480px;
margin: 30px;
padding: 15px;
background: lightgray;
} p {
position: fixed;
width: 50%; /* == (50vw - (width of vertical scrollbar)) */
height: 50%; /* == (50vh - (height of horizontal scrollbar)) */
margin: 5%; /* == (5vw - (width of vertical scrollbar)) */
padding: 5%; /* == (5vw - (width of vertical scrollbar)) */
background: cyan;
}

Example5

这个示例中,P 元素的 position 为 absolute,所以它的包含块是

,也就是距离它最近的一个 transform 值不为 none 的父元素。

body {
background: beige;
} section {
transform: rotate(0deg);
width: 400px;
height: 160px;
background: lightgray;
} p {
position: absolute;
left: 80px;
top: 30px;
width: 50%; /* == 200px */
height: 25%; /* == 40px */
margin: 5%; /* == 20px */
padding: 5%; /* == 20px */
background: cyan;
}

(转自MDN)CSS基础一定要看的包含块(containing block)的更多相关文章

  1. css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )

    平时在工作中,总是有一些元素之间的边距与设定的边距好像不一致的情况,一直没明白为什么,最近仔细研究了一下,发现里面有学问:垂直元素之间的margin有有互相重叠的情况:新建一个BFC后,会阻止元素与外 ...

  2. CSS包含块containing block详解

    “包含块(containing block)”,W3c中一个很重要的概念,今天带大家一起来好好研究下. 初步理解 在 CSS2.1 中,很多框的定位和尺寸的计算,都取决于一个矩形的边界,这个矩形,被称 ...

  3. CSS学习笔记——包含块 containing block

    以下内容翻译自CSS 2.1官方文档.网址:https://www.w3.org/TR/CSS2/visudet.html#strut 有时,一个元素的盒子的位置和尺寸根据一个确定的矩形计算,这个确定 ...

  4. css包含块containing block

    <css权威指南>P167: The Containing Block Every element is laid out with respect to its containing b ...

  5. CSS基础 行内元素/行内块元素设置垂直对齐方式及常见使用案例

    vertical-align 属性值 效果 baseline 基线对齐 top 顶部对齐 middle 中心对齐 bottom 底部对齐 使用案例1:百度搜索框左边和右边底部没有对齐 使用vertic ...

  6. CSS基础面试题,快来查漏补缺

    本文大部分问题来源:50道CSS基础面试题(附答案),外加一些面经. 我对问题进行了分类整理,并给了自己的回答.大部分知识点都有专题链接(来源于本博客相关文章),用于自己前端CSS部分的查漏补缺.虽作 ...

  7. CSS基础知识之float

    前段时间写过一篇CSS基础知识之position,当时对float的理解不太准确,被慕课网多名读者指出(原文已修正,如有误导实在抱歉).现对float进行更深入的学习,在此把学习心得分享给大家. 浮动 ...

  8. 草珊瑚的css基础

    首先要了解如下概念: viewport,窗口大小,containing block,block formatting context,inline formatting context,dirctio ...

  9. CSS 基础 - Cascade and Inheritance

    CSS 基础 - Cascade and Inheritance MDN学习笔记:https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building ...

随机推荐

  1. RabbitMQ系列之【设置RabbitMQ远程ip登录】

    由于账号guest具有所有的操作权限,并且又是默认账号,出于安全因素的考虑,guest用户只能通过localhost登陆使用,并建议修改guest用户的密码以及新建其他账号管理使用rabbitmq. ...

  2. Map 转 json格式 保留null值的解决办法

    Map 转 json格式 保留null值的解决办法 开发中遇到将map数据转json格式,然后map中含null值的键值对都被转没了,所以记录一下,以下是解决方法 使用fastJson进行转换 imp ...

  3. python基础--程序交互、格式化输出、流程控制、break、continue

    在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 (1) 程序交互 #!/usr/bin/env python # -*- coding: ...

  4. 文本溢出后,隐藏显示"..."和margin边距重叠

    一.隐藏加省略 单行文本: overflow: hidden; white-space: nowrap; text-overflow: ellipsis; 多行文本: overflow: hidden ...

  5. cb22a_c++_标准模板库_STL_map_multimap红黑树(数据结构)关联容器

    cb22a_c++_标准模板库_STL_map_multimap红黑树(数据结构)关联容器map(映射,key不能重复,一对一对的,value_type(1, "one")),mu ...

  6. PyCharm远程连接服务器简明教程

    转自本人知乎(https://zhuanlan.zhihu.com/p/149040742) 由于实验室的GPU都是放在远程服务器上,因此一直使用MobaXterm利用SSH远程跑实验,但是MobaX ...

  7. Apache Hudi:云数据湖解决方案

    1. 引入 开源Apache Hudi项目为Uber等大型组织提供流处理能力,每天可处理数据湖上的数十亿条记录. 随着世界各地的组织采用该技术,Apache开源数据湖项目已经日渐成熟. Apache ...

  8. 12.DRF-节流

    Django rest framework源码分析(3)----节流 添加节流 自定义节流的方法 限制60s内只能访问3次 (1)API文件夹下面新建throttle.py,代码如下: # utils ...

  9. 黎活明8天快速掌握android视频教程--14_把文件存放在SDCard

    把文件保存在手机的内部存储空间中 1 首先必须在清单文件中添加权限 <?xml version="1.0" encoding="utf-8"?> & ...

  10. TestNG离线安装步骤

    1.下载testNG 离线安装包[eclipse-testng离线包],并解压.资源可以在下载:http://download.csdn.net/detail/u012100968/9623613: ...