你可能不知道的 css 内容块

position

咱们都知道元素都拥有 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;
}

很好,与咱们指望的同样渲染出来了。如今咱们把 sectiondisplay 属性 换成 inlinegit

section {
  display: inline;
  width: 400px;
  height: 160px;
  background: lightgray;
}

这个破坏真是立竿见影啊,为何会这样呢?要知晓其中的奥秘,就要了解什么是内容块。github

内容块

定义

一般状况下,元素的大小和位置都取决他的内容块。通常地,内容块是该元素最近的块级父元素,但有一些例外状况。浏览器

为何内容块很重要

元素的大小和位置都是由其内容块作为参考的,他会影响到元素的 width, height, padding, margin 还有 offset 相关的属性。flex

如何找到元素对应的内容块

  1. positionstatic 或者 relative 时,其内容块是其最近的块级父元素的内容框(content-box),好比 block, inline-block, list-item,或者是被指定为某种格式容器的元素,好比 table, flex, grid
  2. positionabsolute 时,其内容块是其最近的 position 不是 static 的块级父元素的填充框(padding-box)。
  3. positionfixed 时,其内容块是整个视图窗口(viewport)
  4. positionabsolute 或者 fixed 时,其内容块也多是有下列特殊状况的最近的父元素的填充框(padding-box)。spa

    • transform 或者 perspective 被设置过或将被设置不为 none
    • filter 被设置或将被设置不为 none

从内容块计算百分比

height, topbottom 依据内容块的 height 值进行百分比计算。若是内容块是 static 或者 relative,而且没有设置高度,依靠其内容决定高度,那么这些值都会变成 0code

width, left, right, padding, margin 依据内容块的 width 值进行百分比计算。orm

例子解释

如今咱们了解了内容快的概念以后,再来看看上面的例子,p 最近的父元素是 section, 被设置为 inline 以后再也不是块级元素,因此 body 变成了离 p 最近的块级父元素,此时内部的百分比计算都依据 body 的宽高作对应计算。htm

absolute的用例

咱们再看看别的例子

如今咱们将第一个例子中的 pposition 设置为 absolute, sectioninline 改回 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,因此浏览器窗口才成为了其内容块。

如今咱们还不错,一切都在掌握之中,咱们试着把 sectiontransform 设置为 rotate(0deg),旋转了 0 度,能够预计到原本应该没有视觉上的效果,但这么作会影响对内容块的决定,从而致使 p 的大小和位置变化。

section {
  transform: rotate(0deg);
  width: 400px;
  height: 160px;
  background: lightgray;
}

p {
  position: absolute;
  ...
}

看!因为咱们为 section 设置了 transformp 的内容块再也不是浏览器窗口了,而是 section

总结

css 的世界就是这么奇妙,表面上看上去酷炫多彩,心里维护着本身的规则世界。有时候产生了一些让人迷惑不解的 bug ...不过,经过探究其本质,迷雾终会散尽,bug 总会改完的。

但愿你们都 get 到了新技能,下回再见!

首发于本身的 github/kimochg/TinyThoughts

相关文章
相关标签/搜索