網頁的縮放,適配以及移動的適配!
從佈局出發:寬度自適應,常用百分比的方式。由於父級元素採用百分比的佈局方式,隨著螢幕的拉伸,它的寬度會無限的拉伸。而子元素由於採用了浮動,那麼它們的位置也會固定在兩端。該寬度自適應在新的時代有了新的方法,隨著彈性佈局的普及,它經常被flex或者box這樣的伸縮性佈局方式替代,
1.rem
rem屬性指的是相對於根元素設定某個元素的字型大小。它同時也可以用作為設定高度等一系列可以用px來標註的單位。
瀏覽器的預設字型高度一般為16px,即1em:16px,但是 1:16 的比例不方便計算,為了使單位em/rem更直觀,CSS編寫者常常將頁面跟節點字型設為62.5%,比如選擇用rem控制字型時,先需要設定根節點html的字型大小,因為瀏覽器預設字型大小16px*62.5%=10px。
html {
font-size: 10px;
}
div {
font-size: 1rem;
height: 2rem;
width: 3rem;
border: .1rem solid #000;
}
採用以上寫法,div繼承到了html節點的font-size,為本身定義了一系列樣式屬性,此時1em計算為10px,即根節點的font-size值。所以,這時div的高度就是20px,寬度是30px,邊框是1px,字型大小則是10px;一旦有了這樣的方法,我們自然可以根據不同的螢幕寬度設定不同的根節點字型大小。假設我們現在設計的標準是iphone5s,iphone5系列的螢幕解析度是640。為了統一規範,我們將iphone5 解析度下的根元素font-size設定為100px;
html {
font-size: 100px;
}
/*
資料計算公式 640/100 = device-width / x 可以設定其他裝置根元素字型大小
ihone5: 640 : 100
iphone6: 750 : 117
iphone6s: 1240 : 194
*/
var deviceWidth = window.documentElement.clientWidth;
document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
接下來我們可以根據根元素的字型大小用rem設定各種屬性的相對值。當然,如果是移動裝置,螢幕會有一個上下限制,我們可以控制解析度在某個範圍內,超過了該範圍,我們就不再增加根元素的字型大小了.
一般的情況下,你是不需要考慮螢幕動態地拉伸和收縮。當然,假如使用者開啟了轉屏設定,在網頁載入之後改變了螢幕的寬度,那麼我們就要考慮這個問題了。解決此問題也很簡單,監聽螢幕的變化就可以做到動態切換元素樣式。
var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth;
document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
window.onresize = function(){
var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth;
document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
};
//為了提高效能,讓程式碼開起來更加完美,可以為它加上節流閥函式:
window.onresize = _.debounce(function() {
var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth;
document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
}, 50);
2.css--media query(媒體查詢)
運用css新屬性media query 特性也可以實現我們上說到過的佈局樣式。為尺寸設定根元素字型大小,但靈活性不高,取每個裝置的精確值需要自己去計算,所以只能取範圍值。考慮裝置螢幕眾多,解析度也參差不齊,把每一種機型的css程式碼寫出來是不太可能的。
常用於pc端的適配,比如常見的1024,1366等解析度。此種自適應佈局一般常用在相容PC和手機裝置,由於螢幕跨度很大,介面的元素以及遠遠不是改改大小所能滿足的。這時候需要重新設計整介面的佈局和排版了,與rem相比,最明顯的特點是直接可以改變佈局。
許多css框架經常用到這樣的多端解決方案,著名的bootstrap就是採用此種方式進行柵格佈局的。
@media screen and (device-width: 640px) { /*iphone4/iphon5*/
html {
font-size: 100px;
}
}
@media screen and (device-width: 750px) { /*iphone6*/
html {
font-size: 117.188px;
}
}
@media screen and (device-width: 1240px) { /*iphone6s*/
html {
font-size: 194.063px;
}
}
小結
1.如果只做pc端,那麼靜態佈局(定寬度)是最好的選擇;
2.如果做移動端,且設計對高度和元素間距要求不高,那麼彈性佈局(rem+js)是最好的選擇,一份css+一份js調節font-size搞定;
3.如果pc,移動要相容,而且要求很高那麼響應式佈局還是最好的選擇,前提是設計根據不同的高寬做不同的設計,響應式根據媒體查詢做不同的佈局。
場景1:1920的設計稿,需要在1024,1366等等主流解析度下適配(採用網頁等比例縮放)
常見的縮放有zoom和transform:scale兩種,兩者都具備縮放的功能,他們的區別如下
1.zoom支援的值型別有:
- 百分比值:
zoom:50%
,表示縮小到原來的一半。 - 數值:
zoom:0.5
,表示縮小到原來的一半。 - normal關鍵字:
zoom:normal
等同於zoom:1
.
注意,雖然Chrome/Safari瀏覽器支援了zoom
屬性,但是,其實zoom
並不是標準屬性。
2、CSS3 transform下的scale
而transform
下的scale
就不一樣了,是明明確確寫入規範的。從IE9+到其他現代瀏覽器都支援。語法為:transform: scale(<x> [<y>])
. 同時有scaleX
, scaleY
專門的x
, y
方向的控制。
和zoom
不同,scale
並不支援百分比值和normal
關鍵字,只能是數值。而且,還能是負數,沒錯,負數。而zoom
不能是負值!
3、zoom和scale更深層次的差異
控制縮放的值不一樣。zoom
更全面,但是不能是負數,只能等比例控制;而scale
雖然只能是數值,但是能負數,可以只控制1個維度。
- zoom的縮放是相對於左上角的;而scale預設是居中縮放;
- zoom的縮放改變了元素佔據的空間大小;而scale的縮放佔據的原始尺寸不變,頁面佈局不會發生變化;
- zoom和scale對元素的渲染計算方法可能有差異(如下截圖示意)。
- 對文字的縮放規則不一致。zoom縮放依然受限於最小12畫素中文大小限制;而scale就是純粹的對圖形進行比例控制,文字50%原來尺寸。
然後,還有一個肉眼看不見卻更重要的差異,渲染的效能差異明顯。
由於zoom的縮放會改變元素的真實空間大小,會影響其它的元素,在文件流中zoom
加在任意一個元素上都會引起一整個頁面的重新渲染,而scale
只是在當前的元素上重繪。即scale變化時其原本的尺寸是不變的,但zoom則會改變其原來尺寸。
我們要實現元素的縮放效果,可以使用CSS3 animation
, 但是存在這樣一種情況,就是元素原本就使用了一些transform
屬性進行,此時,再使用scale
進行animation
縮放,就會覆蓋原來的值,事情就會變得麻煩。
在移動端,大家也可以使用zoom
進行一些靜態內容的控制,可以避免為了scale
而佔有translate
, rotate
, skew
等公用的transform
屬性。
需要注意的是,Chrome等瀏覽器下,zoom/scale
不要同時使用,因為,縮放效果會累加。
下面是不改變整體佈局時進行的筆記本適配。將網頁進行整體縮放。效果相當於ctrl+滑鼠滾動j進行網頁的縮放,只不過這是通過計算比例,然後在具體的解析度下顯示縮放後的網頁(無需手動縮放),業務場景應該是希望內容一屏顯示,在不同的解析度下不希望出現滾動條。
function zoomhtml(){
var wid=$(window).width(),len;
if(wid<1600){
len=wid/1600;
$("html").css("zoom",len);
$("html").css({"-moz-transform":"scale("+len+")"},{"-moz-transform-origin":"0 0"});
}
};
zoomhtml();
場景2 :經常會遇到一些需求是頁面鋪滿整個螢幕,即:螢幕有多高頁面就有多高不能出現滾動條。
可用如下的方式解決
1.設定頁面viewport初始縮放為1
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
2.頁面結構如下;其中content為目標縮放容器
<body class="container">
<div class="main_content content">
</div>
</body>
3.js指令碼如下,需要放在頁面最底部
<script>
var clientWidth = parent.document.documentElement.clientWidth;
var clientHeight = parent.document.documentElement.clientHeight;
resize(clientWidth, clientHeight);
window.addEventListener('resize', resize(clientWidth, clientHeight));
function resize(docWidth, docHeight) {
var docScale = docHeight / docWidth,
designWidth = 375, designHeight = 667, els = document.querySelectorAll('.content'),
scale = docWidth / designWidth,
scaleX = docWidth / designWidth,
scaleY = docHeight / designHeight;
convertArray(els).forEach(function (el) {
extend(el.style, {
width: designWidth + 'px',
height: (docScale * designWidth) + 'px',
position: 'absolute',
top: 0,
left: 0,
transformOrigin: '0 0',
webkitTransformOrigin: '0 0',
transform: 'scale(' + scale + ')',
webkitTransform: 'scale(' + scale + ')',
overflow: 'auto',
webkitOverflowScrolling: 'touch'
});
});
}
function convertArray(arrayLike) {
return Array.prototype.slice.call(arrayLike, 0);
}
function extend() {
var args = Array.prototype.slice.call(arguments, 0);
return args.reduce(function (prev, now) {
for (var key in now) {
if (now.hasOwnProperty && now.hasOwnProperty(key)) {
prev[key] = now[key];
}
}
return prev;
});
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">
<title>測試頁面</title>
<style type="text/css">
div {
width: 600px;
text-align: center;
font-size: 4em;
color: #333;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(function() {
var r = document.body.offsetWidth / window.screen.availWidth;
$(document.body).css("-webkit-transform","scale(" + r + ")");
});
$(window).resize(function() {
var r = document.body.offsetWidth / window.screen.availWidth;
$(document.body).css("-webkit-transform","scale(" + r + ")");
});
</script>
</head>
<body>
<div>改變視窗大小試試,你會發現什麼?</div>
</body>
</html>
最後:
希望你看了文章有所收穫,歡迎交流!如有錯誤,歡迎指正!