侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

CSS中的一些百分比相关调试经验分享

前端  /  管理员 发布于 7年前   200

很多css属性的取值都可以是百分比值。虽然形式上来说,百分比值都是数字后跟%的形式(注意数字和%之间不可以有空格),但在不同的使用场合下,其意义会有很多不同。因此,百分比值可以说包含了相当丰富的内容。
百分比值是相对值

要理解诸如100%这样的百分比值,其关键点是要明白,百分比是一定有其对应的参照值的。也就是说,百分比值是一种相对值,任何时候要分析它的效果,都需要正确找到它的参照。

一个css属性值从定义到最终实际使用,是存在一个过程的。这其中涉及到Specified Values(指定值)、Computed Values(计算值)、 Used Values(使用值)、Actual Values(实际值)等概念,可以想见到,百分比值实际会在这个过程中,根据它的参照计算转化为一个绝对值(比如100px),然后再被应用。这就是百分比值的意义。

更多关于css属性值的处理过程的信息,可以查看Value Processing。
百分比值的作用?

简单地说,就是可变性。这可以衍生出自适应、响应式等看起来很有用的东西。

比如说,一个固定宽高的盒子,然后希望盒子内有一个绝对定位的,宽高和盒子一样的盖板(就这样称呼吧...),下面这样的写法会很合适:

CSS Code复制内容到剪贴板
  1. .box{position:relative;width:100px;height:100px;}   
  2. .box_cover{position:absolute;width:100%;height:100%;left:0;top:0;}  

这里使用百分比值的好处的是,如果需要修改盒子的尺寸,只需要修改盒子的宽高,而盖板会自动保持和盒子的尺寸一致。

再一个例子是Bootstrap的栅格系统:

可以看到,栅格系统里会用到百分比值来实现确切的对空间的划分。百分比值是相对的,自适应的,因此栅格系统可以很好地用于响应式设计。
可用百分比值的常见css属性
width & height

宽和高在使用百分比值时,其参照都是元素的包含块(Containing Block,详情)。width参照包含块的宽度,height参照包含块的高度。在大部分情况下,包含块就是父元素的内容区(盒模型里的content)。

我以前写过width:100%; height:100%;这样的代码来实现尺寸和父元素一致。但我发现有时候宽度是符合意思(100%)的,但高度却没有效果。请看下面这个示例:

可以看到,直接父元素(包含块)是否有明确的高度定义,会影响height为百分比值时的结果。

关于这一点的详细解释是,当一个元素的高度使用百分比值,如果其包含块没有明确的高度定义(也就是说,取决于内容高度),且这个元素不是绝对定位,则该百分比值等同于auto。auto是初始默认值,所以看起来就像是“失效”了。

如果元素是根元素(<html>),它的包含块是视口(viewport)提供的初始包含块(initial containing block),初始包含块任何时候都被认为是有高度定义的,且等于视口高度。所以,<html>标签的高度定义百分比总是有效的,而如果你希望在<body>里也用高度百分比,就一定要先为<html>定义明确的高度。这就是为什么在之前的固定页脚一文中,有html, body{height:100%;}这样的写法。
margin & padding

这2个属性属于混合属性,也通过一个例子说明:

可以分析得到,对于margin和padding,其任意方向的百分比值,参照都是包含块的宽度。

为什么会多个方向都取包含块的宽度作为参照呢?在我看来,包含块的宽度在块布局的排版中是最有用的(想象一下word里输入文字,到宽度边缘后换行的场景),对应的,水平方向的内外边距一定要参照包含块的宽度。再考虑垂直方向的内外边距,它们如果不和水平方向取相同的参照物,就会因为不一致而很难使用。所以,总体来说,统一以包含块的宽度作为参考,会具有相对最好的可用性。

严格地说,参照是包含块的宽度,是在样式属性writing-mode为默认值时的情况。不过这个属性极少被用到,所以在此不做考虑。
border-radius

你也许见过有人用下面的代码来让一个矩形变成刚好的圆形(请体会这个“刚好”):

CSS Code复制内容到剪贴板
  1. .circle{border-radius:50%;}  

对此的解释是,为一个元素的border-radius定义的百分比值,参照物是这个元素自身的尺寸。也就是说,假如这个元素宽是60px,高是50px(border-box的尺寸),那么border-radius:50%的结果等同于border-radius:30px/20px;。

如果你还疑惑这里带/的圆角写法,请查看MDN对border-radius的说明。
background-position

background-position的初始值就是百分比值0% 0%。下面是一个使用示例:

background-position的百分比值,取的参照是一个减法计算值,由放置背景图的区域尺寸,减去背景图的尺寸得到,可以为负值。对照上面的示例,思考一下,应该可以感受到,以这个减法计算值为参照的话,正好可以符合我们感官上对背景图位置的理解。

这个属性包括水平位置和垂直位置,它们分别参照的是宽度减法计算值和高度减法计算值。

你可能注意到了上面示例的最后一个竟然写了4个值(一般都只用2个值)。关于它的意义,请查看W3C的background-position。
font-size

参照是直接父元素的font-size。例如,一个元素的直接父元素的font-size是14px,无论这个是直接定义的,还是继承得到的,当该元素定义font-size:100%;,获得的效果就是font-size:14px;。
line-height

参照是元素自身的font-size。例如,一个元素的font-size是12px,那么line-height:150%;的效果是line-height:18px;。
vertical-align

参照是元素自身的line-height(和前面很有关联吧,所以我排在了这里)。例如,一个元素的line-height是30px,则vertical-align:10%;的效果是vertical-align:3px;。

对这个属性我还想说,尽管vertical-align可以使用数字,百分比值,但浏览器兼容性差异较大,在跨浏览器实现时可能需要较多hack。因此,我个人倾向于使用middle等相对来说兼容性差异较小的关键字类型的值。
定位用的bottom、left、right、top

参照是元素的包含块。left和right是参照包含块的宽度,bottom和top是参照包含块的高度。
transform: translate

平移变换,在水平方向和垂直方向上也可以使用百分比,其参照是变换的边界框的尺寸(等于这个元素自己的border-box尺寸)。例如,一个宽度为150px,高度为100px的元素,定义transform:translate(50%, 50%)的效果是transform:translate(75px, 50px);。

还可以补充一点,translate3d对应是还有第三个维度的,但是,经过测试,最后的第3个值不可以使用百分比(否则样式定义无效)。至于为什么不可以参照呢,大概是因为那是神秘的第三维度吧...
其他

如果你想要知道更多的百分比值在css属性中的可用情况及参照值,请参考MDN的CSS percentage values。
百分比值的继承

请注意,当百分比值用于可继承属性时,只有结合参照值计算后的绝对值会被继承,而不是百分比值本身。例如,一个元素的font-size是14px,并定义了line-height:150%;,那么该元素的下一级子元素继承到的line-height就是21px,而不会再和子元素自己的font-size有关。
结语

好不容易终于看完了这么多百分比值的用法,有兴趣要使用一些吗?(?-?*)

我自己的看法是,百分比值是css所提供的一种建立元素与元素之间,或者元素的不同属性之间的关联性的有效方法。只要是想建立一种关联性,都可以适当考虑使用百分比值。而且,不需自己做任何动态的事件处理和更新,任何时候,你都可以信赖这个百分比。


  • 上一条:
    解析css中的选择符命名
    下一条:
    深入解读CSS的OOCSS和SMACSS以及BEM
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客