HTML 響應式佈局
一 視口
移動前端中常說的 viewport (視口)就是瀏覽器中用於呈現網頁的區域。視口通常並不等於螢幕大小,特別是可以縮放瀏覽器視窗的情況下。手機端與PC端視口存在差異,電腦端的視口寬度等於解析度,而移動端的視口寬度跟解析度沒有關係,寬度預設值是裝置廠家指定的。iOS, Android基本都將這個視口解析度設定為 980px。
1、為什麼手機端視口要設為980px?
喬布斯設想:蘋果手機如果在市場上火爆了,但是各個網站還沒有來得及製作手機端網頁,那麼使用者不得不用手機訪問電腦版的網頁,如何用小螢幕訪問大螢幕的頁面也同樣可讀呢?喬幫主就想著為手機固定一個視口寬度,讓手機的視口寬度等於世界上絕大多數PC網頁的版心寬度,就是980px。這樣,用手機訪問電腦版網頁的時候,旁邊剛好沒有留白。不過頁面縮放後文字會變得非常小,使用者需要手動放大縮小才能看清楚,體驗非常差。
2.約束視口
為了解決前面的問題,可以在網頁的中新增下面這行程式碼:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
width=device-width 視口為裝置寬度(就是人設定的一個寬度)//不設定的話預設為980px
initial-scale=1.0 初始化的視口大小是1.0倍
maximum-scale=1.0 最大的倍數是1.0倍
user-scalable=0 不允許縮放視口
這個視口的標籤告訴瀏覽器怎麼渲染網頁。在這裡,標籤想表達的意思是:按照裝置的寬度(device-width)來渲染網頁內容。事實上,在支援這個標籤的裝置上給你看一看效果,你就明白了。
此時如果用document.documentElement.clientWidth來測試瀏覽器螢幕寬度,你會發現當前視口寬度等於手機螢幕的寬度,約數後的視口寬度都是在320~480之間(手機豎直使用的時候)。
這個視口的尺寸,是手機廠商設定的,能夠保證我們的文字比如16px,在自己的這個視口下清晰、大小剛剛合適。所以大螢幕的手機的約束視口 > 小螢幕手機的約束視口。這就能夠保證我們的網頁可以用px寫字號、寫行高。
需要注意的是:約束之後的視口寬度,不是自己的解析度!!每個手機的解析度,都要比自己的視口寬度大得多得多!
最最重要的一句話:前端開發工程師,絲毫不關心手機的解析度,我們只關心視口。
二、圖片
下面我們就在頁面上方新增一張鬆餅的圖片(2000畫素寬),效果類似引誘使用者往下看的大題圖。
它讓整個網頁看起來都失衡了,水平方向上圖片溢位了,可以用CSS給圖片指定固定寬度,但問題是我們想讓它能在不同大小的螢幕中自動縮放。比如,我們例子中的iPhone螢幕寬度為320畫素,如果我們把圖片設定成320畫素寬,那麼iPhone螢幕旋轉後又怎麼辦呢?這時候320畫素變成了480畫素。
解決方案很簡單,只要一行CSS程式碼就可以讓圖片隨容器寬度自動縮放:
img {
max-width: 100%;
}
回到手機上,重新整理頁面,結果比較符合預期了。
這裡宣告max-width規則,就是要保證所有圖片最大顯示為其自身的100%(即最大隻可以顯示為自身那麼大)。此時,如果包含圖片的元素(比如包含圖片的body或div)比圖片固有寬度小,圖片會縮放佔滿最大可用空間。
為什麼不用width:100%?
要實現圖片的自動縮放,也可以使用更通用的 width 屬性,比如width:100%。然而,這條規則在這裡並不適用。因為這條規則會導致它顯示得跟它的容器一樣寬。在容器比圖片寬得多的情況下,圖片會被無謂地拉伸。
三、手機瀏覽器核心
在移動端,僅有四個獨立的瀏覽器核心,分別為微軟的Trident、火狐的Gecko、開源核心Webkit、Opera的Presto。
目前微軟的Trident在移動終端上主要為WP7、8系統內建瀏覽器。Opera的Presto核心主要為 Opera Mobile、OperaMini、歐朋瀏覽器以及歐朋HD Beta版。Webkit核心的適用範圍則較為廣泛,Android原生瀏覽器、蘋果的Safari、谷歌Chrome(Android4.0使用)都是基於Webkit開源核心開發的。
相容的字首:
1 -ms-
2 -moz-
3 -o-
4 -webkit-
四、流式佈局
百分比佈局也叫作流式佈局、彈性盒佈局。手機網頁沒有版心,都左右撐滿。
百分比能夠設定的屬性是width、height、padding、margin。其他屬性比如border、font-size不能用百分比設定的。
- 如果用百分比寫width,那麼指的是父元素width的百分之多少。
- 如果用百分比寫height,那麼指的是父元素height的百分之多少。
- 如果用百分比寫padding,那麼指的是父元素width的百分之多少,無論是水平的padding還是豎直的padding。
- 如果用百分比寫margin,那麼指的是父元素width的百分之多少,無論是水平的margin還是豎直的margin。
- 不能用百分比寫border的寬度
接下來我們看一個例子:.
div{
width:200px;
height:300px;
padding:10px;
}
div p{
width:50%;
height:50%;
padding:10%;
}
此時p的真實寬度是多少?
此時p的真實寬度是140px*190px
五、媒體查詢
1.為什麼響應式 Web 設計需要媒體查詢
CSS3媒體查詢可以讓我們針對特定的裝置能力或條件為網頁應用特定的CSS樣式。如果沒有媒體查詢,光用CSS是無法大大修改網頁外觀的。這個模組讓我們可以提前編寫出適應很多不可預測因素的CSS規則,比如螢幕方向水平或垂直、視口或大或小等等。彈性佈局雖然可以讓設計適應較多場景,也包括某些尺寸的螢幕,但有時候確實不夠用,因為我們還需要對佈局進行更細緻的調整。媒體查詢讓這一切成為可能,它就相當於CSS中基本的條件邏輯。
2.媒體查詢語法
我們在媒體查詢外面寫的第一條規則,是“基本的”樣式,它適用於任何裝置。在此基礎上,我們再為不同視口、不同能力的裝置,漸進增加不同的視覺效果和功能。
body {
background-color: grey;
}
@media screen and (min-width:1200px){
body{
background-color: pink;
}
}
@media screen and (min-width:700px) and (max-width:1200px){
body{
background-color: blue;
}
}
@media screen and (max-width:700px){
body{
background-color: orange;
}
}
其中@media就表示媒體查詢,查詢現在看這個網頁的裝置是什麼,以及它的寬度是多少。screen表示看這個網頁的裝置是顯示器,而不是殘疾人聽力裝置、也不是印表機。後面用and符號羅列所有的可能性。
值得注意:媒體查詢只能包裹選擇器,不能包裹k:v對兒。
IE6、7、8不支援媒體查詢,也為了防止手機端的某些瀏覽器不支援媒體查詢,所以不要把所有的選擇器都放在媒體查詢裡面
六、rem響應式佈局
rem響應式佈局思想
- 一般不要給元素設定具體的寬度,但是對於一些小圖示可以設定具體寬度值
- 高度值可以設定固定值,設計稿有多大,我們就嚴格寫多大
- 所有設定的固定值都用REM做單位(首先在HTML中設定一個基準值:PX和REM的對應比例,然後在效果圖上獲取PX值,佈局的時候轉化為REM值)
- JS獲取真實螢幕的寬度,讓其除以設計稿的寬度,算出比例,把之前的基準值按照比例進行重新的設定,這樣專案就可以在移動端自適應了
什麼是rem,它與em有何區別
rem:當前頁面中元素的REM單位的樣式值都是針對於HTML元素的font-size的值進行動態計算的
em:表示父元素的字號的倍數。(特例:在text-indent屬性中,表示文字寬度)
body →font-size:20px;
<div class="box1"> → font-size:2em;
box1
<div class="box2"> → font-size:2em;
box2
<div class="box3"> → font-size:2em;
box3
</div>
</div>
</div>
.
em為單位的時候,font-size屬性是計算後繼承,box1計算出來是40px。那麼裡面的box2、box3繼承的都是40px。em單位不僅僅可以用來設定字號,還可以設定任何盒模型的屬性,比如width、height、padding、margin、border
rem有一點優勢就是可以和媒體查詢配合,實現響應式佈局:
@media screen and (min-width: 320px) {
html {font-size: 14px;}
}
@media screen and (min-width: 360px) {
html {font-size: 16px;}
}
@media screen and (min-width: 400px) {
html {font-size: 18px;}
}
運用場景
如果我們做的H5頁面只在移動端訪問,這是因為REM不相容低版本的瀏覽器。而如果移動端和PC端公用一套程式碼,建議使用流式佈局。
如何做個REM響應式佈局
1、從UI設計師拿到PSD設計稿,然後在樣式中給HTML設定一個font-size的值,我們一般都設定一個方便後面計算的值,例如:100px
html{
font-size:100px;//1rem=100px
}
2、寫頁面,寫樣式
首先按照設計稿的尺寸來寫樣式,然後在寫樣式值的時候,需要把得到的畫素值除以100計算出對應的REM的值。
值得注意的是:真實專案中外層盒子的寬度我們一般還是不寫固定值,沿用流式佈局法的思想,我們用百分比的方式佈局
margin:0 0.2rem
height:3rem;
3、根據當前螢幕的寬度和設計稿的寬度來計算我們HTML的font-size的值
例如:設計稿寬度為640px,其中有一個部分是輪播圖,它的尺寸是600*300,在樣式中給HTML設定一個font-size的值為100px,則輪播圖大小應該為 6rem×3rem,那如果手機螢幕寬度為375px,其font-size應該設定為多少。
375/640*100->fontsize=58.59375//此時輪播圖能自適應手機螢幕大小
根據當前螢幕寬度和設計稿寬度的比例,動態計算一下當前寬度下的fontsize值應該是多少,如果fontsize的值改變了,之前設定的所有REM單位的值自動會跟著放大或者縮小。可以通過以下這段程式碼實現:
<script>
~function(){
var desW=640,
winW=document.documentElement.clientwidth,
ratio=winW/desW;
document.documentElement.style.fontSize=ratio*100+“px“;
}();
</script>
但如果當前螢幕寬度大於設計稿寬度,圖片會被拉長而失真,所以以上程式碼需要稍微做些修改:
//html部分
<section id="main">
<div class="box"></div>
</section>
//js部分
<script>
~function(){
var desW=640,
winW=document.documentElement.clientwidth,
ratio=winW/desW;
var oMain=document.getElementById(“main“);
if(winW>desW){
oMain.style.width=desW+"px";
oMain.style.margin="0 auto";
return;
}
document.documentElement.style.fontSize=ratio*100+“px“;
}();
</script>