1.流体布局
所谓的流体布局,就是用百分比来定义宽度,最外层容器的宽度设置为100%;
就可以适配不同的屏幕,子元素按照比例来设置百分比,子元素整体的百分比之和就是100%;
但是如果有子元素设置了边框,或者padding,那么整体的宽度就会大于100%,这时,我们可以将盒子的尺寸计算方式设置为从边框计算,通过设置:box-sizing:border-box,此时,盒子设置的宽度就是盒子的实际宽度,就没有这个问题了。
宽度解决了,高度如何设置呢?
一般的元素,高度可以固定不变,所以在屏幕变化时,我们可以看到元素的宽度变了,高度不变,但是对于图片,如果高度不同,图片就会被拉扁,此时我们可以将图片的宽度设为100%;它的宽度就由它的父级的宽度决定,图片的高度不设置,图片就会按照宽度变化等比例放大或缩小,这是图片的特性,这样就可以做到图片的适配了。 流体布局的伪代码如下:
* {
box-sizing: border-box;
}
.wrap {
overflow: hidden;
}
.banner {
overflow: hidden;
}
.banner img {
width:100%
}
.left_con {
width: 33.333333%;
height: 50px;
float: left;
}
.center_con {
width: 33.333333%;
height: 50px;
float: left;
}
.right_con {
width: 33.333333%;
height: 50px;
float: left;
}
2.响应式布局
响应式布局,就是使用媒体查询的方式,针对不同的屏幕,对应不同的样式;
但是移动端的屏幕很多种,如果要对应这么多套不同的样式,这样做也不现实,所以针对移动端,可以划分出三个屏幕宽度范围,在范围之内的,就使用同一套样式,这样定义三套样式就可以了,宽度的区间可以参照苹果手机的分辨率: 374px以下为第一个区间, 375px到413px为第二个区间, 414px以上为第三个区间,按照这个三个区间定义三套样式,在苹果手机上可以做到很好的适配,但对于一些其他分辨率的手机,可能会有一些不太适配的细节,但是这三套,应该基本上是适用了
// 大于等于375px尺寸样式
@media screen and (min-width: 375px) {
......
}
// 大于等于414px尺寸样式
@media screen and (min-width: 414px) {
......
}
3.弹性盒子布局
弹性盒子布局模型是一个新增的CSS布局模块,它带有流体布局和响应式布局的一些特性,而且它用少量的属性可以实现了多个元素的对齐方式,分布以及顺序等问题,用它能快捷高效的实现适配多终端的布局,这种模块简称为flexbox, flexbox布局模块的先后有三个版本,前两个版本的一些属性在最新的浏览器上已经得不到支持了,第三个版本在最新的浏览器上已得到广泛的支持。
Flexbox布局模块是CSS3新增的一些属性,这些属性分为容器属性和条目属性,容器和条目是这种模块里面的概念,指的其实就是父元素和子元素。父元素通过设置display:flex来声明flexbox模块、通过flex-flow来设置子元素排列方式、通过justify-content来设置元素的分布方式等等。而子元素通过flex属性来设置伸长或缩小比例、通过order来设置它在容器中的顺序等等。
.menu {
max-width: 800px;
height: 40px;
margin: 0 auto;
display: flex;
justify-content: flex-start;
align-items: center;
}
.menu-item {
flex: 1;
}
4.基于rem布局
rem是CSS3新增的一个单位,相对于em单位, rem的单位设置更加简单,它是相对于<html>根元素的的字体大小,其他的元素如果用rem来设置单位,它们对应的基准就是一样的,这样,在移动端适配中,除了html元素,其他元素的宽、高、行高、背景定位等等都用rem来设置,我们设定一个宽度作为基准,比如320px,然后按照这个基准,按比例来调节不同屏幕上对应的html元素的字体大小,就可以同步改变其他所有元素的用rem设置的尺寸的大小,这样就可以做到真正的按比例适配,不像流体布局,只能改变宽度,这种方式直接,高效,目前广泛应用在移动端布局中。
动态改变htm1标签文字大小的JavaScript如下
(function() {
var calc = function() {
var docElement = document.documentElement;
var clientWidthValue = docElement.clientWidth > 640 ? 640 : docElement.clientWidth;
docElement.style.fontSize = 20 * (clientWidthValue / 320) + 'px';
};
calc();
window.addEventListener('resize', calc);
})();
CSS样式设置伪代码如下:
.searchposition {
position: absolute;
right: 0.725rem;
top: 0.625rem;
width: 1.35rem;
height: 1.35rem;
background: url(../images/icons.png) left -31.97rem;
background-size: 2.9rem 33.5rem;
}
5.rem + vw适配
1》这里要认清三种视口
● visual viewport 视觉窗口,指屏幕宽度
● layout viewport 布局视口,指DOM宽度
● ideal viewport 理想窗口,使得布局视口就是可见视口即为理想视口
获取屏幕宽度(visual viewport)的尺寸:
window.innerWidth/Height
获取DOM宽度(layout viewport)的尺寸:
document.documentElement.clientWidth/Height
设置理想视口ideal viewport:
<meta
name="viewport"
content="width=device-width, // 宽度=设备宽度
user-scalable=no, // 用户可伸缩的=不
initial-scale=1.0, // 初始缩放=1
maximum-scale=1.0, // 最大缩放=1
minimum-scale=1.0"> // 最小缩放=1
总结方案:
方案一:百分比设置
因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一;
方案二:rem单位 + 动态html的font-size【推荐】
设计稿为375px
步骤1:设置为理想视口
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
步骤2:淘宝的移动端适配文件 lib-flexible
github上可下载
也可以直接复制下面的源码:
// lib_flexible 中的index.js文件是淘宝移动端适配文件
(function flexible(window, document) {
var docEl = document.documentElement
// 设备像素比
var dpr = window.devicePixelRatio || 1
// adjust body font size【翻译:调整正文字体大小】
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize【翻译:重置页面大小的rem单位】
window.addEventListener('resize', setRemUnit)
//在浏览器点击前进、后退时是不会刷新页面,会使用之前缓存的,所以是
//不会触发'resize' 事件,也就不会去重新计算rem,导致页面的元素大小
//不正确,所以需要通过 'pageshow' 事件,在前进、后退是再次触发'resize'事件
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports 【翻译:检测0.5px的支持】
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
步骤3:以下方式计算rem
方案1:手动计算
● 比如有一个375px屏幕上,100px宽度和高度的盒子;
● 我们需要将100px转成对应的rem值;
● 100 / 37.5 = 2.6667,其他也是相同的方法计算即可;
方案2:less/scss函数
方案3:postcss-pxtorem 插件
vue框架中 webpack会自带这个插件,自动完成rem转换,需要配置【暂无配置说明】
方案4:VSCode 中的 px to rem 插件
注意:需要点击设置指定的根元素的 font-size
设置
方案三:vw单位【推荐】
此方案:不需要使用 lib-flexible来动态设置html的 font-size了,更加方便【推荐】
方案1:手动计算
● 比如有一个375px屏幕上,100px宽度和高度的盒子;
● 我们需要将100px转成对应的vw值;
● 100 / 37.5 = 2.6667,其他也是相同的方法计算即可
方案2:less/scss函数
方案3:postcss-px-to-viewport-8-plugin 插件
和rem一样,webpack会自带这个插件,自动完成 vw转换,需要配置
方案4:VSCode 中的 px to rem 插件
设置