资讯专栏INFORMATION COLUMN

我所了解的CSS包含块

BenCHou / 3410人阅读

摘要:根元素包含块根元素的包含块是一个矩形叫做初始化包含块。如果属性是的话,包含块就是由组成的。示例二代码在这里,这个标签为默认的且它的父标签的为,所以标签的包含块为标签,通过我们的判断规则一来确定。

写在前面,本文将同步发布于Blog、掘金、segmentfault、知乎等处,如果本文对你有帮助,记得为我得到我的个人技术博客项目给个star哦。

指出错误观念

许多开发者认为一个元素的包含块就是他的父元素的内容区,其实这是错误的(至少不完全正确)!
一个元素的尺寸和位置经常受其包含块的影响。大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样。
下面我们看看盒模型:
当浏览器展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

内容区

内边距区

边框区

外边距区

什么是包含块?

包含块有分为根元素包含块和其他元素的包含块。

根元素包含块

根元素html的包含块是一个矩形,叫做初始化包含块(initial containing block)。
可以看到html外面还有空间,这个包含html的块就被称为初始包含块(initial containing block),它是作为元素绝对定位和固定定位的参照物。
对于连续媒体设备(continuous media),初始包含块的大小等于视口viewpor的大小,基点在画布的原点(视口左上角);对于分页媒体(paged media),初始包含块是页面区域(page area)。初始包含块的direction属性与根元素的相同。

其他元素的包含块

大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样,下面就来学习如何确定这些元素的包含块。

如何确定元素的包含块?

确定包含块的过程完全依赖于这个包含块的 position 属性,大致分为下列场景:

如果 position 属性是 static 或 relative 的话,包含块就是由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)或格式化上下文BFC(比如说 a table container, flex container, grid container, or the block container itself)的内容区的边缘组成的。

如果 position 属性是 absolute 的话,包含块就是由它的最近的 position 的值不是 static (fixed, absolute, relative, or sticky)的祖先元素的内边距区的边缘组成的。

如果 position 属性是 fixed 的话,包含块就是由 viewport (in the case of continuous media) or the page area (in the case of paged media) 组成的。

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

A transform or perspective value other than none
A will-change value of transform or perspective
A filter value other than none or a will-change value of filter (only works on Firefox).

元素包含块的作用?

元素的尺寸和位置经常受其包含块的影响。对于一个绝对定位的元素来说(他的 position 属性被设定为 absolute 或 fixed),如果它的 width, height, padding, margin, 和 offset 这些属性的值是一个比例值(如百分比等)的话,那这些值的计算值就是由它的包含块计算而来的。
简单来说,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

height, top, bottom 这些属性由包含块的 height 属性的值来计算它的百分值。如果包含块的 height 值依赖于它的内容,且包含块的 position 属性的值被赋予 relative 或 static的话,这些值的计算值为0。

width, left, right, padding, margin, text-indent(2018-05-27修改)这些属性由包含块的 width 属性的值来计算它的百分值。

下面看些例子

下面示例公用HTML代码


  

This is a paragraph!

示例一

CSS代码

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;
}

在这里,这个P标签position为默认的static,所以它的包含块为Section标签,通过我们的判断规则一来确定。

示例二

CSS代码

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;
}

在这里,这个P标签position为默认的static且它的父标签Section的display为inline,所以P标签的包含块为body标签,通过我们的判断规则一来确定。

示例三

CSS代码

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;
}

在这里,这个P标签position为absolute且它的父标签Section的transform不为none,所以P标签的包含块为Section标签,通过我们的判断规则四来确定。

示例四

CSS代码

body {
  background: beige;
}

section {
  position: absolute;
  left: 30px;
  top: 30px;
  width: 400px;
  height: 160px;
  padding: 30px 20px;
  background: lightgray;
}

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;
}

在这里,这个P标签position为absolute且它的父标签Section的position不为static,所以P标签的包含块为Section标签的padding边缘算起(前提是不能 box-sizing设置为border-box),通过我们的判断规则二来确定。

示例五

CSS代码

body {
  background: beige;
}

section {
  width: 300px;
  height: 300px;
  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;
}

在这里,这个P标签position为fixed,所以P标签的包含块为初始包含块(viewport),通过我们的判断规则三来确定。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/116884.html

相关文章

  • 我所知道flex布局 —— 上篇

    摘要:布局也经历了一段演变历史。不同于将要出现的网格布局针对目标为大比例布局,弹性盒布局更适用于应用组件和小比例布局。常规布局是基于块和内联流方向,而布局是基于流。 前言 你还在用display+position+float来进行css布局吗?有没有觉得用传统的这种布局方法来实现特殊布局特别麻烦困难,例如:垂直居中。今天来记录一下自己对flex布局的了解(虽然不算神马新东西了都可以说是旧东西...

    andycall 评论0 收藏0
  • 基础知识 - 收藏集 - 掘金

    摘要:本文是面向前端小白的,大手子可以跳过,写的不好之处多多分钟搞定常用基础知识前端掘金基础智商划重点在实际开发中,已经非常普及了。 JavaScript字符串所有API全解密 - 掘金关于 我的博客:louis blog SF专栏:路易斯前端深度课 原文链接:JavaScript字符串所有API全解密 本文近 6k 字,读完需 10 分钟。 字符串作为基本的信息交流的桥梁,几乎被所有的编程...

    wdzgege 评论0 收藏0
  • 翻译 | 上手 Webpack ? 这篇就够了!

    摘要:最后,我们在控制台中打印这个新数组。也可以借助简单的将其跑在浏览器上,之后可在控制台中看到同样的运行结果。使用配置文件虽然会更占位置,但与此同时增加了可读性,因为它是由写成的。例如,规定后缀的文件要先通过检查,再通过把语法转换为语法。 译者:小 boy (沪江前端开发工程师) 本文原创,转载请注明作者及出处。 原文地址:https://www.smashingmag...

    codercao 评论0 收藏0
  • 我所理解简单项目结构

    摘要:将图片都放入文件夹下指定公共的名字。匹配删除的文件根目录开启在控制台输出信息启用删除文件插入开关说一些可能没用的站在前端角度不懂的很多很多时候一个项目都是由一个小组完成的,小组成员可能包括产品,前端,后端,测试,运营等等。 不急,先听我唠会嗑~ 随着js发展的如此迅速,市场上越来越多的前端框架可以方便开发者使用。 本人大四渣渣一名,先后实习了两个地方,第一家公司用vuejs,实话...

    _DangJin 评论0 收藏0
  • bfc初探

    摘要:初探什么是全称是块级格式化上下文,是可视化渲染的一部分,它是块级盒子的布局发生,浮动互相交互的部分。可以把父元素设置成这样可以使这个元素包含其浮动子元素。而浮动元素本身是脱离文档流的,非元素的高度计算是不会把浮动元素计算在内。 bfc初探 什么是bfc bfc全称是块级格式化上下文(block formating context),是web可视化css渲染的一部分,它是块级盒子的布局发...

    yzd 评论0 收藏0

发表评论

0条评论

BenCHou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<