首页 前端知识 css 相对值的好处、em 和 rem,自定义属性(即CSS变量)

css 相对值的好处、em 和 rem,自定义属性(即CSS变量)

2024-04-29 12:04:50 前端知识 前端哥 830 374 我要收藏

相对值的好处

像素单位(px)是绝对单位,在哪里都一样大。 rem和em是相对单位,相对单位的值会根据外部因素发生变化。

c s s为网页带来了后期绑定的样式:直到内容和样式都完成了,二者才会结合起来。

那些年追求的像素级完美

网页设计者通过聚焦到‘像素级完美’的设计:通过创建一个紧凑的容器,通常是居中的一栏,大约800p x 宽,然后再像之前的本地应用程序或者印刷 出版物那样,在这些限制里面进行设计。(固定宽度的栏目设计)

像素级完美的时代终结了

**响应式 :样式能够根据浏览器窗口的大小有不同的响应。**这要求有意地考虑任何尺寸的手机,平板设备或者桌面屏幕。

像素、点、派卡:
css支持几种绝对长度单位,最常用,最基础的是像素(px)。不常用的绝对单位是 mm(毫米)、cm(厘米)、in(英寸)、pt(点,印刷术语,1/72英寸)、pc(派卡,印刷术语,12点)
公式换算:1in = 25.4mm = 2.54cm = 6pc = 72pt = 96px。因此 16px 等于12pt(16/96*72)

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

em 和 rem

em 是最常见的相对长度单位,适合基于特定的字号进行排版。在 css中,1em 等于当前元素的字号,其准确值取决于作用的元素

浏览器会根据相对单位的值计算出绝对值,称做计算值。

示例说明:

<div class="padded">hello world</div>
  body {
      font-size: 30px;
     }
     .padded {
         outline: 1px solid red;
         font-size: 18px;  
         padding: 1em;
     }

padding: 1em 中 是根据font-size进行相对大小

  • 如果当前class没有font-size值,继承父级font-size,若父级没有,直至继承根元素 font-size的值,根元素没有,即默认值(16px)浏览器默认值。
  • 如果当前class有font-size值,即根据当前font-size进行相对大小。

我们可以定义一个元素的大小,然后只需要改变字号 就能整体缩放元素。

示例:

<span class="box box-small">Small</span>
<span class="box box-large">Large</span>

.box {
    padding: 1em;
    border-radius: 1em;
    background-color: lightgray; 
}
.box-small {
    font-size: 12px;
}
.box-large {
    font-size: 18px;
}
// small : padding:12px  large : padding:18px

提示:如果知道字号的像素值,但是想用 em 声明,可以用一个简单的公式换算:**用想 要的像素大小除以父级(继承)的像素字号。**如果想要一个 16px 的字体,父级字 号为 12px,则计算结果是 16/12 = 1.3333em。对于大多数浏览器来说,默认的字号为16px.

使用 em 定义字号

谈到 font-size 属性是,em表现的不太一样。之前提过,当前元素的字号决定了 em, 但是,如果声明 font-size:1.2em.那么这个字号是根据继承的字号来计算的

示例:

We love coffee
<p class="slogan">We love coffee</p>

body {
    font-size: 16px;
  }
.slogan {
    font-size: 1.2em;// 1.2*16 = 19.2px
    padding: 1.2em;// 23.04px= 16*1.2*1.2
} 

在这个案例中显示:em的复杂之处在于同时用它指定一个元素的字号和其他属性。这时,浏览器必须先计算字号,然后使用这个计算值去算出其余的属性值。这两类属性可以拥有一样的声明值,但是计算值不一样。

字体缩小的问题

当使用em给列表元素定义字号并且多级嵌套时,就会产生意外的结果。文字缩小了。

示例:

<ul>
  <li>Top level
      <ul>
          <li>Second level
              <ul>
                  <li>Third level
                      <ul>
                          <li>Fourth level
                              <ul>
                                  <li>Fifth level</li>
                              </ul>
                          </li>
                      </ul>
                  </li>
              </ul>
          </li>
      </ul>
  </li>
</ul>

body {
	font-size: 16px;
}
 ul {
  font-size: .8em;
}// 这样会导致一层层*0.8然后就会越来越小

解决方案:

ul {
  font-size: .8em;
}
ul ul {
  font-size: 1em;
}
嵌套的列表应当跟其父级
的字号一致
使用rem设置字号

当浏览器解析HTML文档时,会在内存里将页面的所有元素表示为DOM(文档对象模型)它是一个树结构,每个元素都由一个节点表示。元素是顶级(根)节点。它下面是子节点, 和 ,再下面是逐级嵌套的后代节点。

在文档中,根节点是所有其他元素的祖先节点。根节点有一个伪类选择器(:root),可以用来选中它自己。:root == html,但是:root的优先级相当于一个类名,而不是一个标签。

rem 是 root em 的缩写。 rem 不是相对于当前元素,而是相对于根元素的单位。

:root {
	font-size: 1em; // root 伪类等价于类型选择器 html,使用浏览器的默认字号(16px)
}
ul {
	font-size: .8rem // 16px * 0.8 = 12.8px.相对根元素,所以所有字号都一样就算是嵌套列表也一样
}

可访问性:对字号使用相对单位;一般用rem设置字号,用px设置边框,用em设置其他大部分属性(尤其是内边距,外边距和圆角)

于em 相比,rem 降低了复杂性。实际上,rem 结合了 px和 em的优点,保留了相对单位的优势,又简单易用。

视口的相对单位

相对于浏览器视口定义长度的视口的相对单位

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

  • vh: 视口高度的1/100
  • vw:视口高度的1/100
  • vmin:视口宽,高中较小的一方的1/100(IE9中叫 vm, 而不是 vmin)
  • vmax:视口宽,高中较大的一方的1/100

例如:50vw 等于视口宽度的一半,25vh 等于视口高度的 25%。vmin 取决于宽和高中较小的 一方,这可以保证元素在屏幕方向变化时适应屏幕。在横屏时,vmin 取决于高度;在竖屏时,则取决于宽度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

使用vw定义字号

相对视口单位还有一个用途就是设置字号。

如果给一个元素加上 font-size: 2vw 会发生什么?在一个 1200px 的桌面显示器上,计算 值为 24px(1200 的 2%)。在一个 768px 宽的平板上,计算值约为 15px(768 的 2%)。好处是:元素能够在这两种大小之间平滑的过渡,这意味着不会在某个断点突然改变。当视口大小改变时,元素会逐渐过渡。24px 在大屏上来说太大了。更糟糕的是,在 iPhone 6 上会缩小到只有 7.5px。如果能够保留这种缩放的能力,但是让极端情况缓和一些就更棒了。CSS 的 calc()函数可以提供

使用 calc() 定义字号

calc()函数内可以对两个及其以上的值进行基本运算。当要结合不同单位的值时,calc() 特别实用。它支持的运算包括:加(+)、减(−)、乘(×)、除(÷)。加号和减号两边必须有空 白,建议大家养成在每个操作符前后都加上一个空格的习惯,比如 calc(1em + 10px)。

calc()结合了 em 和 vw 两种单位。删除之前样式表的基础字号(以及相 4 关的媒体查询),换成如下代码示例:

:root {
      font-size: calc(0.5em + 1vw);
}

现在打开网页,慢慢缩放浏览器,字体会平滑地缩放。0.5em 保证了最小字号,1vw 则确保 了字体会随着视口缩放。这段代码保证基础字号从 iPhone 6 里的 11.75px 一直过渡到 1200px 的浏 览器窗口里的 20px

不用媒体查询就实现了大部分的响应式策略。省掉三四个硬编码的断点,网页上的内容 也能根据视口流畅地缩放

无单位的数值和行高

  • 定义:有些属性允许无单位的值(即一个不指定单位的数)。
  • 支持属性包括:line-height、z-index、font-weight(700 等于 bold,400 等于 normal,等等)。
  • 任何长度单位(如 px、em、rem)都可以用无单位的值 0,因为这些情况下单位不影响计算值,即 0px、0%、0em 均相等

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

line-height属性比较特殊:既可以有单位也可以无单位

  • 优先使用无单位值:继承了无单位的值

使用无单位的数值时,继承的是声明值,即在每个继承子元素上会重新算它的计算值
我们可以用一个无单位的数值给body设置行高,之后就不用修改了,除非有些地方想要不一样的行高

body:{
	line-height: 1.2;// 后代元素继承了无单位的值
}
.about-us {
	font-size: 2em;
}
<p class="about-us">About us</p>

这个段落继承了行高1.2。因为段落字号是32px(2em × 16px,浏览器默认字号),所以此时行高的计算值为38.4px(32px×1.2)。每行文字之间都会有一个合理的间距。

  • 有单位的值定义行高:用有单位的值定义行高,会产生了意想不到的结果,导致行重叠
body {
	line-height: 1.2em; //后代元素继承了计算值(19.2px)
} 

.about-us {
	font-size: 2em; //计算值为32px 
} 

当一个元素的值定义为长度(px、em、rem,等等)时,子元素会继承它的计算值。当使用em等单位定义行高时,它们的值是计算值,传递到了任何继承子元素上。如果子元素有不同的字号,并且继承了line-height属性,就会造成意想不到的结果,比如文字重叠。

自定义属性(即CSS变量)

  • 自定义属性:叫做层叠变量的自定义属性
  • 声明一个变量,为它赋一个值,然后在样式表的其他地方引用这个值。这样不仅能减少样式表中的重复,而且还有其他好处

如果刚好用了内置变量功能的CSS预处理器,比如Sass或者Less,你可能就不太想用CSS变量了。千万别这样。新规范里的CSS变量有本质上的区别,它比任何一款预处理器的变量功能都多。因此我倾向于称其为“自定义属性”,而不是变量,以强调它跟预处理器变量的区别。

定义了一个名叫 --main-font的变量,调用函数var()就能使用该变量

:root {
	--main-font: Helvetica, Arial, sans-serif;
	--brand-color: #369;
}
p{
	font-family: var(--main-font);
	color: var(--brand-color);
}
p{
	font-family: var(--main-font, sans-serif);
	color: var(--secondary-color, blue);
	//因为--secondary-color是一个未定义的变量,所以使用了备用值blue。
}
  • 变量名前面必须有两个连字符(- -),用来跟CSS属性区分,剩下的部分可以随意命名
  • 变量必须在一个声明块内声明。这里使用了:root选择器,因此该变量可以在整个网页使用,
  • 变量声明本身什么也没做,我们使用时才能看到效果。将这个变量用到一个段落上,就会产生的结果。
  • var()函数接受第二个参数,它指定了备用值。如果第一个参数指定的变量未定义,那么就会使用第二个值。

说明如果var()函数算出来的是一个非法值,对应的属性就会设置为其初始值。比如,如果在padding: var(–brand-color)中的变量算出来是一个颜色,它就是一个非法的内边距值。这种情况下,内边距会设置为0。

动态改变自定义属性
//分别将背景色和文字颜色变量定义为白色和黑色
:root {
	--main-bg: #fff;
	--main-color: #000;
}
// 在面板样式中使用变量
.panel {
	font-size: 1rem;
	padding: 1em;
	border: 1px solid #999;
	border-radius: 0.5em;
	background-color: var(--main-bg);
	color: var(--main-color);
} 
.panel > h2 {
	margin-top: 0;
	font-size: 0.8em;
	font-weight: bold;
	text-transform: uppercase;
} 

//在容器内重定义--main-bg 和--main-color变量
.dark {
	margin-top: 2em;
	padding: 1em;
	background-color: #999;
	--main-bg: #333;
	--main-color: #fff;
}

在本例中,总共定义了自定义属性两次:

  • 第一次在根元素上(–main-color为黑色),
  • 第二次在深色容器上(–main-color为白色)。
  • 自定义属性就像作用域变量一样,因为它的值会被后代元素继承。
  • 在深色容器中,–main-color为白色,在页面其他地方,则是黑色。
使用JavaScript改变自定义属性
  • 使用JavaScript在浏览器中实时访问和修改自定义属性
<script type="text/javascript">
	var rootElement = document.documentElement;
	var styles = getComputedStyle(rootElement); //获取一个元素的styles 对象
	var mainColor = styles.getPropertyValue('--main-bg'); //获取styles对象的--main-bg值
	console.log(String(mainColor).trim());//确保mainColor是一个字符串,并去掉前后空格;打印结果为“#fff”
</script>
  • 可以实时改变自定义属性的值,所以可以用JavaScript为–main-bg动态设置一个新值
var rootElement = document.documentElement;
rootElement.style.setProperty('--main-bg', '#cdf');//将根元素上的--main-bg 设置为浅蓝色
  • 如果运行以上脚本,所有继承了–main-bg属性的元素都会更新,使用新的值。

利用这种技术,就可以用JavaScript实时切换网站主题,或者在网页中突出显示某些元素,或者实时改变任意多个元素。只需要几行JavaScript代码,就可以进行更改,从而影响网页上的大量元素。

探索自定义属性

  • 自定义属性是CSS中一个全新的领域,开发人员刚刚开始探索。因为浏览器支持有限,所以还没有出现“典型”的用法。
  • 值得注意的是,在不支持自定义属性的浏览器上,任何使用var()的声明都会被忽略。请尽量为这些浏览器提供回退方案。

回退方案

color: black;
color: var(--main-color);
转载请注明出处或者链接地址:https://www.qianduange.cn//article/6625.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!