咱们都知道元素都拥有 position
这个css属性,先来看看他的基本定义和可用值。css
position
决定了元素位置是如何被渲染的html
值 | 描述 |
---|---|
static | 默认值,元素在文档流中依次渲染 |
absolute | 元素位置相对于其最近的非 static 的父元素 |
fixed | 元素位置相对于浏览器窗口 |
relative | 元素位置相对于本来应该渲染的位置 |
sticky | 根据滚动的位置在 relative 和 fixed 之间切换 |
initial | 设置为默认值 |
inherit | 从父元素继承 |
<body> <section> <p>This is a paragraph!</p> </section> </body>
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; }
很好,与咱们指望的同样渲染出来了。如今咱们把 section
的 display
属性 换成 inline
git
section { display: inline; width: 400px; height: 160px; background: lightgray; }
这个破坏真是立竿见影啊,为何会这样呢?要知晓其中的奥秘,就要了解什么是内容块。github
一般状况下,元素的大小和位置都取决他的内容块。通常地,内容块是该元素最近的块级父元素,但有一些例外状况。浏览器
元素的大小和位置都是由其内容块作为参考的,他会影响到元素的 width
, height
, padding
, margin
还有 offset
相关的属性。flex
position
是 static
或者 relative
时,其内容块是其最近的块级父元素的内容框(content-box),好比 block
, inline-block
, list-item
,或者是被指定为某种格式容器的元素,好比 table
, flex
, grid
。position
是 absolute
时,其内容块是其最近的 position
不是 static
的块级父元素的填充框(padding-box)。position
是 fixed
时,其内容块是整个视图窗口(viewport)position
是 absolute
或者 fixed
时,其内容块也多是有下列特殊状况的最近的父元素的填充框(padding-box)。spa
transform
或者 perspective
被设置过或将被设置不为 none
。filter
被设置或将被设置不为 none
。height
, top
和 bottom
依据内容块的 height
值进行百分比计算。若是内容块是 static
或者 relative
,而且没有设置高度,依靠其内容决定高度,那么这些值都会变成 0
。code
width
, left
, right
, padding
, margin
依据内容块的 width
值进行百分比计算。orm
如今咱们了解了内容快的概念以后,再来看看上面的例子,p
最近的父元素是 section
, 被设置为 inline
以后再也不是块级元素,因此 body
变成了离 p
最近的块级父元素,此时内部的百分比计算都依据 body
的宽高作对应计算。htm
咱们再看看别的例子
如今咱们将第一个例子中的 p
的 position
设置为 absolute
, section
从 inline
改回 block
,
body { background: beige; } section { display: block; width: 400px; height: 160px; background: lightgray; } p { position: absolute; width: 50%; /* == 浏览器宽度的50% */ height: 25%; /* == 浏览器高度的25% */ margin: 5%; /* == 浏览器宽度的5% */ padding: 5%; /* == 浏览器宽度的5% */ background: cyan; }
因为 p
设置为了 absolute
, 显而易见他的大小尺寸都根据了浏览器窗口来计算,注意这里也经历了寻找内容块的过程。p
的祖先元素均是 static
,因此浏览器窗口才成为了其内容块。
如今咱们还不错,一切都在掌握之中,咱们试着把 section
的 transform
设置为 rotate(0deg)
,旋转了 0 度,能够预计到原本应该没有视觉上的效果,但这么作会影响对内容块的决定,从而致使 p
的大小和位置变化。
section { transform: rotate(0deg); width: 400px; height: 160px; background: lightgray; } p { position: absolute; ... }
看!因为咱们为 section
设置了 transform
,p
的内容块再也不是浏览器窗口了,而是 section
。
css 的世界就是这么奇妙,表面上看上去酷炫多彩,心里维护着本身的规则世界。有时候产生了一些让人迷惑不解的 bug ...不过,经过探究其本质,迷雾终会散尽,bug 总会改完的。
但愿你们都 get 到了新技能,下回再见!
首发于本身的 github/kimochg/TinyThoughts