CSS长度单位px、rem、em、vh、vw
px像素(Pixel)
px
是相对于显示设备(如电脑显示器、手机屏幕等)上的物理像素的单位,也就是屏幕上的一个物理像素点
一个 px
是屏幕上一个最小的显示单位,通常对应显示设备上的一个像素点
px相对长度单位是相对于显示器屏幕分辨率而言的
比如一般电脑的分辨率有1920*1024
等不同的分辨率,1920*1024
前者是屏幕宽度总共有1920个像素,后者则是高度为1024个像素
🍎优点
px
提供精确控制,在不同设备上可能表现不一致,特别是针对不同的屏幕分辨率和缩放设置
🍎缺点
无法自动响应设备的不同屏幕尺寸和分辨率,因此在响应式设计中不太灵活。
🍎设备独立像素DIP(Device Independent Pixel)与逻辑像素
想要理解 px
的工作原理,我们需要了解一些关于屏幕的物理特性和设备分辨率的知识
不同设备(如智能手机、电脑显示器、电视等)可能有不同的分辨率和屏幕大小,px
在不同的设备上可能表示不同的物理尺寸。为了解决这个问题,Web 浏览器将 px
映射为逻辑像素,也称为设备独立像素(DIP)。
设备独立像素(DIP)
是一个抽象的单位,用来在不同屏幕分辨率的设备间提供一致的尺寸表现。对于高分辨率设备(例如高清显示屏),Web 浏览器会把 px
映射成多个物理像素,以确保元素显示的尺寸一致。而在低分辨率设备上,浏览器会将 px
映射为更少的物理像素
🍎屏幕的 DPI 和 PPI
DPI(Dots Per Inch)
每英寸的点数,通常用于打印设备的分辨率描述。它表示每英寸显示的像素点数
PPI(Pixels Per Inch)
每英寸的像素数,通常用于显示设备(如手机、电脑显示器等)来表示屏幕的分辨率。
例如,如果一台手机的屏幕有 400 PPI,这意味着每英寸的屏幕上有 400 个像素点
🍎px
现代浏览器代表CSS 像素
px
在现代浏览器中通常代表的是CSS 像素 ,而非物理像素。浏览器会根据设备的像素密度(PPI)来调整 px
的实际显示尺寸。例如,iPhone 等高分辨率设备(Retina 屏幕)会将 1 CSS 像素映射为多个物理像素,以保证图像和元素的显示更细腻。
在标准屏幕(1x 屏幕密度)上,1 CSS 像素 = 1 物理像素。
在高清屏幕(2x 或更高的屏幕密度)上,1 CSS 像素可能会映射为多个物理像素。
例如,2x 屏幕密度的设备,1 CSS 像素 = 2 物理像素。
🍎设备显示因素
屏幕分辨率
设备的屏幕分辨率决定了显示的像素数量,分辨率较高的设备能在较小的显示区域内显示更多的像素
屏幕尺寸
不同设备的屏幕尺寸不同,但如果分辨率相同,屏幕尺寸越小,单位物理像素的实际显示尺寸就越小
反之,屏幕尺寸越大,单位物理像素的实际显示尺寸越大
设备像素比(DPR 或 Device Pixel Ratio)
设备的像素比决定了 px
的映射关系。
在 2x 屏幕上,1 CSS 像素可能会映射成 2 物理像素,这样显示内容就更细腻
低分辨率设备(例如,老式 LCD 屏幕,PPI = 100):
1 CSS 像素 = 1 物理像素
高分辨率设备(例如,Retina 屏幕,PPI = 300):
1 CSS 像素 = 3 物理像素(以设备像素比为 3 的设备为例)
rem
(root em)
rem
相对于根元素 (<html>
标签) 的字体大小来计算,通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。即1rem
等于根元素字体大小的值
🍎默认值
在浏览器中,默认的根元素字体大小通常是 16px
,所以 1rem
默认是 16px
🍎使用案例
javascript
html {
font-size: 16px; /* 1rem = 16px */
}
.element {
font-size: 2rem; /* 2rem = 32px */
}
🍎优点
调整根元素的字体大小,可以方便地缩放整个页面的布局,适用于响应式设计。
em
em
是相对单位,是相对于父元素的字体大小计算的
总结大概如下:
em元素字体大小的em是相对于父元素字体大小
em元素的width/height/padding/margin是相对于当前元素的font-size
🍎em使用font-size
如果用于某个元素的 font-size
,则 1em
是该元素父元素的字体大小
javascript
div {
font-size: 16px;
}
p {
font-size: 2em; /* 32px */
}
多个元素计算的时候
javascript
<div style="font-size: 16px;">
<p style="font-size: 2em;">这是一个字体大小为 32px 的段落</p>
<div style="font-size: 1.5em;">
<p style="font-size: 2em;">这是一个字体大小为 48px 的段落</p>
</div>
</div>
第一个 p
标签的字体大小为 2em
,相当于父元素 div
(16px)的两倍,即 32px
。
第二个 p
标签的字体大小为 2em
,但它的父 div
的字体大小是 1.5em
(相对于父 div
的字体大小),所以计算方式是 1.5em * 2 = 3em
,然后再计算这个结果相对于最外层 div
的大小。所以它的实际字体大小是 48px
🍎em使用width\padding
在 width
、padding
、margin
等属性中,em
的大小是相对于当前元素的字体大小来计算的,而不是父元素的字体大小
javascript
div {
font-size: 20px;
padding: 2em; /* 40px padding */
}
使用子元素的时候
javascript
div {
font-size: 20px;
}
p {
font-size: 1.5em; /* 30px */
padding: 2em; /* 60px padding */
}
vh\vw
(viewport weight/viewport height)
vh
是相对于 视口高度 的单位,1vh 等于视口高度的 1%
vw
代表 视口宽度 (viewport width),1 vw
= 1% 的视口宽度。100vw
代表视口的 100% 宽度,即浏览器窗口的整个宽度。
某些移动设备(如 iOS Safari)中,vh
可能会有一些兼容性问题,尤其是当浏览器地址栏隐藏时,视口高度可能会不准确
使用技巧
处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好
** 🍎**vh**
和 ****vw**
的计算和应用
视口尺寸
vh
和 vw
是相对于浏览器视口(即显示区域)的尺寸来计算的,而不是相对于父元素或其他容器的尺寸。因此,它们的值会随浏览器窗口的大小变化而动态调整
全屏背景
比如我们日常写一个全屏背景的
javascript
body {
margin: 0;
padding: 0;
height: 100vh; /* body 高度是整个视口的高度 */
}
header {
width: 100vw; /* header 宽度是整个视口的宽度 */
height: 50vh; /* header 高度是视口高度的 50% */
background-color: #333;
}
响应式字体大小
javascript
h1 {
font-size: 10vw; /* 字体大小是视口宽度的 10% */
}
居中布局
javascript
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80vw; /* 宽度为视口宽度的 80% */
height: 40vh; /* 高度为视口高度的 40% */
}
%
表示的是相对于父元素的尺寸(或某些情况下,视口的尺寸)计算的 % 是响应式设计中让网页在不同屏幕尺寸上自适应常用之一
🍎使用 % 设置宽度和高度 % 的宽度或高度值是相对于 父元素的宽度或高度 来计算的
javascript
.container {
width: 100%; /* 容器宽度占满父元素 */
}
.child {
width: 50%; /* 子元素宽度是父元素的 50% */
}
🍎% 设置 padding 和 margin padding 和 margin 的百分比值是基于 元素的宽度 来计算的,而不是父元素。
javascript
.box {
width: 200px;
padding-left: 10%; /* padding是基于盒子宽度的 10% 20px */
padding-top: 5%; /* padding是基于盒子宽度的 5% 10px*/
}
🍎使用 % 设置 font-size 使用 % 来设置字体大小时,值是基于父元素的字体大小 来计算的
javascript
div {
font-size: 16px;
}
p {
font-size: 150%; /* 字体大小是父元素字体大小的 150% 24px(16px * 1.5)*/
}
🍎使用 % 设置 position 定位 使用 position: absolute 或 position: relative 时,% 的值是相对于 包含块(parent element) 或 最近的定位元素 来计算的。
javascript
.container {
position: relative;
width: 500px;
height: 300px;
}
.box {
position: absolute;
top: 50%; /* 距离父元素顶部 50% */
left: 50%; /* 距离父元素左侧 50% */
transform: translate(-50%, -50%); /* 完全居中 */
}