布局形式
传统页面布局
demo:https://tgideas.qq.com/book/danceonfingers/chapter1/section1/px-demo.shtml###
设计稿都要大一倍,因为是按照pc端设计然后重构过来的
注意事项
视觉稿给的container限定在了640px,所以对于css来说 320px
滑屏设计
demo:https://tgideas.qq.com/book/danceonfingers/chapter1/section1/translateY.htm
滑屏切换,每向下滑都是一个全屏切换
难点:在移动端屏幕分辨率众多的情况下,如果低成本实现全屏?===> 百分比布局
设置wrap的宽高各为100%,宽度占据浏览器窗口,高度继承自父元素。而wrap的父元素高度默认是由内容填充,所以手动设置html、body高度为100%;
wrap2的高度是1000%,里面有10个page,10个page每个占高100%,由此实现全屏
同理如果是左右切换,那就wrap2宽度为1000%,然后page左浮动;
下面js解决问题:怎么每次滑都是全屏切换,无论用户实际滑了多少;
wap2设置了overflow:hidden屏蔽掉浏览器的默认滑动
思路:
1、touchmove:记录手指的位移,同时wrap2位置需要跟随位移改变
2、touchend:判断出手指的滑动方向,切换wrap2的整体滑动(<= transform:translateY(-100%);
媒体查询
使用media queries
媒体查询条件可以用and连接。
可以直接写在link里,也可以直接写入head的style里
当然除了screen媒体类型,还有其他
媒体查询的断点设置:
way1:根据设备尺寸设置(比较固定,这里的设备尺寸指的是ideal viewport
way2:根据页面内容尺寸设置(移动开发很少用,主要用在pc端页面适配多终端的工作中,因此断点具有业务性
way1:
优缺点:
way2:
举一些业务例子,理解一下怎么用就好
栗1
栗2
优缺点:
屏幕适应
参考:
[转]移动端适配方案:基于flexible库的成熟方案和基于vw的新方案
分享手淘过年项目中采用到的前端技术
way1:百分比布局:
思路:拿到设计稿,根据设计稿各个元素的宽高与设计稿宽度,计算出各个元素的宽度占比,再根据宽度占比反向计算出显示的高度,由此得到元素的css宽高。
然后移动端使用百分比布局,从而适配;
way2:缩放法
思路:直接按照设计稿的640px布局,然后动态获取浏览器的实际宽度和设计稿(640px)的比例,再对页面进行缩放。
缩放方式:zoom 或 transform的scale。推荐zoom
因为zoom:1、清新度更高;2、zoom缩放后容器所占空间也是跟着一起缩放的,而scale只缩放元素
way3:rem自适应
rem是动态单位,如果设置html字号为20px,那么1rem=20px,1.2rem=24px;
且rem单位可以作用于字号、width、margin、padding、radius等等
思路:将页面容器的所有元素都用rem为单位,即容器元素尺寸都以根元素为相对尺寸计算而来,我们根据浏览器分辨率动态调整各个元素大小的思路就转变为根据浏览器分辨率动态调整html的字号大小;由此实现牵一发动全身的省时做法;
难点: 设计稿的像素单位和rem的倍数单位 是什么关系呢?
比较:
rem与缩放法:
落地到实践上,做常用的:百分比+css媒体查询配合
demo1:图片列表(当iphone4/5时为两列显示,当iphone plus时是4列展示
https://tgideas.qq.com/book/danceonfingers/chapter1/section1/summary-piclist.shtml
图片列表常见于 商城应用
demo2:文字列表(百分比布局+固定尺寸配合
文字列表常见于新闻资讯板块
新闻左侧的分类标签[头条]和发布实践11/29是固定宽度,新闻标题是不固定宽度
典型的中间自适应两端定宽的布局;
百分比布局
<div class="wrapper">
<p>我是内容</p>
</div>
<style>
.wrapper {
width:300px;
height:200px;
}
.wrapper p {
margin:10%;
}
</style>
问:p的margin左右上下的实际像素值各位多少
==> 实际上都为30px
margin、padding的百分比宽度都是基于自身父元素的宽度计算。因为浏览器排版方式默认是从左到右,再从上到下,理论上高度是可以无限扩展的,是不可预知的。但是宽度却是一定的;
如果我们改变排版方式,那么margin也可以基于父元素的高度计算而来;
此外,还需要注意的是,宽高的百分比参考对象是不一样的
width的百分比是以父元素宽度参考计算,
height的百分比是以父元素高度参考计算,但是!实际上只有在父元素的高度为指定值的时候,子元素的百分比高度设置才会起作用,否则高度会被重置为auto
这有什么指导意义呢?
比如我们在一个网页里布局一张图片,图片需要百分比展示,假设设计稿中:
因为网页高度是无限的参考对象不同导致height无法实现等比例的变化,即图片的高度不可能由占比计算而来,我们的作用时根据宽度的占比计算出图片的显示高度像素值;
由此提炼出的最佳实践:
引申:你可能不知道的padding、margin用法
demo:https://tgideas.qq.com/book/danceonfingers/chapter1/section1/piclist.shtml
以padding撑开高度
缩放布局
rem自适应
demo:https://tgideas.qq.com/book/danceonfingers/chapter1/section1/rem.html
// 设置字体
(function (win,doc){
if (!win.addEventListener) return;
var html = document.documentElement;
function setFont(){
var cliWidth = html.clientWidth;
// 以设计图为750px为准 将页面分为100份 每份75px 所以 设计图的 某按钮 176px*176px == 2.3rem * 2.3rem
// 关于字体、内间距用rem 其余布局采用百分比
html.style.fontSize = 100 * (cliWidth / 750) + 'px';
}
win.addEventListener('resize',setFont,false)
doc.addEventListener('DOMContentLoaded',setFont,false)
})(window,document);
注意设置字号时避免小于12px
rem在使用雪碧图的定位上的解决问题:
rem是可以作用于background-position的,具体怎么使用rem偏移我们需要计算一下
思路:根据html字号大小和雪碧图的设计稿宽度,将雪碧图的background-size设置为rem为单位的,然后偏移的时候基于rem偏移
1、html:font-size=100px;
雪碧图实际宽度=100px;按钮在雪碧图位置:background-position:-50px -50px;
==>
雪碧图:background-size:1rem auto;
按钮:background-position:-.5rem -.5rem;
2、
假设按钮需要放大一倍,不必替换雪碧图,此时我们只需要更改size和position即可
雪碧图:background-size:2rem auto;
按钮:background-position:-1rem -1rem;
即按按钮的缩放比例去缩放雪碧图的尺寸和定位;
flexible方案
flexible方案是阿里早期开源的一个移动端适配解决方案,引用flexible后,我们在页面上统一使用rem来布局。
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
// 通过设置document.documentElement.style.fontSize就可以统一整个页面的布局标准
方法论:
1、通过监听页面resize事件控制根元素的字号大小
2、页面所有元素大小基于rem相对单位
具体值为多少?此时需要将UI出的图转换为rem
一般将ui出的物理像素图 转换为1px的设备独立像素单位,比如ui基于680px单位的手机设计出的按钮为100px,当我们设置了viewport使得css像素=物理像素后,我们将100px/dpr 得到100px的物理像素在设备比为3的机型上的设备独立像素大小。但,这只是粗略适配;
我们引入rem单位,使得适配更完美;
我们的思路转变为 将ui出的图换算为rem
以iPhone6
为例:布局视口为375px
,则1rem = 37.5px
,这时UI
给定一个元素的宽为75px
(设备独立像素),我们只需要将它设置为75 / 37.5 = 2rem
。
====》 每一个元素都自己计算那不是太麻烦了?我们可以借助PostCSS
的px2rem
插件。
由于viewport
单位得到众多浏览器的兼容,上面这种方案现在已经被官方弃用:
===》啥意思我去,建议大家开始使用viewport来替代此方案。
意思是只要设置了viewport就可以直接用px了?
对于750 x 1134 px的设计稿,Flexible会将视觉稿分成100份,1rem = 75px即<html>
对应的font-size
为75px:
图片,其尺寸是176px x 176px,转换成为2.346667rem x 2.346667rem。
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var px2rem = require('postcss-px2rem');
gulp.task('default', function() {
var processors = [px2rem({remUnit: 75})];// 基于750px的视觉稿传入此背景下的html字号
return gulp.src('./src/*.css')
.pipe(postcss(processors))
.pipe(gulp.dest('./dest'));
});
还有个关键问题,我们一般不会在字号上使用rem,文本等我们还是使用的px
只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小。
js获取dpr填在dom元素上,css设置不同dpr下元素的字号显示
div {
width: 1rem;
height: 0.4rem;
font-size: 12px; // 默认写上dpr为1的fontSize
}
[data-dpr="2"] div {
font-size: 24px;
}
[data-dpr="3"] div {
font-size: 36px;
}
封装成函数直接调用
@mixin font-dpr(@font-size){
font-size: @font-size;
[data-dpr="2"] & {
font-size: @font-size * 2;
}
[data-dpr="3"] & {
font-size: @font-size * 3;
}
}
div {
width: 1rem;
height: 0.4rem;
font-size: @font-dpr(12px); // 默认写上dpr为1的fontSize
}
vh、vw方案
现在最流行的vh、vw
方案vh、vw
方案即将视觉视口宽度 window.innerWidth
和视觉视口高度 window.innerHeight
等分为 100 份。
这个方案注意事项:
px
转换成vw
不一定能完全整除,因此有一定的像素差。- 比如当容器使用
vw
,margin
采用px
时,很容易造成整体宽度超过100vw
,从而影响布局效果。
此时推荐使用padding
代替margin
,结合calc()
函数使用等等…
如果视觉视口为750px
,那么1vw = 7.5px
,这时UI
给定一个元素的宽为75px
(设备独立像素),我们只需要将它设置为75 / 7.5= 10vw
。
同样我们可以使用 PostCSS的 postcss-px-to-viewport 插件帮我们完成这个过程,在代码中写px,打包时可用这个工具来将px转成vw
"postcss-px-to-viewport": {
viewportWidth: 750,
viewportHeight: 1334,
unitPrecision: 5,
viewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false
}
使用场景:
1、容器适配,可以使用vw
2、文本的适配,可以使用vw
3、大于1px的边框、圆角、阴影都可以使用vw
4、内距和外距,可以使用vw
排版设计
从设计角度讲讲针对不同设备页面中的模块和内容的分割、割舍、排版方式改变等等方式来适应设备
减少列数
隐藏或展开,常见于导航
放大与缩小,比如这里的轮播
增删模块,比如移动端去掉pc的下载按钮
特殊排布技巧
视频&iframe
demo:https://tgideas.qq.com/book/danceonfingers/chapter1/section1/video.shtml
解决方式也是采用百分比布局,如果不知道视频尺寸可以按照通用尺寸比例计算即可
传说中的等宽高比写法
参考
1、指尖上行
2、