浅析em/rem/vw/vh与响应式布局
什么是em rem
em是一种相对长度单位,相对于自身元素的字号大小,如果没有设置字号,则继承父元素的字号大小。
rem是根元素的字号大小。
<h2>hello</h2>
<div></div>
/* 一般浏览器默认16px 那么默认html的font-size就是1em=16px*/
h2 {
/* 1.5em=1.5*16px=24px */
font-size: 1.5em;
}
html {
/* 此时 1em=24px */
font-size: 1.5em;
/* 由于此次设置了font-size 那么此时h2 的 1.5em 就是 36px */
}
body div {
/* 1em=24px */
font-size: 1em;
/* 从现在起忘记像素px */
/* width: 300px;
height: 300px; */
background-color: violet;
width: 10em;
height: 8em;
}
/* 缩小盒子 */
body div {
/* 此时 1em=12px */
font-size: .5em;
}
/* 放大盒子 */
body div {
/* 此时 1em=48px */
font-size: 2em;
}
/* 盒子的字号font-size使用了em,所有只需要设置font-size属性就可以控制盒子大小 */
应用 :用em制作一组响应式按钮组件
<button class="btn small">button1</button>
<button class="btn normal">button2</button>
<button class="btn larger">button3</button>
/* 基础样式 */
.btn {
background-color: #1e9fff;
color: #fff;
border: none;
outline: none;
padding: 0.5em 1em;
border-radius: 0.3em;
}
/* 伪类悬停 */
.btn:hover {
/* 透明度 0`1之间的值*/
opacity: 0.8;
/* 鼠标样式:将鼠标设置为手型 */
cursor: pointer;
box-shadow: 0 0 3px #888;
transition: 0.3s;
}
/* 如果想设置三个不同大小的按钮,只需要为这三个按钮指定不同的字号 */
.samll {
font-size: 10px;
}
.normal {
font-size: 16px;
}
.larger {
font-size: 24px;
}
简单理解:em是以自身font-size为基本单位;rem以html的font-size为基本单位
em实现响应式布局
<button>放大</button>
<div class="panel">
<h2>各种知名网站的404页面,看看谁更有创意?</h2>
<div class="panel-body">
<p>大厂的 404 页面都长啥样?看到最后一个,我笑了~
每天浏览各大网站,难免会碰到404页面啊。你注意过404页面么?下面这些知名网站的404页面,以供大家欣赏,看看哪个网站更有创意</p>
</div>
</div>
<style>
html {
font-size: 0.75em;
/* 后面可以直接用rem来引用12px来定义字号或者其他属性 */
}
.panel {
/* 此时panel 是 1rem=0.75em=12px */
/* 如果不写 默认字号是1个rem 1rem */
font-size: 1rem;
/* 此时如果panel中的其他属性使用em单位时就是12px;
如果panel的font-size:2rem;那么 此时的em就是24px;
也就是说em是本元素的其他使用属性使用em计算的基本单位
em会随着不同元素的设置而不同,rem始终等于html的font-size设置*/
padding: 1em;
border-radius: .5em;
/* 边框一定不要用em/rem,一定要用px */
border: 1px solid #999;
background-color: #eee;
margin: 2em;
}
.panel h2 {
/* 以后的字号,都要使用rem设置 */
font-size: 1.2rem;
/* 此时h2 字号就设置成了1.2rem=1.2*12px=14.4px
此时em=1.2rem=1.2*12px=14.4px */
margin: 1em;
}
.panel p {
font-size: 1.1rem;
text-indent: 2em;
}
/* 屏幕宽度 >= 800px ,字号放大14px */
@media screen and (min-width: 800px){
/* 14/16 = 0.875em */
html {
font-size: 0.875em;
}
.panel {
background-color: wheat;
}
}
/* 屏幕宽度 >= 1000px ,字号放大16px */
@media screen and (min-width: 1000px){
/* 16/16 = 1em */
html {
font-size: 1em;
}
.panel {
background-color: lightcyan;
}
}
/* 屏幕宽度 >= 1200px ,字号放大16px */
@media screen and (min-width: 1200px){
/* 20/16 = 1.25em */
html {
font-size: 1.25em;
}
.panel {
background-color: skyblue;
}
}
/* 扩展通过js动态增加时间控制字号大小 */
.panel.large {
font-size: 1.5rem;
}
</style>
<script>
document.querySelector('button').addEventListener('click',(ev)=>{
const panel = document.querySelector('.panel');
panel.classList.toggle('large');
if (panel.classList.contains('larger')) ev.target.innerHTML='缩小';
else ev.target.innerHTML = '放大';
})
</script>
总结
rem 和 em 单位是由浏览器基于你的设计中的字体大小计算得到的像素值。
em 单位基于使用他们的元素的字体大小。
rem 单位基于 html 元素的字体大小。
em 单位可能受任何继承的父元素字体大小影响
rem 单位可以从浏览器字体设置中继承字体大小。
使用 em 单位应根据组件的字体大小而不是根元素的字体大小。
在不需要使用em单位,并且需要根据浏览器的字体大小设置缩放的情况下使用rem。
使用rem单位,除非你确定你需要 em 单位,包括对字体大小。
媒体查询中使用 rem 单位
不要在多列布局中使用 em 或 rem -改用 %。
不要使用 em 或 rem,如果缩放会不可避免地导致要打破布局元素。
视口单位:vw/vh
视口:浏览器用于显示文档的可视区域
不包括地址栏,菜单栏,工具栏,状态栏
vh:视口的"初始包含块"的高度的百分之一(1/100)相对高度
vw:视口的"初始包含块"的宽度的百分之一(1/100)相对宽度
初始包含块:目前可以简单的理解为"html"
<div class="box"></div>
.box{
width: 50vw;
height: 50vh;
background-color: lightgreen;
margin:auto;
}
怎么获得一个正方形的区块呢?
.box{
/* 谁小以谁为标准 */
width: 80vmin;
height: 80vmin;
background-color: lightgreen;
margin:auto;
}
.box{
/* 谁大以谁为准 */
width: 80vmax;
height: 80vmax;
background-color: lightgreen;
margin:auto;
}
css原生变量
<a href="">hello</a>
body {
/* 2015年以后支持变量 */
--color:#f00;
--hover-color:#0f0;
--a-border:1px solid;
/* css预处理器,用js来编译css代码,less,sass用考拉来做
功能也比css原生变量强 */
}
a{
/* color:#f00; */
color:var(--color);
}
a:hover{
/* color:#0f0;
border: 1px solid; */
color: var(--hover-color);
border: var(--a-border);
}