我们最熟悉同时也是最简单的是 像素单位(px),它属于绝对单位,大小是固定的。
而其他单位,如em,rem等,这些属于 相对单位,相对单位的值会根据外部因素而发生变化。
CSS为网页带来了**后期绑定(late-binding)**的样式,即在内容和样式都完成城后,二者才会结合起来,这样带来的好处是一个样式表可以作用于成千上百个网页,开发人员也能直接改变渲染效果。
在web环境下,用户可以设置浏览器窗口的大小,还可以缩放网页,所以,不能在刚创建网页时就应用样式,而是要将网页渲染到屏幕上时,才能去计算样式。
同时,随着高清显示器及手机的发展,开发人员无法做到每个用户访问网站的体验都能一样,这时候得抛弃那种固定宽度的栏目设计,转向响应式设计。
响应式——在CSS中指的是样式能够根据浏览器窗口的大小有不同的“响应”。这要求有意地考虑任何尺寸的手机、平板设备,或者桌面屏幕。
em是最常见的相对单位长度,适合 基于特定的字号进行排版。CSS中,1em等于当前元素的字号,其准确值取决于作用元素。
.demo {
font-size:16px;
padding:1em;
}
上面的代码指定了元素的内边距为1em,浏览器将乘以字号(16px),最终渲染为16px。这一点很重要:浏览器会根据相对单位的值计算出绝对值,称作 计算值。
在设置padding,height,width,border-radius等属性时,使用em会很方便,这是因为当元素继承了不同的字号,或者用户改变字体设置时,这些属性都会跟着改变。
使用em定义字号时,font-size是根据继承的字号来决定的。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
body {
font-size: 16px;
}
.slogan {
/* 继承字号 16px*1.2=19.2px 等用于局部变量,影响padding值*/
font-size: 1.2em;
/* 继承字号 19.2px*1.2=23.04px */
padding: 1.2em;
}
style>
head>
<body>
We love basketball!
<p class="slogan">We love basketball!p>
body>
html>
上述例子中,slogan类从body中继承了16px的字号,最终计算字号为19.2px,因此19.2px是em的局部值(等同于局部变量),padding的声明为1.2em,此时是用19.2px这个当前字号乘以1.2,即为23.04px。
所以,在用em来指定多重嵌套的元素的字号时,会产生意外结果,如下段代码
元素嵌套时。
<head>
<style>
body {
font-size: 16px;
}
ul {
font-size: 0.8em;
}
style>
head>
<body>
<ul>
<li>Top level
<ul>
<li>Second level
<ul>
<li>Third level
<ul>
<li>Fourth level
<ul>
<li>Fifth levelli>
ul>
li>
ul>
li>
ul>
li>
ul>
li>
ul>
body>
我们给ul指定的字号时0.8em,但是由于
元素嵌套有相同元素,此时会导致下图结果
纠正这个问题,可以用以下代码,尽管解决了问题,但是方式不完美,因为刚设置一个值,立马又用另外一个规则覆盖。
ul {
font-size: 0.8em;
}
ul ul {
font-size: 1em;
}
综上所述,em在设置内边距,外边距以及元素大小时很好,但是如果在字号上就会变得很复杂,但是我们接下来会介绍一个好选择,rem。
当浏览器解析HTML文档时,会在内存里将网页的所有元素表示为DOM(文档对象模型)。他是一个树结构,其中的每一个酸雨都有一个节点来表示。元素是顶级(根)节点。
在文档中,根节点是所有其他元素的祖先节点。根节点有一个伪类选择器(:root),可以用来选中它自己,这等价于类型选择器html,但是html的优先级相当于一个类名,而不是一个标签。
rem是root em 的缩写。rem不是相对于当前元素,而是相对于根元素单位,不管在文档的什么位置使用rem,1.2rem都会有相同的计算值:1.2乘以根元素字号。
在这个例子里,根元素的字号为浏览器默认字号16px。无序列表的字号设置为0.8rem,计算值为12.8px。因为相对于根元素,所以即使嵌套结果也一样。
掌握CSS重要一点是在适当的场景下使用适当的工具,一般可以用rem设置字号,用px设置边框,用em设置其他大部分属性,特别是内边距、外边距和圆角。
停止像素思维,合理的运用em和rem,有时候很多人会把字号改变为html{font-size:.625em;}
,即把浏览器字号转变为10px,有利于后续的计算。这其实就是像素思维,10px对于大多数的浏览器过小,方便的同时却会让我们写更多重复的代码。
如果希望浏览器默认字号为14px,那么就不要将默认字号设为10px,然后再覆盖一遍,而是直接将根元素字号直接设置为想要的值,计算的方法为 想要的字号 / 浏览器默认 字号。如:14 / 16 = 0.875.
:root {
font-size:0.875em
}
以上代码把浏览器字号设置为了你想要的字号,那么就不用在其他地方再去指定一遍了,只需要根据相对它去修改其他元素就可以了。
案例:添加一个面板,用em设置内边距和圆角,用rem设置标题的字号,用px设置边框。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
:root {
font-size: 0.875rem;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.panel {
padding: 1em;
border: 1px solid #ccc;
border-radius: 0.5em;
}
.panel > h2 {
/* 取消 h2 默认顶部的外边距 */
margin-top: 0;
font-size: 0.8rem;
font-weight: 700;
text-transform: uppercase;
}
style>
head>
<body>
<div class="panel">
<h2>Single-originh2>
<div class="panel-body">
We have built partnerships with small farms around the world to
hand-select beans at the peak of season. We then carefully roast
in <a href="/batch-size.html">small batchesa> to maximize their
potential.
div>
div>
body>
html>
第二个选择器里的 > 是一个 直接后代选择器 ,他选中 .panel 的一个h2子元素,而不会选中在 .panel 类下其他子元素中的 h2。
我们可以用媒体查询改变根元素字号,这样就能够基于不同用户的屏幕尺寸,渲染出不同面板的大小。
媒体查询,即@media规则,使用 @media 查询,你可以针对不同的媒体类型定义不同的样式。@media 可以针对不同的屏幕尺寸设置不同的样式,特别是如果你需要设置设计响应式的页面,@media 是非常有用的。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。菜鸟教程,媒体查询定义、用法。
如果用rem设置字号,用px设置边框,用em设置其他大部分属性,特别是内边距、外边距和圆角。那么在媒体查询的过程中,只需改变默认字号大小,便可实现内边距和圆角等一系列的改变,这样可以极大的减少CSS代码中媒体查询的数量。
要实现一个组件部分显示不同的大小,那么可以加多一个large
类,改变里边的rem。
.demo {
font-size:1rem;
}
.demo .large {
font-size:1.125rem;
}
em和rem都是相对于font-size 定义的,但CSS里不止有这一种相对单位,如:视口的相对单位
视口——浏览器窗口里的网页可见部分的边框区域,他不包括浏览器的地址栏、工具栏、状态栏。
案例形成一个大正方形,不管如何缩放浏览器,他都能在视口中显示。
<head>
<meta charset="UTF-8">
<title>Documenttitle>
<style>
div {
width: 90vmin;
height: 90vmin;
background-color: salmon;
}
style>
head>
<body>
<div>div>
body>
html>
视口的相对长度非常适合展示一个填满屏幕的大图。
相对视口单位有一个不起眼的用途,就是设置字号,例如将字号设置为font-size:2vw
,那么它就能做到在不同的屏幕尺寸上实现平滑的过度,而不会像媒体查询那样在某个断点突然改变。
但是,在比较大的屏幕下,字体会变得过大或者过小,CSS的**calc()
函数**可以帮忙解决这一点。
calc()
函数内可以堆两个及以上的值进行基本的运算,加、减、乘、除,加号和减号两边需要有空白才能生效。
设置浏览器默认字号
:root { font-size:calc(0.5em + 1vw); }
有些属性允许 无单位的值,例如line-height、z-index、font-weight。
警告:一个无单位的0只能用于长度值和百分比,比如内边距、边框和宽度等,而不能用于角度值,比如长度,或者时间相关的值,比如秒
行高通常需要使用无单位的数值,否则会发生一些意想不到的错误。
声明变量的时,变量名前面要加两根连词线(--
),如下所示,代码定义了一个--main-font
的变量。
:root {
--main-font:Arial;
}
/*在p标签中使用自定义的变量,var()函数接受第二个参数,可设置备选值,如下段代码的sans-serif*/
p {
font-family:var(--main-font,sans-serif);
}