之前在写《个人常用的水平居中方法》这篇文章的时候,百分比问题涉及到了包含块(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 标签设置为静态定位,所以它的包含块为

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

  1. body {
  2. background: beige;
  3. }
  4. section {
  5. display: block;
  6. width: 400px;
  7. height: 160px;
  8. background: lightgray;
  9. }
  10. p {
  11. width: 50%; /* == 400px * .5 = 200px */
  12. height: 25%; /* == 160px * .25 = 40px */
  13. margin: 5%; /* == 400px * .05 = 20px */
  14. padding: 5%; /* == 400px * .05 = 20px */
  15. background: cyan;
  16. }

Example2

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

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

  1. body {
  2. background: beige;
  3. }
  4. section {
  5. display: inline;
  6. background: lightgray;
  7. }
  8. p {
  9. width: 50%; /* == half the body's width */
  10. height: 200px; /* Note: a percentage would be 0 */
  11. background: cyan;
  12. }

Example3

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

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

  1. body {
  2. background: beige;
  3. }
  4. section {
  5. position: absolute;
  6. left: 30px;
  7. top: 30px;
  8. width: 400px;
  9. height: 160px;
  10. padding: 30px 20px;
  11. background: lightgray;
  12. }
  13. /* 再次强调,是根据包含块的内容区大小(包含padding)计算的。有疑问回上面看内容区表示什么那块 */
  14. p {
  15. position: absolute;
  16. width: 50%; /* == (400px + 20px + 20px) * .5 = 220px */
  17. height: 25%; /* == (160px + 30px + 30px) * .25 = 55px */
  18. margin: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
  19. padding: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
  20. background: cyan;
  21. }

Example4

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

  1. body {
  2. background: beige;
  3. }
  4. section {
  5. width: 400px;
  6. height: 480px;
  7. margin: 30px;
  8. padding: 15px;
  9. background: lightgray;
  10. }
  11. p {
  12. position: fixed;
  13. width: 50%; /* == (50vw - (width of vertical scrollbar)) */
  14. height: 50%; /* == (50vh - (height of horizontal scrollbar)) */
  15. margin: 5%; /* == (5vw - (width of vertical scrollbar)) */
  16. padding: 5%; /* == (5vw - (width of vertical scrollbar)) */
  17. background: cyan;
  18. }

Example5

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

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

  1. body {
  2. background: beige;
  3. }
  4. section {
  5. transform: rotate(0deg);
  6. width: 400px;
  7. height: 160px;
  8. background: lightgray;
  9. }
  10. p {
  11. position: absolute;
  12. left: 80px;
  13. top: 30px;
  14. width: 50%; /* == 200px */
  15. height: 25%; /* == 40px */
  16. margin: 5%; /* == 20px */
  17. padding: 5%; /* == 20px */
  18. background: cyan;
  19. }

(转自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. 程序员实用JDK小工具归纳,工作用得到

    在JDK的安用装目录bin下,有一些有非常实用的小工具,可用于分析JVM初始配置.内存溢出异常等问题,我们接下来将对些常用的工具进行一些说明. JDK小工具简介 在JDK的bin目录下面有一些小工具, ...

  2. intput子系统

    1.按键驱动程序的第一个版本:day07/04      //内核模块的基本要求   init.h module.h LICENSE      struct cdev btn_cdev;      b ...

  3. HashMap(二)之面试题系列

    定义类考题 什么是Hash?什么是HashMap? HashMap 的工作原理是什么 HashMap HashTable的区别 为什么要用HashMap 源码类考题 什么是hash碰撞,怎么减少碰撞, ...

  4. Eureka加了secsecurity后注册失败

    报错信息: com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known ...

  5. @hdu - 6607@ Easy Math Problem

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 求: \[\sum_{i=1}^{n}\sum_{j=1}^{n ...

  6. @loj - 2106@ 「JLOI2015」有意义的字符串

    目录 @description@ @solution@ @accepted code@ @details@ @description@ B 君有两个好朋友,他们叫宁宁和冉冉.有一天,冉冉遇到了一个有趣 ...

  7. XAI/MLI 可解释机器学习系列1- 开源&paper汇总

    一直在关注可解释机器学习领域,因为确实在工作中有许多应用 模型检查,特征重要性是否符合预期和AUC一样重要 模型解释,比起虚无缥缈的模型指标,解释模型学到的规律更能说服业务方 样本解释,为什么这些用户 ...

  8. Linux环境下操作Oracle数据库命令

    A增量备份 在Oracle用户下进行: 1.su – oracle, pwd to make sure. 2.脚本位置more /home/oracle/arch.sh 3.运行脚本 ./arch.s ...

  9. WIN10下如何解决PL2303驱动不可用的问题或者com口显示黄色感叹号usb-to-serial

    WIN10下如何解决PL2303驱动不可用的问题或者com口显示黄色感叹号usb-to-serial

  10. 学习ASP.NET Core(11)-解决跨域问题与程序部署

    上一篇我们介绍了系统日志与测试相关的内容并添加了相关的功能:本章我们将介绍跨域与程序部署相关的内容 一.跨域 1.跨域的概念 1.什么是跨域? 一个请求的URL由协议,域名,端口号组成,以百度的htt ...