终于搞懂了 CSS 中的百分比是基于什么工作的了!_height百分比基于谁

16 阅读5分钟

作为百分比,显然应该有一个目标作为参考源,这个参考一般是父元素。 这是正确的,但并不涵盖所有情况。 最正确的答案应该是包含块(containing block),即包含我们元素的块且它不必是直接的父元素。

看看下面的例子:

01.png

代码:

<div class="grandparent">
  <div class="parent">
    <div class="child"></div>
  </div>
</div>

.grandparent {
  position: relative;
  width: 200px;
  height: 200px;
  background: #eaeaea;
}

.parent {
  width: 100px;
  height: 100px;
  background: #aaa;
}

.child {
  position: absolute;
  width: 50%;
  height: 50%;
  top: 25%;
  left: 25%;
  background: red;
}


在上面的例子中,我创建了 3 个嵌套 div,它们是具有以下特征的3个正方形

  • 最外面的组元 div 是一个浅灰色,大小为 4x4
  • 父元素 div的颜色为深灰色,大小为 2x2
  • 以及分配 50% 大小的红色子 div

如果百分比单位以父级为来源,则子级的大小应该是它的 1/2,但上面的不是,子级的大小实际上等于父级,也就是祖父级的 1/2。 原因是祖父级 div 是子级 div 的真正包含块,因为子级具有 position: absolute ,对应于在祖父级中设置的 position:relative

因此,为了确定哪个是元素的实际包含块,它完全基于元素本身的 position 属性。

但是,对于某些属性,百分比单元的引用源既不是父块也不是包含块,而是它本身—— 自身元素

百分比的属性

width/height

如上面的例子中看到的,当一个元素为其宽度分配一个百分比值时, width 是基于包含块的width, height 是基于包含块的 height

padding

对于 padding,垂直(padding-top/padding-bottom)或水平(padding-left/padding-right)都是基于包含块的 width 来计算。

来个例子:

02.png

<div class="parent">
	<div class="child"></div>
</div>

.parent {
  background: #eaeaea;
  width: 300px;
  height: 200px;
}

.child {
  display: inline-block;
  background: red;
  padding-top: 50%;
  padding-left: 50%;
}

.parent {
  position: relative;
}

线上地址:codepen.io/khangnd/pen…

在这个例子中:

  • div 的大小为 6x4
  • div的大小为 0,但 padding-toppadding-left 分别为 50%

最后的结果是,子元素的大小相当于父级元素 1/2宽度,也就是一个 3x3 的正方形。

margin

paddingmargin 的百分比(垂直和水平)也是相对于包含块的宽度来计算。

来个事例:

03.png

<div class="parent">
  <div class="child"></div>
</div>

.parent {
  background: #eaeaea;
  width: 300px;
  height: 200px;
}

.child {
  display: inline-block;
  background: red;
  width: 50px;
  height: 50px;
  margin-top: 50%;
  margin-left: 50%;
}


在这个例子中:

  • 父级 div 的大小为 6x4
  • margin-topmargin-left 分别为 50%

其结果是,子元素被定位在离父级元素的上边距和左边距3个单位的地方(父级宽度的1/2)。

top/bottom/left/right

topbottom基于包含块的height来计算,leftright 基于包含块的width来计算。

来个例子:

906769235-61460c0334586_fix732.png

<div class="parent">
  <div class="child"></div>
</div>

.parent {
  position: relative;
  background: #eaeaea;
  width: 300px;
  height: 200px;
}

.child {
  position: absolute;
  background: red;
  width: 16.67%;
  height: 25%;
  top: 50%;
  left: 50%;
}


在这个事例中:

  • 父级 div 的大小为 6x4
  • 子元素有 position: absolutetopleft 分别为 50%

最终结果,子 div 被定位在离父 div 的顶部边缘 2个单位的位置(父 div 高度的 1/2),并被定位在离父 div 的左侧边缘 3 个单位的位置(父 div 宽度的 1/2)。

transform: translate()

一个用于动画/过渡的不可思议的属性,它也支持百分比值。然而,这个属性并不指其包含的块,而是指其自身。

来个例子:

04.png

<div class="parent">
  <div class="child"></div>
</div>

.parent {
  background: #eaeaea;
  width: 300px;
  height: 200px;
}

.child {
  background: red;
  width: 100px;
  height: 50px;
  transform: translate(50%, 50%);
}


在这个事例中:

  • 父级 div 的大小为 6x4
  • div 的大小为 2x1,使用 transform: translate(50%, 50%)

最后结果,子 div 被定位在离父 div 的顶部边缘 0.5 个单位的位置(自身高度的 1/2),并被定位在离父 div 的左侧边缘 1 个单位的位置(自身宽度的 1/2)。

background-size

background-size 属性将百分比单元的复杂性提升到一个新的水平

此属性的百分比值指的是背景定位区域,类似于包含块,但添加了以下 3 个因素:

  • 只有内容的块(content-box)
  • 带有内容和 padding 的块 (padding-box
  • 带有内容、paddingborder 的块(border-box)

这三个值是由 background-origin 给出,具体看 MDN :developer.mozilla.org/zh-CN/docs/…

来个例子:

<div class="parent">
  <div class="child"></div>
</div>

.parent {
  background: #eaeaea;
  width: 300px;
  height: 200px;
}

.child {
  background-image: url(https://d2fltix0v2e0sb.cloudfront.net/dev-rainbow.png);
  background-size: 50% 50%;
  background-repeat: no-repeat;
  background-color: red;
  width: 50%;
  height: 50%;
}

05.png

在这个例子中:

  • div 的大小为 6x4
  • div 的大小为 3x2,没有 padding,没有 border
  • 这里使用了一个DEV logo(比例为 1:1 )作为子 div 的背景图像,背景大小属性设置为 50% 50%

其结果是,背景图像被拉伸为 1.5 x 1 的大小。

background-position

background-size 类似,background-position 属性的百分比也依赖于背景定位区域。

在这个例子中:

<div class="parent">
  <div class="child"></div>
</div>

ES6

  • 列举常用的ES6特性:

  • 箭头函数需要注意哪些地方?

  • let、const、var

  • 拓展:var方式定义的变量有什么样的bug?

  • Set数据结构

  • 拓展:数组去重的方法

  • 箭头函数this的指向。

  • 手写ES6 class继承。

微信小程序

  • 简单描述一下微信小程序的相关文件类型?

  • 你是怎么封装微信小程序的数据请求?

  • 有哪些参数传值的方法?

  • 你使用过哪些方法,来提高微信小程序的应用速度?

  • 小程序和原生App哪个好?

  • 简述微信小程序原理?

  • 分析微信小程序的优劣势

  • 怎么解决小程序的异步请求问题?

开源分享:docs.qq.com/doc/DSmRnRG…