CSS中的相对单位——长度和视口相对单位

  • 绝对单位:放在哪儿都一样,即其值不会随着外部因素的变化而变化,如px。
  • 相对单位:放在不同的位置,其值的大小可能不一样,即其值会随着外部因素的变化而变化,如em,rem等。

相对单位变化的方式使其难以预测,绝对单位更加简单明了。但是利用好相对单位可以让代码更加简洁、灵活和简单。

一、相对值的好处

CSS为网页带来了后期绑定(late-binding)的样式:直到内容和样式都完成了,二者才会结合起来(这里具体在流程中是: DOM 结构和 CSS 所代表的 CSSOM 结构是分开生成的)。

不能在刚创建网页时就应用样式,而是等到要将网页渲染到屏幕上时,才能去计算样式。

我们无法根据理想的条件给元素添加样式,而是要设置无论元素处于任意条件,都能够生效的规则。像素级完美也无法适应外部因素的变化,比如智能手机、电脑等载体的变化,不同屏幕比例的变化等,使得绝对单位的应对方法表现得不够灵活。

响应式——在CSS中指的是样式能够根据浏览器窗口的大小有不同的“响应”。

在写CSS的时候,我们既要考虑整体性,也要考虑差异性。当有很多方法解决同一个问题时,我们要选择能够兼顾更多情况的方法。

相对单位就是CSS用来解决这种抽象的一种工具。

像素是一个具有误导性的名称,CSS像素并不严格等于显示器的像素,尤其在高清屏(视网膜屏)下。尽管CSS单位会根据浏览器、操作系统或者硬件适当缩放,在某些设备或者用户的分辨率设置下也会发生变化,但是96px通常等于一个物理英寸的大小。

二、em和rem

  • em:em是一种相对长度单位,相对于自身元素的字号大小,如果没有设置即参照父容器的字号大小或浏览器默认字号大小。
  • rem: rem是css3的新标准也是一种相对长度单位,其相对于HTML根标签的字号大小。

Block 、Element、Modifier方法(通常称为BEM)是HTML 和 CSS 中类的流行命名约定。由Yandex 团队开发,其目标是帮助开发人员更好地理解给定项目中 HTML 和 CSS 之间的关系。
在此 CSS 方法中,块是新组件的顶级抽象,例如按钮 .btn { }。这个块应该被认为是父块。子项目或元素可以放在里面,这些元素由块名称后面的两个下划线表示,例如 .btn__price { }。最后,修饰符可以操纵块,这样我们就可以为特定组件设置主题或样式,而不会对完全不相关的模块造成更改。这是通过将两个连字符附加到块的名称来完成的,例如 .btn--orange.

2.1 使用em定义字号

提示:如果知道字号的像素值,但是想用em声明,可以用一个简单的公式换算:用想要的像素大小除以父级(继承)的像素字号。

对大多浏览器而言,默认字号大小为16px。准确地说,medium关键字的值是16px。

2.1.1 em同时用于字号和其他属性

em的复杂之处在于同时用它指定一个元素的字号和其他属性。这时,浏览器必须先计算字号,然后使用这个计算值去算出其余的属性值。这两类属性可以拥有一样的声明值,但是计算值不一样。注意看基准值是继承值还是绝对值。

2.1.2 字体缩小的问题

当用em来指定多重嵌套的元素的字号时,就会产生意外的结果。为了算出每个元素的准确值,就需要知道继承的字号,如果这个值是在父元素上用em定义的,就需要知道父元素的继承值,以此类推,就会沿着DOM树一直往上查找。

em用在内边距、外边距以及元素大小上很好,但是用在字号上就会很复杂,因为需要逐级向上寻找继承值。

em一般用于设置padding和margin,不建议来设置字体大小

1.当设置padding和margin时,最终值=字体值*em,即改变字体大小padding和margin会随之改变

2.当用于设置字体大小时,最终值=字体大小(继承或本身)*em,而且当为每一级都设置em的情况下字体可能会出现放大或缩小的情况。

em 用在字号上时需要根据父级字号来计算,当父级也用 em 定义字号时,就会出现字号逐级增大或减小的情况。

值得庆幸,我们有更好的选择:rem。

2.2 使用rem设置字号

当浏览器解析HTML文档时,会在内存里将页面的所有元素表示为DOM(文档对象模型)。在文档中,根节点是所有其他元素的祖先节点。根节点有一个伪类选择器(:root),可以用来选中它自己。

rem是root em的缩写。rem不是相对于当前元素,而是相对于根元素的单位。rem可以说是结合了px和em,既保留了相对单位的优势,也比较简单易用。


可访问性:对字号使用相对单位

有些浏览器给用户提供了两种方式来设置文字大小:缩放操作和设置默认字号。

  • 按住Ctrl+或Ctrl−,用户可以缩放网页。这种操作会缩放所有的字和图片,让网页整体放大或者缩小。在某些浏览器中,这种改变只会临时对当前标签页生效,不会将缩放设置带到新的标签页。
  • 设置默认字号可以永久生效,除非用户再次修改默认值。这种方式的缺点是,它不会影响用px或者其他绝对单位设置的字号。

由于默认的字号对某些用户而言很重要,尤其是对视力受损的人,所以应该始终用相对单位或者百分比设置字号。


推荐CSS搭配方案

  • rem设置字号;
  • px设置边框;
  • em设置内外边距、圆角等;
  • 百分比设置宽度;
  • https://tailwindcss.com

三、停止像素思维

响应式网页中,需要习惯“模糊”值。1.2em到底是多少像素并不重要,重点是它比继承的字号要稍微大一点。如果在屏幕上的效果不理想,就调整它的值,反复试验。这种方式同样适用于像素值。

给根元素设置了字号后,就定义了一个rem。在这之后,应该只在少数特殊情况下使用像素,而不能经常使用。

3.1 设置一个合理的默认字号

如果你希望默认字号为14px,那么不要将默认字体设置为10px然后再覆盖一遍,而应该直接将根元素字号设置为想要的值。将想要的值除以继承值(在这种情况下为浏览器默认值)是14/16,等于0.875。

3.2 构造响应式面板

我们可以根据屏幕尺寸,用媒体查询改变根元素的字号。这样就能够基于不同用户的屏幕尺寸,渲染出不同大小的面板。

媒体查询:即@media规则,可以指定某种屏幕尺寸或者媒体类型(比如,打印机或者屏幕)下的样式。这是响应式设计的关键部分。

ea76f51c84094082a4ec0955f2316a64.jpg

 通过给页面根元素设置不同字号,我们响应式地重新定义了整个网页的em和rem。

如果整个页面的样式都由相对单位来设置,那么整个页面可以随着视口大小响应式变化;而且位于样式表顶部的媒体查询可以极大减少后续css代码中媒体查询的数量。

3.3 缩放单个组件

给每个面板添加父元素声明font-size: 1rem,这样无论面板位于页面何处,都有一个可预测的字号。再用em设置内部物件,使其能随着父元素基准大小变化;最后根据组件大小再设置rem覆盖最初父元素。

四、视口的相对单位

CSS中的相对单位

  • 相对于font-size: em、rem;
  • 相对于浏览器视口定义长度:vw、vh、vmin、vmax;

视口——浏览器窗口里网页可见部分的边框区域。它不包括浏览器的地址栏、工具栏、状态栏。

❑ vh:视口高度的1/100。

❑ vw:视口宽度的1/100。

❑ vmin:视口宽、高中较小的一方的1/100(IE9中叫vm,而不是vmin)。这可以保证元素在屏幕方向变化时适应屏幕。在横屏时,vmin取决于高度;在竖屏时,则取决于宽度。

❑ vmax:视口宽、高中较大的一方的1/100。

视口相对长度非常适合展示一个填满屏幕的大图。我们可以将图片放在一个很长的容器里,然后设置图片的高度为100vh,让它等于视口的高度。

“3”是一个非正式的版本号,其实并没有CSS3规范,而是CSS规范分成了单独的模块,每个模块单独管理版本。如今背景和边框的规范脱离了盒模型模块以及层叠和继承模块。这样W3C就能够制定CSS某个领域的新版本,而不需要更新其他没变的领域。

4.1 使用vw定义字号

当视口大小变化时,元素大小会逐渐过渡,而不是在某个断点突然改变。但是在视口越来越大或者越来越小之后,元素大小会出现极端情况,不能很好适应视口。

4.2 使用calc()定义字号

calc()函数内可以对两个及其以上的值进行基本运算。在根节点用calc()设置字号可以使得不用媒体查询就实现了大部分的响应式策略。省掉三四个硬编码的断点,网页上的内容也能根据视口流畅地缩放。

calc(1em + 1vw):1em保证最小字号,1vw确保字体会随着视口变化。

五、无单位的数值和行高

有些属性允许无单位的值(即一个不指定单位的数)。支持这种值的属性包括line-height、z-index、font-weight(700等于bold,400等于normal,等等)。

注意:一个无单位的0只能用于长度值和百分比,比如内边距、边框和宽度等,而不能用于角度值,比如度,或者时间相关的值,比如秒。

line-height属性比较特殊,它的值既可以有单位也可以无单位。通常我们应该使用无单位的数值,因为它们继承的方式不一样。

继承的一个怪异特性:

  • 当一个元素的值定义为长度(px、em、rem,等等)时,子元素会继承它的计算值。
  • 使用无单位的数值时,继承的是声明值,即在每个继承子元素上会重新算它的计算值。

六、自定义属性(CSS变量)

层叠变量的自定义属性(Custom Properties for Cascading Variables):这个规范给CSS引进了变量的概念,开启了一种全新的基于上下文的动态样式。

要定义一个自定义属性,只需要像其他CSS属性那样声明即可。

  • 变量名前面必须有两个连字符(--),用来跟CSS属性区分,剩下的部分可以随意命名;
  • 变量必须在一个声明块内声明;
  • 调用函数var()就能使用该变量;
  • var()函数接受第二个参数,它指定了备用值。如果第一个参数指定的变量未定义,那么就会使用第二个值。
  • 如果var()函数算出来的是一个非法值,对应的属性就会设置为其初始值。

在样式表某处为自定义属性定义一个值,作为“单一数据源”,然后在其他地方复用它。

6.1 动态改变自定义属性

自定义属性的声明能够层叠和继承:可以在多个选择器中定义相同的变量,这个变量在网页的不同地方有不同的值。

首先在根元素的规则集中自定义属性,然后在不同作用域为同一个属性变量设置不同的值,会根据dom树按照就近原则继承该变量值,不同作用域的值互不影响。

6.2 使用JavaScript改变自定义属性

使用JavaScript在浏览器中实时访问和修改自定义属性。

  • 访问:

getComputedStyle(document.documentElement).getPropertyValue(‘—main-color’)

  • 修改

document.documentElement.style.setProperty(‘—main-color’, ‘#fff’)


利用这种技术,就可以用JavaScript实时切换网站主题,或者在网页中突出显示某些元素,或者实时改变任意多个元素。

6.3 探索自定义属性

在不支持自定义属性的浏览器上,任何使用var()的声明都会被忽略。请尽量为这些浏览器提供回退方案。但是当使用自定义属性的动态特性时,很难有回退方案。

七、总结

  • 拥抱相对单位,让网页的结构决定样式的含义。
  • 建议用rem设置字号,但是有选择地用em实现网页组件的简单缩放。
  • 不用媒体查询也能让整个网页响应式缩放,比如视口的相对单位,calc()计算公式等,来修改根元素的字号大小。
  • 使用无单位的值设置行高,有单位的继承是先计算再继承;无单位的是在子元素中重新计算值。
  • 请开始熟悉CSS的一个新特性:自定义属性(在作用域中使用前缀--声明变量,用var(变量名,备用值)使用值,可以用JavaScript访问和修改自定义属性)。
  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值