CSS3 媒體查詢與響應(yīng)式布局
第一章 序論
現(xiàn)今每天都有更多的手機(jī)和平板電腦問(wèn)市。消費(fèi)者能夠擁有可想象到的各種規(guī)格和形狀的設(shè)備,但是網(wǎng)站開(kāi)發(fā)人員卻面臨一個(gè)挑戰(zhàn):如何使他們的網(wǎng)站在傳統(tǒng)瀏覽器、手機(jī)和平板電腦瀏覽器上有很好的效果,如何在各種大小的屏幕上提供一流的用戶體驗(yàn)?
答案是:采用響應(yīng)式設(shè)計(jì)。
響應(yīng)式設(shè)計(jì)可以隨所顯示的屏幕大小而改變。實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)的主要方法是使用 CSS 媒體查詢。
Bootstrap的柵格系統(tǒng)就是通過(guò)媒體查詢來(lái)實(shí)現(xiàn)的。
第二章 回顧媒體類(lèi)型 media type
HTML4 和 CSS2支持根據(jù)媒體類(lèi)型(media type)加載。
比如,如果是'屏幕設(shè)備',則加載screen.css,如果是'打印設(shè)備',則加載print.css。
HTML4和CSS2 支持媒體類(lèi)型來(lái)決定使用CSS樣式,例:
<link rel="stylesheet" type="text/css" media="screen" href="sans-serif.css">
<link rel="stylesheet" type="text/css" media="print" href="serif.css">
我們同樣可以在CSS樣式表中,聲明條文適用于某些媒體類(lèi)型。
@media screen {
* { font-family: sans-serif }
}
可以在使用@import導(dǎo)入CSS時(shí)使用媒體查詢,有條件地向當(dāng)前樣式表中加載其他樣式表。
@import url("serif.css") screen;
print和screen媒體類(lèi)型是HTML4中定義的.
HTML4定義的媒體類(lèi)型如下:
- screen 屏幕
- print 打印機(jī)
- all 所有
- aural 聲音
- braille 盲文
- handheld移動(dòng)設(shè)備
- projection 投影儀
- tty 打字機(jī)
- tv 電視
- embossed 盲文打印
令人尷尬的是,除了前3種類(lèi)型,剩下的幾乎沒(méi)人用,實(shí)際已經(jīng)廢棄了.
第三章 媒體查詢 media query
媒體查詢是評(píng)估 True 或 False 的一種表達(dá)。如果為 True,則繼續(xù)使用樣式表。如果為 False,則不能使用樣式表。這種簡(jiǎn)單邏輯通過(guò)表達(dá)式變得更加強(qiáng)大,使我們能夠更靈活地對(duì)特定的設(shè)計(jì)場(chǎng)景使用自定義的顯示規(guī)則。
媒體查詢(media query)則根據(jù)媒體類(lèi)型(medir type)和由媒體特征(media features)值組成的表達(dá)式.
媒體特征值如: width , height,color,即寬,高,色彩等.
共有13種特征(重點(diǎn)記住前3種) , 如下:
| 設(shè) 備 特 性 | 是否允許 min/max 前綴 | 特 性 的 值 | 說(shuō) 明 |
|---|---|---|---|
| width | 允許 | 含單位的數(shù)值 | 指定瀏覽器窗口的寬度大小, 如480像素 |
| height | 允許 | 含單位的數(shù)值 | 指定瀏覽器窗口的高度大小, 如320像素 |
| orientation | 不允許 | 字符串值 | 指定移動(dòng)設(shè)備瀏覽器的窗口方向。 只能指定portrait(縱向)和landscape (橫向)兩個(gè)值 |
| device-width | 允許 | 含單位的數(shù)值 | 指定移動(dòng)設(shè)備的屏幕分 辨率寬度大小,如480像素 |
| device-height | 允許 | 含單位的數(shù)值 | 指定移動(dòng)設(shè)備的屏幕分 辨率高度大小,如320像素 |
| aspect-radio | 允許 | 比例值 | 指定移動(dòng)設(shè)備瀏覽器窗口的 縱橫比例,如16:9 |
| device-aspect-radio | 允許 | 比例值 | 指定移動(dòng)設(shè)備屏幕分辨率的 縱橫比例,如16:9 |
| color | 允許 | 整數(shù)值 | 指定移動(dòng)設(shè)備使用多少位的顏色值 |
| color-index | 允許 | 整數(shù)值 | 指定色彩表的色彩數(shù) |
| monochrome | 允許 | 整數(shù)值 | 指定單色幀緩沖器中每像素的字節(jié)數(shù) |
| resolution | 允許 | 分辨率值 | 指定移動(dòng)設(shè)備屏幕的分辨率 |
| scan | 不允許 | 字符串值 | 指定電視機(jī)類(lèi)型設(shè)備的掃描方式。 只能指定兩種值:progressive表 示逐行掃描和interlace表示隔行掃描 |
| grid | 不允許 | 整數(shù)值 | 指定設(shè)備是基于柵格還是基于位圖。 基于柵格時(shí)該值為1,否則為0 |
第四章 媒體查詢實(shí)戰(zhàn)
@media screen and (width: 600px){
body {
background: gray;
}
}
上例指,對(duì)于屏幕且瀏覽器寬600px像素時(shí),啟用指定的css.
縮放瀏覽器試一下, 當(dāng)瀏覽器窗口恰好是600px寬時(shí),背景變灰.
上例中的媒體查詢不是很實(shí)用,因?yàn)閷挾惹『?code>400px像素的條件太苛刻.
在實(shí)戰(zhàn)中,用范圍表達(dá)寬度更普遍.
@media screen and (min-width: 600px){
body {
background: gray;
}
}
上例指:對(duì)于屏幕且最小600寬(>=600px)的瀏覽器時(shí),啟用指定的css.
拖動(dòng)瀏覽器試一下?
同時(shí),打印預(yù)覽再看一下背景色,想一想為什么?
@media (orientation:portrait){
body {
background: gray;
}
}
@media (orientation:landscape){
body {
background: blue;
}
}
上例中,指屏幕height>width時(shí),如手機(jī)豎直時(shí),和屏幕width>height,如手機(jī)橫放時(shí),啟動(dòng)指定的css。
在針對(duì)所有設(shè)備的媒體查詢中,可以使用簡(jiǎn)寫(xiě)語(yǔ)法,即省略關(guān)鍵字all(以及緊隨其后的and)。換句話說(shuō),如果不指定關(guān)鍵字,則關(guān)鍵字就是all。
第五章 復(fù)雜表達(dá)式
媒體查詢表達(dá)式還可以更復(fù)雜。
5.1 and聯(lián)查
在表達(dá)式中,我們可以根據(jù)自己的喜好和需求使用任意數(shù)量的 and 條件。如果想要增加其他條件來(lái)檢查特定的屏幕方向,只需添加另一個(gè) and 關(guān)鍵詞,后跟 orientation 媒體查詢。
@media screen and (min-width:768px) and (max-width:1200px) and (orientation:landscape){
*{
background:blue;
}
}
5.2 or條件
媒體查詢中使用逗號(hào)分隔效果等同于 or 邏輯操作符。當(dāng)使用逗號(hào)分隔的媒體查詢時(shí),如果任何一個(gè)媒體查詢返回真,樣式就是有效的。逗號(hào)分隔的列表中每個(gè)查詢都是獨(dú)立的,一個(gè)查詢中的操作符并不影響其它的媒體查詢。
@media (width:768px), screen and (orientation:portrait) {
* {
background: blue;
}
}
5.3 not條件
not 關(guān)鍵字應(yīng)用于整個(gè)媒體查詢,在媒體查詢?yōu)榧贂r(shí)返回真,但僅能應(yīng)用于整個(gè)查詢,而不能單獨(dú)應(yīng)用于一個(gè)獨(dú)立的查詢。所有的not判斷都在媒體查詢的最后進(jìn)行。
注意區(qū)分:
@media not all and (min-width:768px) {
*{
background:blue;
}
}
等價(jià)于:
@media not (all and (min-width:768px)) {
*{
background:blue;
}
}
雖然這么寫(xiě)也是錯(cuò)誤的,我們只是用來(lái)理解not的判斷順序。
而不是:
@media (not all) and (min-width:768px){
*{
background:blue;
}
}
第六章 響應(yīng)式布局
6.1 思路
響應(yīng)式布局即根據(jù)瀏覽器或屏幕的大小,調(diào)整頁(yè)面的布局方式.
例:

先嘗試做一些"不響應(yīng)式"的div來(lái),只考慮定義12個(gè)類(lèi),寬分別是1/12,2/12...12/12,且分別左浮.
*{
box-sizing: border-box;
}
.col-xs-1,
.col-xs-2,
.col-xs-3,
.col-xs-4,
.col-xs-5,
.col-xs-6,
.col-xs-7,
.col-xs-8,
.col-xs-9,
.col-xs-10,
.col-xs-11,
.col-xs-12 {
min-height:1px;
float:left;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
<div class="row">
<div class="col-xs-3">第一列</div>
<div class="col-xs-3">第二列</div>
<div class="col-xs-3">第三列</div>
<div class="col-xs-3">第四列</div>
</div>
<div class="row">
<div class="col-xs-4">第五列</div>
<div class="col-xs-4">第六列</div>
<div class="col-xs-4">第七列</div>
</div>
無(wú)論我們?cè)趺赐蟿?dòng)瀏覽器的寬窄,這四列始終相對(duì)位置不變.
來(lái)一堆div
<div class="row">
<div class="col-sm-4">三一列</div>
<div class="col-sm-4">三二列</div>
<div class="col-sm-4">三三列</div>
</div>
注意看類(lèi)名col-sm-4,由于我們沒(méi)有定義這個(gè)類(lèi),因此呈現(xiàn)div的默認(rèn)效果,即寬100%,因此都是豎直方向堆積顯示.
6.2 "響應(yīng)式"布局
我們假設(shè)當(dāng)瀏覽器變到768px寬時(shí),col-sm-4變?yōu)?5%寬,且左浮.
程序表達(dá):
if(width>=768px) {
.col-sm-4 {
25%px;
float:left;
}
}
結(jié)合前面學(xué)的媒體查詢Media Query,我們寫(xiě)如下代碼:
@media (min-width: 768px) {
.col-sm-1 {
width: 8.333333%;
}
.col-sm-2 {
width: 16.666667%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-4 {
width: 33.333333%;
}
.col-sm-5 {
width: 41.666667%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-7 {
width: 58.333333%;
}
.col-sm-8 {
width: 66.666667%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-10 {
width: 83.333333%;
}
.col-sm-11 {
width: 91.666667%;
}
.col-sm-12 {
width: 100%;
}
.col-sm-1,
.col-sm-2,
.col-sm-3,
.col-sm-4,
.col-sm-5,
.col-sm-6,
.col-sm-7,
.col-sm-8,
.col-sm-9,
.col-sm-10,
.col-sm-11,
.col-sm-12 {
position: relative;
float: left;
}
}
分析: 當(dāng)瀏覽器width>=768px時(shí),對(duì)應(yīng)的css發(fā)揮作用,把col-sm-*的寬度按百分比設(shè)置,且左浮,形成了響應(yīng)效果。
第七章 Bootstrap細(xì)節(jié)處的技巧
Container
有兩個(gè)作用:
在隨時(shí)可能的寬度變化(響應(yīng)式)中提供寬度限制。當(dāng)頁(yè)面寬度變化,container 的寬度也隨之變化。并且其中的 column 的寬度是基于百分比,所以他們的值不需要變化。
提供一個(gè)水平方向的 padding,使其內(nèi)部的內(nèi)容不會(huì)接觸到瀏覽器的邊界,大小為15px,就是圖片中粉紅色的部分,作用會(huì)在下面說(shuō)。
注意,不需要也不應(yīng)該在 container 中嵌套另一個(gè) container。

Row
Row 是 column 直接存在的容器,按照文檔描述 row 中最多可有12個(gè) column,不過(guò)可以通過(guò)套嵌的方式靈活擴(kuò)展。同時(shí)作為都是左浮動(dòng)的 column 的容器,自帶清除浮動(dòng)的性質(zhì)。
同時(shí) row 還有一個(gè)很特殊的地方,就是左右各有 -15px 的 margin,就是圖片中的藍(lán)色部分。這樣也就抵消了上面提到的 container 中15px的 padding,那么為什么要這么折騰呢?接著看往下讀。
注意:千萬(wàn)記住要把 row 放到 container 的內(nèi)部,這樣才能保證正常。

Column
注意,每個(gè)column 也會(huì)有15px的水平方向的 padding,也就是圖片中黃色的部分,還記得上面提到的 row 的作用嗎,column 只能在 row 中生存,由于 row 的 margin 為-15px,那么位于兩邊的 column 就碰到了 container 的邊界。但是 colunmn 本身又有 15px 的 padding 使得它其中的內(nèi)容并不會(huì)碰到 container,同時(shí) 不同column的內(nèi)容之間就有了30px的槽。結(jié)合圖片看一下就一目了然了。
注意:一定要把 column 放到 row 里使用。

Nesting
當(dāng)把上面一系列的 container, row, column 都設(shè)置好,就可以通過(guò)套嵌 擴(kuò)展它的柵格系統(tǒng)了,也就是在 column 中直接嵌套 row,而不需要再套一層 container:

還記得 container 和 column 都有15px的 padding 嗎,對(duì)在套嵌的時(shí)候 column 的作用也相當(dāng)于 container 了,這樣就可以實(shí)現(xiàn)任意的嵌套了。

1px
根據(jù)我們上面完善后的boolstrap,寫(xiě)一個(gè)最簡(jiǎn)單的布局:
<style type="text/css">
.container{
background:gray;
}
</style>
<div class="container">
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-9">右面有九個(gè)</div>
</div>
</div>
但是實(shí)際效果并不是我們想象的那樣:

左側(cè)的3列并沒(méi)有顯示。
這是因?yàn)?,我們的列都是左浮的,?dāng)左側(cè)元素沒(méi)有內(nèi)容的時(shí)候,右側(cè)的列會(huì)直接占據(jù)其位置。我們只需要給列一個(gè)最小的行高,即可解決這個(gè)問(wèn)題。
.col-md-1,
.col-md-2,
.col-md-3,
.col-md-4,
.col-md-5,
.col-md-6,
.col-md-7,
.col-md-8,
.col-md-9,
.col-md-10,
.col-md-11,
.col-md-12{
min-height:1px;
padding:0px 15px;
}
列偏移
使用 .col-md-offset-*類(lèi)可以將列向右側(cè)偏移。這些類(lèi)實(shí)際是通過(guò)使用選擇器為當(dāng)前元素增加了左側(cè)的邊距(margin)。
我們可以類(lèi)似下面的方法實(shí)現(xiàn)列偏移:
.col-md-offset-4{
margin-left:33.333%;
}
對(duì)于列排序,則是通過(guò)相對(duì)定位,重新定位列的位置。
Container和Container-fluid
通過(guò)分析源碼,我們可以得知在Bootstrap中,container是階梯狀增長(zhǎng)的,用于固定寬度并支持響應(yīng)式布局的容器。
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
而container-fluid則是用于 100% 寬度,占據(jù)全部視口(viewport)的容器。
我們?cè)O(shè)定container-fluid為
.container-fluid{
width:100%;
padding:0px 15px;
}
還有很多方法可以實(shí)現(xiàn)響應(yīng)式布局 比如我們學(xué)過(guò)的彈性盒模型和display:table-cell