(转自MDN)CSS基础一定要看的包含块(containing block)
之前在写《个人常用的水平居中方法》这篇文章的时候,百分比问题涉及到了包含块(containing block)这个概念。
今天刷面试题的时候,又看到了containing block这个词,之前计算百分比考虑了几种情况(如那些属性值根据哪个元素计算的),但不知道所谓的‘哪个元素’就是包含块。系统的看了看MDN中的内容,感觉受益匪浅。大家可以移步去MDN看,我这篇仅仅是在原文基础上加了个小知识点——client相关值。
一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。
当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:
内容区、内边距区、边框区、外边区
许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。
包含块的影响
元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值 (比如 position 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。
确定包含块
确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:
static、relative、sticky:包含块可能由它的最近的祖先块元素的内容区的边缘组成。也可能会建立格式化上下文(比如说 table container, flex container, grid container, 或者是block container 自身)。
absolute: 包含块就是由它的最近的 position 的值不是 static 的祖先元素的内边距区的边缘组成。
注意以上两个,一个是内容区、一个是内容边距区
- fixed:在连续媒体的情况下包含块是窗口视图(viewport),分页媒体下的情况下包含块是分页区域(page area)。
如果position值是absolute或fixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:
注意:根元素()所在的包含块是一个被称为初始包含块的矩形。
内边距区相关补充
在原来整理的一篇所有视图属性和方法中,提到了clientWidth和clientHeight,这就是本文所指的内边距区大小。
在chrome和firefox浏览器中f12,选取页面中的元素时,显示的数据就是内边距区的宽高。注意不要和元素内容区的width、height混淆。
根据包含块计算百分值
如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:
height、top、bottom:通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relative 或 static ,那么,这些值的计算值为 auto。
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 元素的包含块是
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,所以它的包含块是
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)的更多相关文章
- css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )
平时在工作中,总是有一些元素之间的边距与设定的边距好像不一致的情况,一直没明白为什么,最近仔细研究了一下,发现里面有学问:垂直元素之间的margin有有互相重叠的情况:新建一个BFC后,会阻止元素与外 ...
- CSS包含块containing block详解
“包含块(containing block)”,W3c中一个很重要的概念,今天带大家一起来好好研究下. 初步理解 在 CSS2.1 中,很多框的定位和尺寸的计算,都取决于一个矩形的边界,这个矩形,被称 ...
- CSS学习笔记——包含块 containing block
以下内容翻译自CSS 2.1官方文档.网址:https://www.w3.org/TR/CSS2/visudet.html#strut 有时,一个元素的盒子的位置和尺寸根据一个确定的矩形计算,这个确定 ...
- css包含块containing block
<css权威指南>P167: The Containing Block Every element is laid out with respect to its containing b ...
- CSS基础 行内元素/行内块元素设置垂直对齐方式及常见使用案例
vertical-align 属性值 效果 baseline 基线对齐 top 顶部对齐 middle 中心对齐 bottom 底部对齐 使用案例1:百度搜索框左边和右边底部没有对齐 使用vertic ...
- CSS基础面试题,快来查漏补缺
本文大部分问题来源:50道CSS基础面试题(附答案),外加一些面经. 我对问题进行了分类整理,并给了自己的回答.大部分知识点都有专题链接(来源于本博客相关文章),用于自己前端CSS部分的查漏补缺.虽作 ...
- CSS基础知识之float
前段时间写过一篇CSS基础知识之position,当时对float的理解不太准确,被慕课网多名读者指出(原文已修正,如有误导实在抱歉).现对float进行更深入的学习,在此把学习心得分享给大家. 浮动 ...
- 草珊瑚的css基础
首先要了解如下概念: viewport,窗口大小,containing block,block formatting context,inline formatting context,dirctio ...
- CSS 基础 - Cascade and Inheritance
CSS 基础 - Cascade and Inheritance MDN学习笔记:https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building ...
随机推荐
- Centos 7 k8s Deployment新副本控制器
一.概念 Kubernetes提供了一种更加简单的更新RC和Pod的机制,叫做Deployment.通过在Deployment中描述你所期望的集群状态,Deployment Controller会将在 ...
- kali设置NAT模式,无法正常上网请试试这个办法
1.释放网卡: dhclient -r eth0 2.自动获取网络 dhclient -v eth0 3.开启22端口 lsof -i :22 4.打开ssh service ssh start sy ...
- 备份、恢复数据库(Dos命令提示符下)_数据库安装工具_连载_1
Dos命令提示符下: 备份.恢复数据库,是不是很简单啊,是的,当你20年不碰MS SQL,是不是又忘记了呢,答案也许也是吧,^_^虽然在程序中执行SQL代码时,很讨厌那个Go,正如MySQL中那个分号 ...
- selenium获取图片验证码
# encoding:utf-8 from PIL import Image from selenium import webdriver url = '网站地址' driver = webdrive ...
- C#数据结构与算法系列(七):约瑟夫问题(Josephu)
1.介绍 Josephu问题为:设编号为1.2....n的n个人围坐在一圈,约定编号为k(1<=k<=n) 的人从1开始报数, 数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人 ...
- 前台页面id为空--驼峰命名映射
错误: 前台页面id为空,或其他数据映射问题(方案2) 原因: java的bean类属性和数据库字段命名不一致,查询的时候就不能把数据封装进bean类里, 在数据库字段命名规范中,通常使用下划线“_ ...
- Quaternion:通过API对Quaternion(四元数)类中的方法属性初步学习总结(二)
1.RotateTowards方法 RotateTowards(From.rotation,To.rotation,fspeed) 个人理解:使From的rotation以floatspeed为速度, ...
- 多语言工作者の十日冲刺<9/10>
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺--第九天(05.08) 作业正文 ...
- v-forv-for指令的三种使用方法
1.迭代数组 <p v-for="(item,i) in list">id:{{item.id}}---名字:{{item.name}}---索引{{item.age} ...
- .NET Core请求控制器Action方法正确匹配,但为何404?
前言 有些时候我们会发现方法名称都正确匹配,但就是找不到对应请求接口,所以本文我们来深入了解下何时会出现接口请求404的情况. 匹配控制器Action方法(404) 首先我们创建一个web api应用 ...