モバイル開発およびPC側の開発は異なり、特にモバイル端末アプリケーションの起動年間で、予想外のさまざまな問題が発生する可能性があり、モバイルインターネットの急速な発展に伴い、いくつかの問題は、よくサポートされており、そのような1つの画素として国境問題。もちろん、より良いアドレスモバイル側に、我々はモバイル最後のフィールドの関連する知識を持っている必要があり、次のように語っています。
DPRデバイス画素比率
このDPR約最初の話だけで、終わりを移動するためにそこにPCの終了を持っていますが、一部の携帯端末が生成された問題の原因と解決策は、1ピクセルの問題として、より重要になってきます。いくつかの概念を初めて目:
物理像素(physical pixel)
物理的な表示画素は、各画素は、独自の物理的な色及び輝度の値を有し、表示装置に最小の物理的ユニットです。電話スクリーンiphone6例えば物理の750個の* 1334ピクセルであります
设备独立像素(density-independent
、独立したピクセルと呼ばれる独立した画素密度デバイスは、ポイント表示装置の座標系のように、それは理解できるで使用される論理画素、ダミー画素の画素CSS手順と呼ぶことができます。
设备像素比dpr(device pixel ratio)
デバイスピクセルよりも、DPRをいう、以下のように具体的な対応関係が算出される、物理デバイス独立の画素と画素との対応関係を定義します。
dpr = 物理像素 / 设备独立像素
DPRは、同じ値が両方DPR、一つの方向として、xまたはy方向を指す上記計算; DPR取得プログラム次のように
jsがDPRの使用を取得します
window.devicePixelRatio
使用CSSをGET DPR
-webkit-device-pixel-radio
IPhone6例えば、高い375 * 667デバイスの幅は、個々の画素(すなわち画素CSS)装置として理解することができる; 2であるDPR、に対応する各画素の次に、物理的な幅と高さ* 2、* 1334、すなわち750、論理ピクセルであります、x軸とy軸が2つの物理的なピクセルを表示するために必要とされる示すように、画像は、千の言葉の価値がある。
上述したラインからCSSが1ピクセル1ピクセルで、知ることができるリードモバイル設計の開発に、物理的なディスプレイ装置を意味するものではありません画素1ピクセルの設計の物理的な分割、CSSの値は、システム内の小さな値、低いバージョンアンドロイド(<= 4.4)とIOS(<= 8)であってもよいが、自動的に変換され、1 / DPRに変換しました共通の1ピクセルのピクセル問題の移動端で0;以下、具体的な解決策を与えます。
ビューポート
学生の移動側の開発は、以下のHTMLメタタグに精通してありました。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" >
これは、携帯端末を制御するために使用されviewport
た領域を示し、それらを理解する必要がある方法です。
理解ビューポート
PCのブラウザでは、こと、ビューポートは、実際にブラウザの表示可能領域であるが、モバイルデバイスの問題がより複雑になる上、ビューポートは、ブラウザの表示可能領域の大きさに限定されるものではなく、面積は、視覚ブラウザよりも大きくすることができますブラウザの表示領域よりも小さい。しかし、PCに比べて画面のモバイル側は、移動端末におけるPCのエンド設計のための通常の表示サイトの絞り込みすぎるので、ケース内のモバイルエンドデバイス上のデフォルトのビューポートは、ブラウザよりも大きくなるようにしています視野領域は、典型的な値は980px
他の値を有していてもよく、異なる装置に従って決定、ビジュアルブラウザよりもビューポート領域大きいため、ブラウザは、水平スクロールバーであろう。
ノートに二つのこと:
ビューポートのサイズに比べて幅のHTMLタグページ。
PC側は可視域のブラウザのビューポートのサイズで、デフォルトビューポートは、エンド980pxに移動され、カスタムのMETAタグに応じて設定すればよいです。
ビューポートの理論について、外国人の存在であるPPKこれは、特に彼らの書かれた3件の記事を参照して、より詳細な研究を行っている①、②、③。ビューポートが3つのレベルに分かれて理解されるであろう。
レイアウトビューポート
幅は、ブラウザの表示可能領域よりも大きいため、ブラウザの表示可能領域の幅よりも小さくすることができるよりも、レイアウトウィンドウ、真のビューポートページレイアウトは、それが大きくてもよい、ビューポートの(例えばデフォルトビューポートのビューポート980pxやカスタム設定など)のみその内容を表示するには、ブラウザのスクロールバーをスクロールすることもできます。
視覚的なビューポート
可視ウィンドウ、モバイルブラウザ可視領域の大きさ、幅、およびモバイルデバイスの表示画面の一定幅は、唯一の初期規模の場合に等しくなるようにスケーリングされました。
理想的なビューポート
理想化されたウィンドウには、固定されたサイズを有していないモバイルデバイスビューポートに最も適したモバイルデバイスの画面幅の幅を有します。ウィンドウを理想化次のページセットにかかわらず、画面の解像度の、ユーザーがズームする必要がなく、水平スクロールバーは、テキストのページ、画像などにぴったりのサイズをユーザに提示することを確実にするために、ウェブサイトのコンテンツを正しく表示することができます。
写真は、特定の違いを説明するために、いくつかのオンラインマップを借りて、千個の言葉の価値があります:
上記の二つの数字は、以下の2つの比較チャートを理解もされて、サイトのユーザーのための理想的なビューポートでの経験の重要性は、ユーザーが優れた経験の効果を得ることができ、スクロールやズームを持っていません。
制御ビューポートメタタグ付き
使用<meta name="viewport" content="xxx">
ビューポートのサイズは、最初にそのサファリブラウザのビューポートの目的にアップルが導入されて制御するためのタグは、モバイルデバイスの問題を解決することです。その後アンドリュース、主要なブラウザのベンダーは、ビューポートのサポートを導入し、追随してきました。
ビューポートmeta
次のようにページビューポートラベルのサイズを制御するには、特定の形式は次のとおりです。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" >
これはwidth=device-width
、それが、これはまた設定された特定の論理画素値、など980幅の広い装置をビューポートが設けられていることを示唆しています。
次のようにも単独で使用することが同時に使用されてもよい6つのプロパティの内容、の関連するビューポートメタタグ値も、組み合わせて使用してもよいです。
幅 | 設定layout viewport 幅は、正の整数であってもよいデバイス幅 |
---|---|
高さ | 設定layout viewport 幅はほとんど使用されません、正の整数であります |
初期の規模 | 初期スケール値は、一連のページで番号で、小数かもしれ |
最小規模 | ページの最小スケール値が、数値で、それが小数であってもよいです |
最大規模 | ページの最大スケーリング値は、数、10進数です |
ユーザースケーラブル | かどうかはページズームを可能にするために、される「いいえ」または「はい」は、無許可されていません、はい許可します |
ノートに二つのこと:
user-scalable=no禁止缩放在ios>=10系统的safari下有兼容问题,具体可以看禁止页面缩放meta标签兼容性问题这部分
meta属性中initial-scale的缩放是相对于
ideal viewport
来进行的
这样通过meta
标签很容易设置页面layout viewport为移动设备屏幕宽度(它也是ideal layout)即:
<meta name="viewport" content="width=device-width">
上面这种方式是最直接也是最轻易想到的设法,但是还可以使用initial-scale来达到同样的效果,即:
<meta name="viewport" content="initial-scale=1">
简单解释下,initial-scale
表示页面初始缩放值,其缩放是相对于ideal viewport的来说的,为1表示不缩放,那么其layout viewport的宽度就是ideal viewport的宽度,也就是移动设备屏幕的宽度。
既然二者都可以设置layout viewport的宽度,那么二者同时设置且值不相等会怎样呢?答案是:
浏览器会以二者中值较大的那个为准。
可能读者会有新的疑惑,在设置layout viewport为屏幕宽度时,经常看到的是二者都写上,为什么呢?答案是:
一个是兼容性的考虑,另一方面解决某些设备横竖屏不分导致通通以ideal viewport的宽度为准的问题
viewport的缩放
上面提到,meta中的initial-scale是相对于ideal viewport进行缩放的,该属性的作用:
initial-scale用来确定visual viewport即浏览器可视区域宽度大小
阿里早期的iphone/ipad下的自适应布局解决方案flexible
就是利用initial-scale来解决的。
有人可能会有疑问,移动端浏览器可视区域宽度不就是移动设备屏幕的宽度么?其实我们这里所说的可视区域宽度是逻辑意义上的宽度,而非实际真实的宽度,例如iphone4的320px屏幕宽度,initial-scale放大2倍,那么可视区域的逻辑大小变成了160px,可以通过查看页面html元素的宽度测试。
其实visual viewport与ideal viewport的关系如下:
visual viewport = ideal viewport / initial-scale
在iphone/ipad下,在没有指定initial-scale的情况下,无论你怎么设置layout viewport宽度,它会根据上面的计算关系,自动计算当前页面的inital-scale值以保证layout viewport宽度在缩放后就是浏览器可视区域的的宽度,即inital-scale = ideal viewport宽度 / visual viewport宽度(等于layout viewport宽度)。
例如,iphone6情况下默认的layout viewport为980px,那么当前缩放值inital-scale=375 / 980。
需要说明一下的是:在设置了initial-scale的情况下,这个自动计算的值就不起作用了。
移动适配方案
移动端设备不同,其屏幕大小也不尽相同,那么针对特定移动设备的页面设计ui怎么在不同移动设备上因设备不同而自适应屏幕展示呢。一般常见的解决方案有rem和vw/vh。下面就来说说。
rem适配
rem
是一个相对单位,相对于<html>
的font-size
来说的;那么参与页面布局的单位使用rem
而不是px,这样我们只需控制不同设备下网页<html>
的font-size
即可做到页面的自适应。
可以像flexible一样将移动屏幕宽度100等份,每份为a,同时1rem认定为10a;例如750px的设计稿来说,这样的话:
1a = 750px / 100 = 7.5px
1rem = 10a = 75px
实现代码如下:
(function (doc, win) {
var docEl =doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var width = docEl.getBoundingClientRect().width;
if (!width) return;
docEl.style.fontSize = (width / 100)*10 + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
recalc();
// hack兼容某些特殊机型
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
另外,我们也可以基于特定的设计稿尺寸来计算其他移动设备下的font-size,例如基于750px的设计稿,我们假设其font-size为40px,那么其他设备下font-size的计算关系式:
\[ 750/40 = 设备屏幕宽/fontsize \]
对应的核心转换代码即: docEl.style.fontSize = (width / 750)*40 + 'px'
VW适配
首先要知道vw和vh的概念代表什么,它也是相对单位,相对于屏幕的宽高而言的。
100vw = ideal viewport 宽
100vh = ideal viewport 高
跟rem类似,我们可以使用vw单位作为css的唯一单位,这样所有元素基于vw来布局;基于特定设计稿的尺寸来转换vw单位,我们使用stylus预编译函数来进行转换:
$vw_base = 375
vw(px) {
(px/$vw_base) * 100vw
}
然后无论是文本还是布局高宽、间距等都使用 vw 作为 CSS 单位,如
.container
padding: vw(15) vw(10) vw(10)
height: vw(40)
vw+rem结合适配
单纯的vw适配在视口缩放时尤其是缩小时有些小瑕疵,因为vw是利用视口单位实现的布局,依赖视口的大小而自动缩放,也就失去了最大最小的宽度限制。一种比较好的解决方法是使用vw与rem配合来进行适配,即:
页面需要适配的元素使用rem为单位,而的font-size值是根据vw来设定的,但是该font-size值需要限制最大最小值。
具体的stylus代码如下,也可以参考这个demo猛戳
$fontsize = 75 // 将屏幕分成10份
$base = 750 // iphone6 750作为基数
rem(px) {
(px/$fontsize) * 1rem
}
html
font-size: ($fontsize / $base) * 100vw //font-size以vw为单位
// 通过medai query限制根元素的最大值最小值
@media screen and (max-width: 320px) {// 页面宽度<=320时生效
font-size: 64px
}
@medai screen and (min-width: 540px) { // 页面宽度>=540时生效
font-size: 108px
}
媒体查询media query适配
通过类似如下形式来实现适配:
/* 大于1200px */
@media screen and (min-width:1200px){}
/* 大于等于960px,小于1200px */
@media screen and (min-width: 960px) and (max-width: 1199px){}
/* 大于等于768px,小于960px */
@media screen and (min-width: 768px) and (max-width: 959px){}
/* 大于等于480px,小于768px */
@media only screen and (min-width: 480px) and (max-width: 767px){}
/* 小于479px */
@media only screen and (max-width: 479px){}
该方式比较简单,成本低,但是代码量大,比较臃肿,维护不方便,不推荐该方式。
阿里flexible适配
该方案随着viewport单位
得到众多浏览器的兼容支持已逐渐不推荐使用了,它主要是为了解决iphone系列适配问题;虽然官方已不推荐使用,但是其思想还是值得借鉴学习的,主要表现下面三个方面:
根据
dpr
的值来修改<meta>
的viewport
的值实现移动端1px
的问题根据
dpr
的值来修改<html>
的font-size
值,使用以rem
为单位值来等比例缩放使用hack手段用
rem
模拟vw
特性
对应第一点,它通过hack手段来根据设备的dpr
值相应改变<meta>
标签中的viewport
的值:
<!-- dpr = 1-->
<meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no">
<!-- dpr = 2-->
<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">
<!-- dpr = 3-->
<meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no">
这样,iphone系统的不同设备下页面达到的效果是使css 1px像素与物理1px像素相同;然后,flexible使用rem作为布局单位实现适应布局。关键基本代码如下:
// 设置meta的viewport内容进行缩放
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
// 确定html的font-size值
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10; // 屏幕均分100份,每份为a,1rem为10a
docEl.style.fontSize = rem + 'px';
1px边框问题及解决方案
产生1px边框的问题其实归结三点:
1px的css逻辑像素不等于1px的物理像素
ios<8以及Android<=4.4以下的浏览器处理0.5px时会转化为0
对于1px边框问题的解决,flexible
能完美的解决,思路见上面分析的;除此之外还有什么方式,其实网上有很多方法,但是还是列一下思路:
用border-image来实现
使用一张图片来充当border,图片形式是3x3,如下:
.border { border-width: 1px; border-image: url(border.png) 2 repeat; }
缺点:改边框颜色时要修改图片,不灵活
用背景渐变来实现
设置1px的渐变背景,50%有颜色,50%透明
.border { background-image: linear-gradient(180deg, green, green 50%, transparent 0); background-size: 100% 1px; /* 背景宽度100%,高度1px */ background-repeat: no-repeat; background-position: bottom; }
缺点:维护过多代码,圆角没法实现
用box-shadow模拟边框来实现
.border { border: none; height: 100px; width: 100%; box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5); }
缺点:颜色不好处理,有阴影出现
用伪类+transform来实现
比较推荐的方法,原理是把原先元素的border去掉,然后利用
:before
或者:after
重做border,并把transform
的scale
缩小一半,原先元素相对定位,伪元素模拟的border采用绝对定位。.border { position: relative; border: none; } .border:after { content: ' '; position: absolute; left: 0; background: #666; width: 100%; height: 1px; tranform: scaleY(0.5); transform-origin: 0 0; }