响应式布局和适配本质上都是为了让网站在不同设备显示不同的效果,但响应式是用一套css,然后通过断点或相对计算来匹配不同的设备,而适配则是直接写多个css,在js中判断设备尺寸并根据不同的设备引入不同的css文件
适配
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// 检测设备宽度,动态加载不同CSS
if (window.innerWidth < 768) {
loadCSS('mobile.css');
} else if (window.innerWidth < 1024) {
loadCSS('tablet.css');
} else {
loadCSS('desktop.css');
}
function loadCSS(href) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = href;
document.head.appendChild(link);
}
</script>
</head>
响应式布局
响应式布局主要有两大类:
- 绝对计算+为不同设备创建不同的效果
- 相对计算
绝对计算+为不同设备创建不同效果
使用框架断点或媒体查询必须要在标签中加上<meta name="viewport" content="width=device-width, initial-scale=1.0">用于让断点生效,因为浏览器默认是980px而不是按照物理设备的实际宽度,如果不加这个会让断点布局错乱
meta标签是元数据标签,即不会在页面显示但是会被浏览器,搜索引擎解析用来控制页面行为或提供额外信息
name 用于指定元数据名称,content则给出该名称对应的值,浏览器根据name的类型来解析content, name='viewport'表示控制移动端视口布局,content中width用来设置布局视口的宽度,device-width表示使用设备的物理宽度,initial-scale接收一个浮点数用来表示初始缩放比例,1.0表示不缩放
一.媒体查询
媒体查询的基本格式为
@media 媒体类型 连接词 媒体特征 {
该媒体下的css规则
}
css规则就是正常写的css,比如id为'mark'的元素希望他在平板上高度为10px,那么就在自己写的匹配平板的媒体当中写#mark{ height: 10px; },这样当浏览器检测到当前匹配这个媒体查询的时候就会匹配内外的相同的选择器,相同的属性会用里面的效果覆盖外面的默认效果,不同的属性则各自生效互不影响
媒体类型也可以不写,不写默认是all, 媒体特征也可以不写,任意组合即可
不同的媒体特征可以任意组合,比如width==1024px,min-width==1024px即宽度1024px的设备或最小宽度1024px的设备都能匹配上
媒体类型
媒体的类型由浏览器自动判断是否匹配
常见的媒体类型有:
- all : 默认,即所有的媒体类型都可以匹配,没定义媒体查询的默认效果就相当于是这个
- screen : 显示,即在屏幕上显示的时候匹配
- print : 即当前是要打印的时候或者打印预览的时候匹配
- speech : 即当前是语音设备输出的时候匹配(几乎不使用)
连接词
- and : 和,比如
@media (width==100px) and (height==150px)表示匹配宽度100px且高度150px的设备 ,: 或,比如@media (width==100px),(height==150px)- not : 非,否定当前查询条件,注意作用于整个条件但是不包括逗号后的,并且not后面必须显式的跟一个媒体类型,不能直接跟媒体条件,所以一般会加上一个all,比如
@media not print and (width==100px),(height==150px),表示匹配(不为(print且宽度为100px的设备))或者高度为150px的设备
媒体特征 : 必须写在括号中
媒体特征会由浏览器根据视口等条件自行判断是否匹配
特征由自己来定义,常用的有width / min-width / height等
常见断点:
@media (width<768px)是常见的手机尺寸@media (768px<=width<992px)常见的平板尺寸@media (992px<=width<1024px)常见的平板横屏@media (1024px<=width)常见桌面尺寸
二.框架(以TailwindCSS为例)
TailwindCSS的断点:断点尺寸均为最小宽度
- sm : 640px,适用于手机横屏或小尺寸平板
- md : 768px,适用于平板竖屏
- lg : 1024px,适用于小尺寸笔记本电脑
- xl : 1280px,适用桌面显示器
- 2xl : 1536px,适用大尺寸桌面显示器
相对计算
百分比计算
用百分比代替绝对单位保证布局的稳定性
注意相对计算不是相对于父元素而是相对于包含块
包含块:
- 普通流元素的包含块就是最近的块级祖先元素的内容边界(不包含padding)
- 根元素()的包含块通常是视口大小
- position为fixed,他的包含块默认是视口,但是如果有祖先元素设置了transform属性(即该属性不为none)那就相对于该祖先元素的内边距边界(包含padding)
- position为absolute,包含块默认是最近的position不为static的祖先元素或最近的设置了transform属性(即该属性不为none)的祖先元素的内边距边界(包含padding) ,这两个优先级一样
rem/em
rem: 根元素单个文字的尺寸
em: 父元素单个文字的尺寸
vh/vw/dvh/dvw/svh/svw/lvh/lvw
- vh/vw : 浏览器视口的高度/宽度为100vh/100vw
- dvh/dvw : 浏览器实际可视的视口的高度/宽度
- svh/svw : 最小视口高度
- lvh/lvw : 最大视口高度
他们之间的区别主要在于手机端的浏览器适配问题 : 手机端浏览器会有地址栏和底部导航栏,假设手机的屏幕是700px,地址栏和导航栏高度和100px
vh/vw的行为是会使用实际视口(即最大视口,也就是700px),但是这样由于浏览器会判断有一部分数据不可见,所以会渲染出滚动条
dvh/dvw的行为是会使用可见视口,也就是600px,但是当滑动的时候地址栏和导航栏隐藏可见视口变成700px了那他就会发生跳变
svh/svw的行为是会使用最小视口,并且即使地址栏隐藏后也不会改变,所以会有留白
lvh/lvw的行为是会一直使用最大视口
vmin/vmax/dvmin/dvmax/svmin/svmax/lvmin/lvmax
用法跟上面一样,不同的是不是按照视口的宽度或高度来去相对值,而是按照视口长边/短边来取值
这个一般用于适配横屏和竖屏
Grid/Flex
用弹性盒和网格布局保证不同设备下相对位置的稳定性