您的位置:首页 > Web前端

指尖上行--移动前端开发进阶之路(读书笔记)----1.1页面布局

2017-11-29 16:09 288 查看
chapter 1 移动页面开发

页面布局

页面调试

常用库和框架

1.1 页面布局

[b]1.1.1 Vieport(视口,视图窗口)[/b]

设备像素

物理像素:屏幕分辨率;

设备独立像素:CSS像素(eg:IPhone5 CSS像素是320*568px)。

像素密度(PPI)

PPI = ( 屏幕分辨率宽的平方+屏幕分辨率高的平方 )开根号 / 4 (eg:IPhone5的PPI大于等于326)

根据Apple提出的定义,电脑显示屏PPI高于200,手持平板显示屏PPI高于260及移动电话显示屏高于300的屏幕都称为Retina屏幕。(但是可以通过另一数值来判断是否是Retina显示屏—-设备像素比DPR)

设备像素比(DPR)

DPR= 物理像素 / CSS像素

对于常规显示屏来说,物理像素和CSS像素比是1:1,但是在Retina屏幕设备中,一个CSS像素可能等于多个物理像素。



可以通过window的devicePixelRatio属性来获取当前设备的DPR:

<script>
var dpr = window.devicePixelRatio;
console.log('dpr-----' + dpr);
</script>


eg:IPhone6 设备物理像素:750px * 1334px,CSS像素:375px * 667px,DPR=2。(IPhone从4代开始基本就是2,IPhone Plus例外(DPR:3),而安卓设备,碎片化很严重,没有一个定值。)



3个Viewport

1 . Layout Viewport

默认的viewport,通过js的document.documentElement.clientWidth(Height)获取。

2 . Visual Viewport

在浏览器或者App的Webview中的可视区域,通过js的window.innerWidth(Height)获取。

3 . Ideal Viewport

IPhone4/4s/5/5s 320px(竖屏下宽度,下同)

IPhone6s 375px

IPhone6 Plus/6s Plus 414px

Android(大部分) 320px

visual viewport 就是当前显示给用户内容的窗口,你可以拖动或者放大缩小网页,来看清楚网页的内容。

layout viewport 有网页的所有内容,他可以全部或者部分展示给用户。

设置Viewport

在head标签中输入一下代码 (快捷键:meta:vp+tab键):

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">


Viewport可以用js进行动态的修改,以运用于一些特殊的项目中。

淘宝就是通过js的document.write方式设置viewport的

// 使用 document.write
<script>
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">')
</script>

// 使用 setAttribute
<meta id="viewport" name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
<script>
var vp = document.getElementById('viewport');
vp.setAttribute('content', 'width=300')
</script>


图片模糊问题

原因:在Retina显示屏等屏幕下,一个位图像素就对应了多个物理像素,这就导致位图像素的色彩值不够分,多出来的物理像素就近取色,导致图片模糊。( 当1个位图像素等于1个物理像素是,图片就是清晰的。当在高清屏幕中会用两个或多个物理像素来显示实际1px图片的内容。相当于把1px的图片放大显示了。)

解决(应该让图片大一点,然后在代码里缩小图片!):

将原本的尺寸放大一定的倍数,这个倍数便是参考DPR值。(大多数设备的DPR都是2,因此,我们将视觉稿放大两倍去设计即可。

压缩图标尺寸

(1)直接设置宽高压缩。(eg:图片实际大小是240px * 480px,那就在< img >标签中设置 width=120px; height=240px; 这样在移动端就清晰了。)

(2)通过设置background-size的方式来压缩(一般缩小一倍)。

[b]1.1.2 布局形式[/b]

传统页面布局(考虑Retina屏幕的内容清晰度,页面两边背景图留白问题)

滑屏页面布局(每一页都是全屏,百分比布局,设置html,body{height:100%;}使div的高度100%)

具体实现思路:

三层div。

第一层高度100%,设置overflow:hideen;。第二层设置高度1000%,等于10个屏幕的高度。第三层存放10个div,每一个div是一屏,高度为10%。

使用 js 监听 touchstart,touchmove,touchend事件。

[b]1.1.3 媒体查询[/b]

使用媒体查询

方式1:用link在 < head>外链样式表。

< link rel=”stylesheet” media=”screen and (max-width:320px)” href=”ip5.css”>

方式2:直接写入< head>的style里面。

@media screen and (max-width:320px) { background:#fff; }

媒体查询中的断点设置

*根据内容宽度设置( 根据设备宽度设置与内容宽度设置类似,不同之处在于 max-width设置断点为320px,360px,375px,414px,768px)

//css媒体查询:(根字体大小100px,如果10px大小,写成0.1rem)

html {
font-size : 100px;
}

@media only screen and (min-width: 320px) and (max-width: 479px){
html {
font-size: 42.67px !important;
}
}
@media only screen and (min-width: 480px) and (max-width: 639px){
html {
font-size: 64px !important;
}
}
@media only screen and (min-width: 640px) and (max-width: 749px){
html {
font-size: 85.34px !important;
}
}

@media only screen and (min-width: 750px) and (max-width: 959px){
html {
font-size: 100px !important;
}
}
@media only screen and (min-width: 960px) and (max-width: 1241px){
html {
font-size: 128px !important;
}
}

@media only screen and (min-width: 1242px){
html {
font-size: 165.6px !important;
}
}

//js控制(zepto / jQuery)(根字体大小100px,如果10px大小,写成0.1rem)

function setFont() {
let window_width = window.innerWidth;
let font_size = parseFloat(window_width / 3.75);
$(‘html’).css(‘font-size’, font_size);
}

$(window).on(‘resize’, function () {
setFont();
});


根据设备方向设置

@media screen and (orientation:portrait){ /*设置竖屏时的样式*/}
@media screen and (orientation:landscape){ /*设置横屏时的样式*/}


根据设备像素比设置

@media screen and (device-pixel-ratio:2){ /*设置设备像素比为2时的样式*/}


[b]1.1.4 屏幕适应[/b]

百分比布局

百分比布局非常适合移动端,能够很好地解决设备尺寸碎片化的情况,兼容性也非常好,而且元素的占比计算不会太复杂。

eg:设计宽度为640px,图片宽高为191px * 67px;(bg设置,而不是img标签)

图片在页面的百分比宽度width:191px / 640px =` 29.84%

图片在页面的百分比高度height:0.2914 * 67 /191 =` 10.47%

计算公式: W(元素当前百分比宽度)/ padding-bottom = 图片真实宽度 / 图片真实高度。

为什么使用padding-bottom?因为height和width的参考对象不同(height的备份比值是以父元素的高度参考计算的,但是在实际中,只有在父元素的高度是一个指定值时,子元素设置的百分比高度才会起作用,否则高度会被充值未auto,设置height没有太多的运用价值),height值无法实现等比例变化,而高度在完全使用padding-bottom或者padding-top撑起来。

CSS规范中,margin和padding的百分比值是以其自身父元素的宽度为基础进行计算的。CSS的默认排版的横向的,横向宽度会是一定的,纵向高度是可以无限延展的。

eg:一个div元素,宽300px,高度200px,其中包含子元素p,当p的CSS样式为margin:10%,p的margin-top/right/bottom/left分别为多少呢?按常规应该是20px,30px,20px,30px.

但真实值是30px,30px,30px,30px

当改变排版,给p的父盒子div设置-webkit-writing-mode-:vertical-lr; 即横向排版变成纵向。margin参考对象发生改变,从而以父元素的高度为基础进行计算,真实值为:20px,20px,20px,20px;

示例图







【左图为页面渲染结果;中、右图为盒子模型图 。】

左1:是横向排版margin10%,

左2:是竖向排版margin10%

左3:是横向排版margin-left:10px;

中:横向排版margin10%(左1)的盒子模型

右:竖向排版margin10%(左2)的盒子模型

验证margin参考对象遇到的坑———margin塌陷问题(以下是对margin的塌陷问题和外边距合并现象扩展):

场景:给div中的p设置margin:10%样式,按常规渲染应该出现如下图的样子。但实际情况却是上面的 左1图。 【div跟着p一起向下平移了!!】

大盒子包含一个小盒子,小盒子设置margin-top,大盒子会一起向下平移。这就是传说中的margin塌陷问题!

要强调的是外边距的塌陷问题只会在垂直之间产生塌陷;水平之间不受影响的;还有就是两个盒子的垂直外边距完全接触才会触发。

margin塌陷问题的原因:

在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。【对于有块级子元素的元素计算高度的方式,如果元素没有垂直边框和填充,那其高度就是其子元素顶部和底部边框边缘之间的距离。一个DIV和它的子DIV特别重视垂直边框或填充,也就好像是,一口锅,里面放个盆,能不能扣住里面的盆,主要看锅盖了,垂直边框或填充就是这个“锅盖”。】

margin-top是一个距离顶部多少像素的css样式,是用于两个盒子隔离边距用的,margin用于兄弟关系的盒子间距,而padding用于父子级的盒子间距。在编程上,这个其实是没有布好局导致的,需要注意布局方式层级关系。



外边距合并现象:

两个div上下拍咧,上div设置了margin-bottom,下div设置了margin-top,margin会合并,合并之后取较大的值作为两个div之间的间距。

margin外边距合并现象不需要解决,设置好值或者取其一即可。margin的塌陷问题是需要解决的,解决方法如下:

给大盒子(父元素)加一个边框border(border:1px solid transparent;或者border-top:1px solid transparent;)但是这样会改变盒模型和设计视图。不是很推荐,除非不影响页面整体效果。

给大盒子(父元素)设置一个overflow:hidden属性

浮动:float:left;

等等,触发BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。

BFC中的元素的布局是不受外界的影响。并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

浮动元素和绝对定位元素,非块级盒子的块级容器(eg: inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC。

缩放法

缩放的方式有 Zoom 和 transfrom:scale()两种

    1 . 支持的值类型不一样。Zoom:(百分比值)zoom:50%,表示缩小到原来的一半;(数值)zoom:0.5,表示缩小到原来的一半。zoom:normal 等同于zoom:1。

    而 scale 并不支持百分比值和 normal 关键字,只能是数值。但是能负数,可以只控制1个维度。

    2 . 相对缩放位置不一样。Zoom 的缩放是相对于左上角的;而scale默认是居中缩放;

    3 . Zoom 的缩放改变了元素占据的空间大小(缩放后容器所占据的空间是跟着一起缩放的);

     而 scale 的缩放占据的原始尺寸不变,页面布局不会发生变化(缩放后,容器所占据的空间仍不变,会出现空白区域。);

    4 . Zoom 和 scale 对元素的渲染计算方法可能有差异:zoom:0.5(锐利); transfrom:scale(0.5)(模糊);

    5 . 对文字的缩放规则不一致。Zoom 缩放依然受限于最小12像素中文大小限制;而 scale 就是纯粹的对图形进行比例控制,文字50%原来尺寸。

    6 . 渲染的性能差异明显。由于 Zoom 的缩放会改变元素的真实空间大小,在 dom 中 Zoom 加在任意一个元素上都会引起一整个页面的重新渲染,而 scale 只是在当前的元素上重绘。因为 scale 变化时候,其原本的尺寸是不变的,就没有 layout 的重计算;但是 Zoom 牵一发动全身。

//zoom
(function(fixWidth, id) {
var ele = document.getElementById(id);
function setZoom() {
var cliWidth = document.documentElement.clientWidth || document.body.clientWidth;
var blWidth = cliWidth / fixWidth;
ele.style.zoom = blWidth;
}
window.addEventListener('resize', setZoom, false);
setZoom();
})(640, 'wrap'); //wrap是页面最外层容器的id


监听resize事件,窗口大小改变的时候,运行setZoom,第一次运行的时候也设置一次。

setZoom函数先获取屏幕分辨率,然后通过设计稿来计算缩放比例。参数为(设计稿宽度640,页面最外层容器id);

优点:可以按照设计稿尺寸进行页面开发,页面自动个根据浏览器的分辨率进行缩放;

缺点:高度是随着宽度进行缩放比的,所以滑屏布局用缩放来做自适应并不是很有利。

Rem自适应:

通过js来控制根目录字号

(function() {
if(window.addEventListener)return;
var html = document.documentElement;
function setFont() {
var cliWidth = html.clientWidth;
html.style.zoom = blWidth;
}
document.addEventListener('DOMContentLoaded',setFont,false)
}
})();


rem vs Zoom ? 各有千秋 择需采用

Zoom兼容PC和移动端,但是某些情况下回因为缩放导致定位出现错乱,并且滑屏的浏览形式不适用。

rem是CSS3的单位,所以在移动端浏览器使用最优,滑屏的尺寸也是可以精确控制的。

模块和内容的自适应——适配方法

对于模块:

通过变化元素位置达到减少列数的目的,从而让内容以合适的尺寸显示,适应小屏幕设备。

通过隐藏或展开的方式对模块展示进行改变。

对模块尺寸进行放大或者缩小。

考虑增加或者删减模块的数量。

对于模块中的内容:

考虑挤压或拉伸内容容器的形状。

在内容排版上选择换行或者平铺。

和模块类似,对内容进行增加或者删减。

[b]1.1.5 内容排布技巧[/b]

视频与iFrame的自适应

计算公式: W(元素当前百分比宽度)/ padding-bottom = 4/3 或16/9 或 16/10

水平垂直居中

水平通过绝对定位和margin,对于行内使用text-align:center

垂直居中使用display:box;需要注意的是要带私有前缀:-webkit- -moz-
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息