专栏首页程序员宝库移动端布局攻略

移动端布局攻略

作者:Tolonger 原文链接:https://www.jianshu.com/p/9e7e755ca281

除了百分比流式布局之外,rem布局占据了目前移动端布局的热潮。那么究竟这几种布局差别在哪里,对应的有什么效果,希望本文能给你一些有益的启示。除此之外还有响应式布局,固定宽度布局等。

百分比流式布局

这里面最知名的当属bootstrap框架的思路,他所有的组件以及模板ui均是百分比流式布局,单位为px.并且我们看到的大部分对移动端适配的页面也均是采用这种核心思想去做的,方法简单,多端共用,可以针对不同临界值做额外处理。比如百度,天猫,知乎,京东,微信一些文章等。所以无论怎么看,百分比流式布局都是一种常规+主流的布局方案。 核心原则:文字为流式布局,宽度100%按照屏幕宽度缩放,高度固定px,水平采用百分比,或者固宽+变宽,图片固定大小或者百分比缩放,辅助flex布局 。有使用的最大媒体查询临界值(一般为640)。 通过下图去理解下:

缺点:在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度还是和原来一样,实际显示非常的不协调,这就是流式布局的最致命的缺点

网易的rem布局

随着分辨率的增大,页面的效果会发生明显变化,主要体现在各个元素的宽高与间距。375680的比320680的导航栏明显要高。能够达到这种效果的根本原因就是因为网易页面里除了font-size之外的其它css尺寸都使用了rem作为单位,比如你看导航栏的高度设置代码:

header,footer{
height:.90rem;

}

网易页面上html的font-size不是预先通过媒介查询在css里定义好的,而是通过js计算出来的,所以当分辨率发生变化时,html的font-size就会变,不过这得在你调整分辨率后,刷新页面才能看得到效果。你看代码就知道为啥font-size是直接写到html的style上面的了(js设置的原因). 这样的话,每个页面中的宽高以及具体值只要除以100即可,而根节点的字号则是font-size=deviceWidth / 6.4,页面宽度如果是640px,则转换之后是6.4rem。需要注意的是,字号需要额外的媒体查询,而不是rem定的。

//字号单独用px即可 ,这里建议大家用变量定义小中大正常集中字号常量就可以,不用每次去针对具体样式做字号调整。
@media screen and (max-width:321px){
    .m-navlist{font-size:15px}
}

@media screen and (min-width:321px) and (max-width:400px){
    .m-navlist{font-size:16px}
}

@media screen and (min-width:400px){
    .m-navlist{font-size:18px}
}
//设置基本的字号,基本元素取材除100即可得到rem的大小,当然也可以用16px换算改变根字号为6.25rem即可。因为还有很大比例的手机设计为320的,所以这里考虑为640的。当屏幕大于640的时候,不再放大,让页面处于水平居中640px显示。
function fontAuto(){
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';
}
fontAuto();
window.onresize=function(){
fontAuto();
}

阿里rem布局

淘宝的效果跟网易的效果其实是类似的,随着分辨率的变化,页面元素的尺寸和间距都相应变化,这是因为淘宝的尺寸也是使用了rem的原因。在介绍它的做法之前,先来了解一点关于viewport的知识,通常我们采用如下代码设置viewport。

<meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:设备的物理分辨率/(devicePixelRatio * scale),在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。devicePixelRatio称为设备像素比,每款设备的devicePixelRatio都是已知,并且不变的,目前高清屏,普遍都是2,不过还有更高的,比如2.5, 3 等,魅族note的手机还有6p的devicePixelRatio就是3。淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置。js中可以通过devicePixelRatio拿到具体的设备数值。

1. 动态设置viewport的scale

var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

2.动态设置font-size

document.documentElement.style.fontSize =document.documentElement.clientWidth / 10 + 'px'; (3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10 (4)font-size可能需要额外的媒介查询,并且font-size不使用rem,这一点跟网易是一样的。

备注:你也可以通过阿里的现成的解决方案去实现,然后在预处理器中去处理px单位的字号<script src="http://g.tbcdn.cn/mtb/lib-flexible/%7B%7Bversion%7D%7D/??flexible_css.js,flexible.js"/>

@function s($px) {
    <a href="http://www.jobbole.com/members/wx1409399284">@return</a> ($px / 75) * 1rem;
}
p{
    font-size:s(40);padding-left: s(52);
}

美团rem布局

综合使用scale以及font-size的方案,更加简单。其中个元素的css尺寸为px/100,字号也使用rem作为单位。

//根据屏幕大小及dpi调整缩放和大小
(function() {
var scale = 1.0;
var ratio = 1;
if (window.devicePixelRatio >= 2) {
scale *= 0.5;
ratio *= 2;
}
var text = '<meta name="viewport" content="initial-scale=' + scale + ', maximum-scale=' + scale +', minimum-scale=' + scale + ', width=device-width, user-scalable=no" />';
document.write(text);
document.documentElement.style.fontSize = 50*ratio + "px";
})();

响应式布局

响应式这种方式在国内很少有大型企业的复杂性的网站在移动端用这种方法去做,主要原因是工作大,维护性难,所以一般都是中小型的门户或者博客类站点会采用响应式的方法从web page到web app直接一步到位,因为这样反而可以节约成本,不用再专门为自己的网站做一个web app的版本。

@media (max-width:768px){
    //css
}

备注 :响应式布局还可以根据设备宽度选择按需加载不同情况下的样式,可以加在样式link标签中。 <link rel="stylesheet" href="css/1.css" media="(max-width:500px)"/>

固定宽度布局

  • 主体页面固定宽度,两边留白。
.main{
width:980px;
margin:0 atuo;
 }

设置viewport进行缩放

仅仅靠这个实现适配是远远不够的,页面载入的时候会有缩放的情况,所以尽量使用rem等常规布局方式去做布局比较好。 如果你想使用这个方案,可以使用以下代码实现,针对部分安卓不适配进行了一定的修正。(这种方式还是px为单位)

function changeViewport(){
    // UI-width :WebApp布局宽度
    // device-width :屏幕分辨率宽度
    // target-densitydpi = UI-width / device-width * window.devicePixelRatio * 160;
    var uiWidth = 750,
        deviceWidth = (window.orientation == 90 || window.orientation == -90) ? window.screen.height : window.screen.width;
        devicePixelRatio = window.devicePixelRatio || 1;

    var myScale = deviceWidth / uiWidth;
    var targetDensitydpi = uiWidth / deviceWidth * devicePixelRatio * 160;
    //alert(uiWidth+","+deviceWidth+","+devicePixelRatio+","+myScale+","+targetDensitydpi);
    var viewportContent = "initial-scale=" + myScale + ", maximum-scale=" + myScale + ", minimum-scale=" + myScale + ',target-densitydpi=' + targetDensitydpi + ', width=device-width, user-scalable=no';
    //var viewportContent = "initial-scale=" + myScale + ", maximum-scale=" + myScale + ", minimum-scale=" + myScale + ', width=device-width, user-scalable=no';
    document.querySelector('meta[name=viewport]').attributes['content'].value = viewportContent;
}

window.addEventListener("orientationchange", function() {
    // Announce the new orientation number
    changeViewport();
}, false);
changeViewport();

媒体类型

@meida还可以根据媒体类型进行断点。

  • all,所有设备
  • print,打印
  • screen,彩色的电脑屏幕
  • speech,暂不了解

觉得本文对你有帮助?请分享给更多人。

本文分享自微信公众号 - 程序员宝库(chengxuyuanbaoku),作者:Tolonger

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-01-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用 Node.js 开发简单的脚手架工具

    像我们熟悉的 vue-cli,react-native-cli 等脚手架,只需要输入简单的命令 vue init webpack project,即可快速帮我们...

    程序员宝库
  • 48 条高效率的 PHP 优化写法

    能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率高于正则。

    程序员宝库
  • 码农也要学算法

    当“人工智能”、“AlphaGo”、“无人驾驶”、“智能投顾”等词语不断在人们视野中出现的时候,意味着我们正步入一个算法的时代。计算机通过提供给人类每天要面临的...

    程序员宝库
  • Python创建数字列表

    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 10 1 sum is : 55

    py3study
  • JcJc错别字纠错检查API说明

    JcJc错别字纠错检查API说明 JcJc错别字纠错检查1.0发布在即,先发布最新版本的API说明文档: 未来版本的改动,以Github为准, 项目地址: ht...

    田春峰-JCJC错别字检测
  • 《Springboot极简教程》系统异常全局统一处理:@ControllerAdvice plus @ExceptionHandler统一异常处理代码实例运行

    用@ControllerAdvice和@ExceptionHandler两个注解来做异常的统一处理。

    一个会写诗的程序员
  • Python中的map()、apply()和applymap()函数

    map()函数对序列args中的每个值进行相同的function操作,最终得到一个结果序列。

    数据医生
  • 亚马逊加入全球芯片大战,推出首款云端AI芯片

    终于,亚马逊也加入了全球AI芯片大战。今天凌晨,亚马逊在拉斯维加斯召开的AWS re:Invent大会上,亚马逊AWS CEO Andy Jassy发布了一系列...

    镁客网
  • 那些年培训总结的学习方法

    那些年培训总结的学习方法 不管培训机构本身怎么样,什么都是有好有坏;总是关注一些外在因素,既耗费精力,又劳累心态;不要忘记一件事,只有自己才能改变自己...

    奋斗蒙
  • python 学习日志(1)

    py3study

扫码关注云+社区

领取腾讯云代金券