本篇非概念文章,分享一些我們在實際專案中遇到的障礙跟心得
以此文章適合閱讀的對象
施作RWD技術前,我們作了一些現況的調查,幫助了解現在開發要面臨的環境
了解瀏覽器的市佔率,可以幫助我們作技術上的選擇。特別標註IE8,是因為對前端來說,存在RWD的技術斷層,文章結尾會探討到IE8的支援度。
如果你像我們一樣,經營內容型網站,或是內容擴散的Event型活動,那就要了解有很多使用者是在FB APP中點開你的連結 。(也或許是Line或其他APP)
其中 Mobile Website Development and Design Course中Google的資深工程師有探討到幾個行動vs桌面網站的迷思:
了解市場趨勢後,讓我們來分別探討不同的解決方案
優點
ISSUE
優點
ISSUE
接著探討一些我在實作中遇到的問題
<meta name="viewport" content="width=device-width, initial-scale=1">
我們可能想針對不同的螢幕尺寸給予不同的viewport。下面程式碼示範,當螢幕大於640時,我們希望直接使用PC版的瀏覽器。
var meta = document.createElement('meta');
var w = screen.width;
if (w > 640) {
meta.setAttribute("name", "viewport");
meta.setAttribute("content", "width=960");
}
else {
meta.setAttribute("name", "viewport");
meta.setAttribute("content", "width=device-width initial-scale=1");
}
var s = document.getElementsByTagName('head')[0].children; s[s.length - 1].parentNode.insertBefore(meta, s[s.length - 1]);
initial-scale
要下,不然在某些狀況下,手機作橫版直版的轉換時,畫面會跑掉device-width
為特定寬度或是initial-scale
不等於一的狀態下,他不會等於screen.width(物理寬度)所以施作的時後最好搞清楚你要的東西到底是什麼。下面兩張圖分表展示了上段JS運作之後的狀態 iphone的解析度
ipad 因為我們強制指定width=960,所以我們會看到screen.width
取到了物理的相素大小,而window.innerWidth
取到的是CSS/虛擬的的相素大小
我們可以參考最多人在使用的前端框架,bootstrap3的作法,bootstrap3將裝備定議成四種大小,斜線右邊是這個大小下,其對應到的隱含設備(寬度跟其設備沒有絕對的關係)。
圖片來源)
這裡學習bootstrap3的方法示範一段使用less來操作Break points的方法
//變數
// Media queries breakpoints
// --------------------------------------------------
// Extra small screen / phone
@screen-xs: 480px;
@screen-phone: @screen-xs;
// Small screen / tablet
@screen-sm: 768px;
@screen-tablet: @screen-sm;
// Medium screen / desktop
@screen-md: 992px;
@screen-desktop: @screen-md;
// Large screen / wide desktop
@screen-lg: 1200px;
@screen-lg-desktop: @screen-lg;
// So media queries don't overlap when required, provide a maximum
@screen-xs-max: (@screen-sm - 1);
@screen-sm-max: (@screen-md - 1);
@screen-md-max: (@screen-lg - 1);
@screen-sm-min: (@screen-xs +1);
@screen-md-min: (@screen-sm +1);
@screen-lg-min: (@screen-md +1);
//===============================
//layout的斷點,用來打造GridSystem
//===============================
/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */
/* Small devices (tablets, 768px and up) */
@media (min-width: @screen-tablet) { ... }
/* Medium devices (desktops, 992px and up) */
@media (min-width: @screen-desktop) { ... }
/* Large devices (large desktops, 1200px and up) */
@media (min-width: @screen-lg-desktop) { ... }
//===============================
//用於較精準的定義
//===============================
@media (max-width: @screen-xs) { ... }
@media (min-width: @screen-sm-min) and (max-width:@screen-sm-max) { ... }
@media (min-width: @screen-md-min) and (max-width:@screen-md-max) { ... }
@media (min-width: @screen-lg-min) { ... }
一些常見的Media Querys 片段,其中還有針對一些常見的設備的特徵作詳細的定義方法,有別於max-width
利用max-device-width
取得物理尺寸作為更精準的設備參考(但感覺還是追不上市場速度)
PX、EM、%、PT 要搞清楚 這裡有個速查表
使用rem更方便控制,不必擔心em的複合計算行為(將EM跟PX的轉換化為十進制)。 rem參造root或html element,因此我們將html壓縮62.5%(default 16px)> 1rem = 10px ;
html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */
一般來說,我們會針對不同字型調整大小,是為了舒服的閱讀文字體驗,BUT!! 當專案的類型圖片吃重,圖文比例有要求,這時後需要借助一下Javascript
我們從設計那邊拿到的PSD大小是寬度604px的原始檔,我們可以將640px作為參考值,在不同的裝備大小下,去重新定義em的基準值。
(function ($) {
$.fn.rwdFitText = function (opts) {
// default configuration
var config = $.extend({}, {
opt1: null
}, opts);
// main function
function restFontSize(e) {
var rwdFont = function () {
if ($(window).width() <= 640 && $(window).width() > 320) {
var ration = 0;
if ($(window).width() >= 320) {
ration = $(window).width() / 640;
} else {
ration = 0.5; //用來控制最小縮放比率的數值
}
var fontScale = (ration * 100) * 0.625;
$('html').css('font-size', fontScale + "%");
} else if ($(window).width() > 640) {
$('html').css('font-size', "62.5" + "%")
}
};
$(window).resize(function () {
rwdFont();
});
rwdFont();
}
// initialize every element
this.each(function () {
restFontSize($(this));
});
return this;
};
// start
$(function () {
$("html").rwdFitText();
});
})(jQuery);
搜尋rwd font
的關鍵字,網路上可以找到不少相關的程式碼,有些細到可以定義每個DOM物件的最大值跟最小值,看得出來大家都有這些困擾。
要施作一個RWD,需要使用容器管理的概念,我在每個區塊中,在每個區塊中放入 container
與row
來管理我們的佈局
HTML結構
<body>
<nav class="nav">
<div class="container">
<div class="row">
</div>
</div>
</nav>
<section class="main">
<div class="container">
<div class="row">
<ul class="clearfix">
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div class="row">
</div>
</div>
</footer >
</body>
下列程式碼除了示範如何用container來約束網站內容在不同寬度裡的SIZE,另外我還利用了SCSS的Function快速產生一套Grids System 供查詢Grid寬度使用
SCSS
$break:640px;
$grid-width: 7.33333333333333%;//12grid
$gutter-width: 1%;
.clearfix{zoom:1;}
.clearfix:after{content:'.';display:block;clear:both;visibility:hidden;height:0;font-size:0;}
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
@media screen and (min-width: $break+1){
.container {
width:960px;
margin:0 auto;
}
}
@media screen and (min-width: 0) and (max-width: $break){
.container {
width:100%;
margin:0 auto;
}
}
//將 UL 中的所有 LI 設定為流體佈局中的三格寬
ul li{
width:grid-width(3);
float:left;
box-size:border;
border:1px solid #000;
}
有兩個版本,各有優缺點
background-position:背景大小減掉父層容層後的差集
<div class="box">
<div class="item"></div>
</div>
.box {
width:1000px;
height:100px;
}
.item {
background:url(w1000Xh100.jpg) no-repeat 10% 0;
background-size:90% auto;
// (1000(box) - 1000(item)) * 10% = 10 px
}
padding 跟 margin:比較特別的地方是,padding-top、padding-bottom、margin-top、margin-bottom 是參考父層寬度
使用Backgroun-size作使用圖片卻能伸縮的Sprite Button 實作方法是另用Padding-Bottom是參考其父層寬度的特性
簡述FB會遇到的狀況,之後我們會在擬一份PC VS 手機的FB功能替代方案給大家參考
我們使用的是Respond.js
實現原理
- 把head中所有
<link rel=“sheetstyle” href=“xx”/>
的css路径取出来放入数组- 然后遍历数组一个个发ajax请求
- ajax回调后仅分析response中的media query的min-width和max-width语法,分析出viewport变化区间对应相应的css块
- 页面初始化时和window.resize时,根据当前viewport使用相应的css块。
@function calculateRem($size)
$remSize $size / px
@return $remSize * 1rem
@mixin font-size($size)
font-size $size
font-size ulateRem($size)
//Usage
div {
@include font-size(px)
}
//Output
div {
font-size px //Will be overridden if browser supports rem
font-size rem
}
https://github.com/louisremi/background-size-polyfill
作用原理為截入.htc
檔並使用-ms-behavior: url(/backgroundsize.min.htc);
需要使用Background-size的群組屬性裡。他會使用背景圖片將IMG強制插入你的元素裡
HTML5 Cross Browser Polyfills https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
兼容速查
RWD的自動化測試是還要再研究,讓我們先了解一下DEBUG的方式
很多問題,可能要實際在手機的Broswer上才能Debug ,要注意的是IOS的Safari只能搭配OSX來Debug是個吃蘋果的好理由
Chorme的WebDeveloper最好用 = =
試過幾款Web工具發現在Viewport的模擬上跟真實都會有出入,而且在Windows中還可以摸擬TouchEvent跟3G環境也就沒有再找其他的
以上這兩種作法我們都有使用過,並沒有覺得哪個比較好,只能說看狀況
開放討論優先順序
RESPONSIVE REPORT 2014
http://2014.report.gridsetapp.com/
模範市場「Facebook 台灣消費者線上行為調查」
http://www.slideshare.net/yuanping/facebook-36279879
设备像素比devicePixelRatio简单介绍
http://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/
https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
font
http://www.w3schools.com/css/css_font.asp
http://zerosixthree.se/8-sass-mixins-you-must-have-in-your-toolbox/
http://www.kangting.tw/2014/04/rwd.html
http://snook.ca/archives/html_and_css/font-size-with-rem
css sprites button
http://blog.brianjohnsondesign.com/responsive-background-image-sprites-css-tutorial/
Media query ie8- 兼容实现总结 - 阿里妈妈MUX