响应式布局指的是同一个页面在不同大小屏幕下有不同的布局。
响应式与自适应的区别:响应式开发一套界面,通过检测视口分辨率,针对不同客户端在客户端做代码处理,来展现不同的布局和内容;自适应需要开发多套界面,通过检测视口分辨率,判断当前访问的是pc端,平板,手机,从而请求数据层,返回不同的界面。
1、媒体查询
媒体查询就是当浏览器窗口大小的改变时,页面也会根据浏览器的宽度和高度重新渲染页面。
超小屏幕(手机) | 小屏幕(平板) | 中等屏幕(桌面显示器) | 大屏幕(大桌面显示器) |
< 768px | >= 768px | >= 992px | >= 1200px |
媒体查询移动优先与 PC 优先的区别与联系
- 移动优先:从最小的屏幕开始媒体查询 ,有小到大;
- pc 优先:从大屏开始查询,由大屏到小屏。
无论那个,都是随着屏幕宽度增大或减小的时候,后面的样式会覆盖前面的样式。
移动端优先使用 min-width :
/*此项用以表示小于480px,屏幕的设置*/
@media (max-width: 480px) {
html {
font-size: 10px;
}
}
@media (min-width: 480px) {
html {
font-size: 12px;
}
}
@media (min-width: 640px) {
html {
font-size: 14px;
}
}
@media (min-width: 720px) {
html {
font-size: 16px;
}
}
PC端优先使用max-width:
/* pc优先时,此项不可去,用以表示更大的屏幕的设置 */
@media (min-width: 720px) {
html {
font-size: 18px;
}
}
@media (max-width: 720px) {
html {
font-size: 16px;
}
}
@media (max-width: 640px) {
html {
font-size: 14px;
}
}
@media (max-width: 480px) {
html {
font-size: 12px;
}
}
缺点:使用媒体查询的时候,分界点我们必须使用主流设备的宽度尺寸进行划分,这样一来在主流设备上展示效果良好,但是在另外一些设备上展示效果可能对用户不友好,而且在分界点改变布局的那一刻,布局会突然改变,给人的感觉很生硬。
2.百分比布局
百分比布局使得浏览器中组件的宽高随着浏览器的宽高的变化而变化,从而实现响应式布局。
- 子元素的 height、width,都是相对于直接父元素的高度和宽度;
- 子元素的 top、bottom 是相对于非 static 定位的父元素的高度;子元素的 left、right 是相对于非 static 定位的父元素的宽度;
- 子元素的 padding,、marigin 的百分比,不论垂直方向还是水平方向,都是直接相对于父元素的 width,与父元素的高度无关;
- 子元素的 border-radius、translate 的百分比,都是相对于自身的宽度。
/* pc width > 1100px */
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
aside {
width: 10%;
height: 100%;
background-color: red;
float: left;
}
main {
height: 100%;
background-color: blue;
overflow: hidden;
}
缺点:计算困难,如果要定义一个元素的宽高,根据设计稿,要换算成百分比单位;如果每个属性都使用百分比,但是有些属性参照的对象不一样,这样一来,就会造成百分比的布局变得很复杂。
3.rem布局
rem 是CSS3新增的单位,rem 单位是相对于根元素html的font-size来决定大小的,根元素的 font-size 相当于提供了一个基准,当页面的 size 发生变化时,只需要改变根元素; font-size 的值,那么以 rem 为固定单位的元素的大小也会随着发生响应式的改变。因此,如果通过 rem 来实现响应式布局,只需要根据视图容器的大小,动态的改变 font-size 的大小即可(em 同理)。
- em: 相对于父级元素的字体大小;
- rem: 使用rem为元素设定字体大小时,指的是相对于HTML根元素的字体大小。
<div class="box"></div>
<style>
* {
margin: 0;
padding: 0;
}
html {
font-size: 20px; //根元素的大小为20px
}
.box {
width: 5rem; //相对于根元素(HTML)的大小,5 * 20 = 100 px
height: 3rem; //相对于根元素(HTML)的大小,3 * 20 = 60 px
background-color: #ccc;
}
</style>
缺点:在使用 rem 布局时,必须要通过 js 来控制根元素 font-size 的大小,这样 js 和 css 就会有一定的耦合性,并且改变 font-size 的代码要放在样式之前。
4.视口单位
视口单位vw / vh,与视图的窗口有关,vw表示相对于视口的宽度,vh 表示相对于视口的高度:
单位 | 含义 |
vw | 相对于视窗的宽度,1vw等于视窗的1%,全部为100vw |
vh | 相对于视窗的高度,1vh等于视窗的1%,全部为100vh |
vmin | vw 和 vh 中的较小值 |
vmax | vw 和 vh 中的较大值 |
<div class="nav">
<div class="nav-item">
<i class="nav-icon iconfont icon-icon--"></i>
<span class="nav-text">私人FM</span>
</div>
<div class="nav-item">
<i class="nav-icon iconfont icon-calendar_icon"></i>
<span class="nav-text">每日推荐</span>
</div>
</div>
.nav {
width: 100%;
height: 12vh; // 相对于当前视口高度的12%大小
display: flex;
.nav-item {
flex: 1;
height: 100%;
.nav-icon {
margin: 1vh 4vw; //1vh 4vw代表相对于当前视口高度的1%,宽度的4%
width: 17vw; // 相对于当前视口宽度的17%大小
height: 17vw; // 相对于当前视口高度的17%大小
}
.nav-text {
display: inline-block;
width: 100%;
font-size: @font-size-small;
color: @color-text-g;
text-align: center;
}
}
}
虽然采用 vw 适配后的页面效果很好,但是它是利用视口单位实现的布局,依赖视口大小而自动缩放,无论视口过大还是过小,它也随着视口过大或过小,失去了最大最小宽度的限制,此时,我们可以结合 rem 来实现布局。
-
给根元素大小设置随着视口变化而变化的 vw 单位,这样就可以实现动态改变其大小;
-
限制根元素字体大小的最大最小值,配合
body
加上最大宽度和最小宽度。
// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
$vm_fontsize: 75; // iPhone 6尺寸的根元素大小基准值
@function rem($px) {
@return ($px / $vm_fontsize ) * 1rem;
}
// 根元素大小使用 vw 单位
$vm_design: 750;
html {
font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw;
// 同时,通过媒体查询限制根元素最大最小值
@media screen and (max-width: 320px) {
font-size: 64px;
}
@media screen and (min-width: 540px) {
font-size: 108px;
}
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
max-width: 540px;
min-width: 320px;
}
5.图片响应式
图片响应式:
1、大小自适应,能够保证图片在不同的屏幕分辨率下不会出现压缩或拉伸的情况;
2、根据不同的屏幕分辨率和设备像素比来尽可能选择高分辨率的图片,也就是在小屏幕上不用显示高清或大图,用小图代替,这样可以减少网络宽带。
使用max-width(图片自适应):
img {
display: inline-block;
max-width: 100%;
height: auto;
}
图片自适应就是图片可以随着容器的大小进行缩放。display: inline-block 设元素为内联元素,因为内联元素可以设置宽高,max-width 保证了图片随着容器改变进行改变,但是图片的宽度最大为自身宽度,如果包含图片的元素比图片的固有宽度小,那图片就缩放占满最大可用空间,而 height 为 auto 保证了图片等比缩放时不会失真。
使用background-image:
.banner{
background-image: url(/static/large.jpg);
}
@media screen and (max-width: 767px){
background-image: url(/static/small.jpg);
}
现在也有很多成型的解决方案,像 Flex 弹性布局,Grid 网格布局,Columns 栅栏布局等。