CSS 中的百分比(%)

400 阅读5分钟

CSS 中很多属性都会用到百分比作为单位,例如最常见的宽度、高度、边距等。但是每种属性设置为百分比值时,所参照的对象会有所不同,本文就来总结下CSS中有哪些属性会用到百分比,以及它们所参照的对象是什么。

一、 相对于包含块

一般来说,包含块就是这个元素最近的祖先块元素内容区域

CSS 中的盒子模型划分为内容区、内边距区、边框区、外边距区: image.png

1.1 如何确定包含块

对于大多数开发者而言,会默认一个元素的包含块就是其父元素的内容区,但这并不完全准确 。确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:

  1. 如果 position 属性为 staticrelative 或 sticky,包含块可能由它的最近的祖先块元素的内容区的边缘组成。

如下示例,子元素 child position 属性为默认值 static,那么它的包含块为其父元素 parent 的内容区域,即图中红线框选区域。

<style>
  .parent {
    width: 200px;
    height: 200px;
    padding: 20px;
    border: 2px solid #000;
    background: #afb4db;
  }

  .child {
    width: 50%;  /* 100px /
    height: 50%; /* 100px /
    background: #84bf96;
  }
</style>

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

1733014459435.png

  1. 如果 position 属性为 absolute ,包含块就是由它的 最近的 position 的值不是 static  (也就是值为fixedabsoluterelative 或 sticky)的祖先元素的内边距区的边缘组成。

如下示例,子元素 child position 属性为 absolute,其最近的 position 的值不是static的组先元素为parent,那么它的包含块就是 parent 元素的内边距区。

注意:这种情况下是内边距区,即 内边距 + 内容区域。

<style>
  .parent {
    position: repative;
    ...
  }

  .child {
    position: absolute;
    top: 0;
    left: 0;
    ...
  }
</style>

...

1733014904909.png

  1. 如果 position 属性是 fixed,在连续媒体的情况下 (continuous media) 包含块是 viewport ,在分页媒体 (paged media) 下的情况下包含块是分页区域 (page area)。

1.2 根据包含块计算百分值的属性

  • heightmin-heightmax-heighttop 及 bottom 属性根据包含块的 height 计算百分比值。
  • widthmin-widthmax-widthleftrightpadding 和 margin 属性根据包含块的 width 计算百分比值。

注意:margin 和 padding 四个方向上都是相对于包含块的 width 而言的。

此外,包含块的大小会受到box-sizing属性值的影响,假设祖先元素设置的宽高分别 widthheight,设置不同值的区别如下:

  • content-box
    • width = 内容区宽度
    • height = 内容区高度
  • border-box
    • width = border + padding + 内容区宽度
    • height = border + padding + 内容区高度
<style>
    .parent {
      width: 200px;
      height: 200px;
      background: #afb4db;
      padding: 20px;
      border: 2px solid #000;
    }

    .child {
      width: 50%;
      height: 50%;
      background: #84bf96;
    }

    .parent.second {
      box-sizing: border-box;
    }
</style>

<div class="parent first">
  <div class="child">
    content-box
  </div>
</div>
<div class="parent second">
  <div class="child">
    border-box 
  </div>
</div>

image.png

二、相对于自身

有些 CSS 属性设置为百分比时,是相对于自身大小的。

border-radius

元素的外边框圆角。使用百分数定义圆形半径或椭圆的半长轴,半短轴。水平半轴相对于盒模型的宽度;垂直半轴相对于盒模型的高度。负值无效。

例如,我们经常会通过设置 border-radius: 50% 来实现一个圆形:

width: 100px;
height: 100px;
border-radius: 50%;
background-color: #afb4db;

image.png

translate

在水平和/或垂直方向上平移

例如我们通常使用该属性配合 margin来实现水平居中:

margin-left: 50%;
transform: translate(-50%, 0);

background-size

背景图片大小

background-position

背景图片位置,这个位置是相对于由 background-origin 定义的位置图层的。background-origin取值如下:

  • border-box:背景图片的摆放以 border 区域为参考
  • padding-box: 背景图片的摆放以 padding 区域为参考
  • content-box:背景图片的摆放以 content 区域为参考

三、文本、字体相关

  • font-size:字体大小,相对于父元素的字体大小
  • line-height:行高,相对于元素自身的字体大小,计算值是给定的百分比值乘以元素计算出的字体大小
  • text-indent:区块元素中文本行前面空格(缩进)的长度,相对于包含区块级元素内容框的左侧(或右侧,对于从右到左的布局)边缘的距离。
  • vertical-align:指定行内(inline)、行内区块(inline-block)、表格单元格(table-cell)盒子的垂直对齐方式。设置为百分比时使元素的基线对齐到父元素的基线之上的给定百分比,该百分比是 line-height 属性的百分比。可以是负数。

四、flex/ grid 相关

  • flex-basis: flex 元素在主轴方向上的初始大小。设置为百分比时相对于其父弹性盒容器主轴尺寸
<style>
    .wrapper {
        display: flex;
        width: 400px;
        height: 100px;
        padding: 20px;
        border: 1px solid #000;
    }

    .flex-el {
        flex-basis: 30%;
        background: red;
    }
</style>

<div class="wrapper">
    <div class="flex-el">
    </div>
</div>

1733029487506.png

  • row-gap:元素之间的间隙(gutter)大小。设置为百分比时相对栅格容器

  • column-gap:元素之间的间隔(gutter)大小。设置为百分比时相对栅格容器

  • grid-rows-template:定义网格行,设置为百分比时相对于网格容器

  • grid-columnss-template:定义网格列,设置为百分比时相对于网格容器

总结

总结来说,CSS中常见可以设置为百分比的属性在值为百分比时到参照物大致如下:

  • heightmin-heightmax-height、 top 及 bottom 属性根据包含块的 height 计算百分比值。
  • widthmin-widthmax-widthleftrightpaddingmargin 属性根据包含块的 width 计算百分比值。
  • border-radiustranslatebackground-size:相对于元素自身大小
  • font-size:相对于父元素字体大小
  • line-height:相对于自身字体大小
  • flex-basis:相对于其父弹性盒容器主轴尺寸
  • row-gapcolumn-gap:相对于栅格容器大小
  • grid-rows-templategrid-columnss-template相对于网格容器大小

本文到这里就结束啦,当然 CSS 中还有其他可以设置为百分比的属性,这里就暂不讨论啦