響應式設計的思考:媒體查詢(media query)

響應式設計的思考:媒體查詢(media query)

 

Jason Grigsby發表了篇文章,《CSS Media Query for Mobile is Fool’s Gold》對媒體查詢(media query)吐槽,大意是在移動設備上使用媒體查詢會形成不少資源的浪費——瀏覽器請求到不少用不到的圖片等資源,而後寫了一些測試用例測試一些可用方法。而後Tim Kadlec寫了篇《Media Query & Asset Downloading Results》,用js自動化的測試了Jason Grigsby的用例。javascript

本文主要整理自Tim的這篇文章。咱們來看看到底會不會浪費資源,並尋找下最優的方案。php

直接看結果吧~~css

測試一:img標籤

運行測試html

本測試嘗試經過對img標籤的父級元素使用display:none來隱藏圖片。HTML和CSS代碼以下:java

1
2
3
<div id="test1">
	<img src="images/test1.png" alt="" />
</div>
1
2
3
@media all and (max-width: 600px) {
	#test1 { display:none; }
}

測試結果

若是有一種應該100%避免的隱藏圖片的方法,那就是display:none。它基本上是沒有用的。貌似Opera Mobile和Opera mini不會下載圖片,而其它瀏覽器都會下載。Opera能夠比較好的控制資源的下載,對於用戶看不到的內容,它不會預先下載。ios

瀏覽器 請求圖片
Android 2.1+ 請求
Blackberry (6.0+) 請求
Chrome (4.1)+ 請求
Chrome Mobile 請求
Fennec (10.0+) 請求
Firefox (3.6+) 請求
IE 請求
iOS (4.26+) 請求
Kindle (3.0) 請求
Opera (11.6+) 請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
RockMelt 請求
Safari (4+) 請求

結論

很簡單:不要這樣用。git

測試二:背景圖片display:none

運行測試github

在本例中,div被設置了background-image。若是屏幕寬度小於600px,div就被設置爲display:none。HTML和CSS代碼以下:web

1
<div id="test2"></div>
1
2
3
4
5
6
7
8
#test2 {
	background-image:url('images/test2.png');
	width:200px;
	height:75px;
}
@media all and (max-width: 600px) {
	#test2 {display:none;}
}

測試結果

結果和測試一同樣:除了Opera mini和Opera Mobile和Firefox,全部瀏覽器都會下載圖片。瀏覽器

瀏覽器 請求圖片
Android 2.1+ 請求
Blackberry (6.0+) 請求
Chrome (4.1)+ 請求
Chrome Mobile 請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 請求
iOS (4.26+) 請求
Kindle (3.0) 請求
Opera (11.6+) 請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
RockMelt 請求
Safari (4+) 請求
Silk 請求

結論

一樣:不要這樣作。不過,像後面其它的測試,有其它的方法能夠隱藏背景圖片同時避免多餘請求。

測試三:背景圖片的父級元素被設置爲display:none

運行測試

本測試中,對一個div標籤設置背景圖片,而後對其父元素(也是個div)在瀏覽器寬度小於600px時設置display:none。HTML和CSS代碼以下:

1
2
3
<div id="test3">
	<div></div>
</div>
1
2
3
4
5
6
7
8
9
10
#test3 div {
	background-image:url('images/test3.png');
	width:200px;
	height:75px;
}
@media all and (max-width: 600px) {
	#test3 {
		display:none;
	}
}

測試結果

表面上,這個測試貌似和測試二沒太明顯的區別,可是結論是這個方法是比較靠譜的。。。

瀏覽器 請求圖片
Android 2.1+ 不請求
Blackberry (6.0+) 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari (4+) 不請求

結論

這個方法不錯。除了不太成熟的Fennec,其它瀏覽器都不請求沒必要要顯示的圖片。

測試四:背景圖片層疊

運行測試

本測試中,一個div被設置了背景圖片。若是瀏覽器寬度小於600px,該div會被給到另外一個背景圖片。該測試用來檢測是否兩個圖片都會被請求,仍是隻請求須要的。HTML和CSS代碼以下:

1
<div id="test4"></div>
1
2
3
4
5
6
7
8
9
10
#test4 {
	background-image:url('images/test4-desktop.png');
	width:200px;
	height:75px;
}
@media all and (max-width: 600px) {
	#test4 {
		background-image:url('images/test4-mobile.png');
	}
}

測試結果

比設置display:none好一些,這種方法的結果有點兒亂:

瀏覽器 同時請求
Android 2.1-3.0? 請求
Android 4.0 不請求
Blackberry 6.0 請求
Blackberry 7.0 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari 4.0 請求
Safari 5.0+ 不請求

結論

我會避免使用這種方法。儘管環境在改善,可是在Android市場中占主導地位的Android 2.x版本依然會像Fennec和Kindle同樣同時下載兩個圖片。三者中,尤爲由於Android(的碎片化),我會推薦尋找別的方案。

測試五:大背景圖片被設置min-width

運行測試

本測試中,一個div元素在瀏覽器寬度大於601px時被設置一個背景圖片,而後在瀏覽器寬度小於600px時被設置爲另外一個背景圖片。HTML和CSS代碼以下:

1
<div id="test5"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@media all and (min-width: 601px) {
	#test5 {
		background-image:url('images/test5-desktop.png');
		width:200px;
		height:75px;
	}
}
@media all and (max-width: 600px) {
	#test5 {
		background-image:url('images/test5-mobile.png');
		width:200px;
		height:75px;
	}
}

測試結果

這種方案好一點兒:

瀏覽器 同時請求
Android 2.1+ 不請求
Blackberry (6.0+) 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari (4+) 不請求

結論

此次更多的瀏覽器一塊兒玩了。可是,Fennec一如既往得不能自已。Android 2.x比較怪異。它會同時請求兩個圖片——但只有在屏幕寬度大於600px匹配到min-width時才這樣。這種行爲貌似在Android 3.0版本中被改進了。這是件詭異的事情,我很好奇它爲何會這樣。 其實,有個好消息。Jason Grigsby 說他的對本例的測試結果和個人不太同樣。因此我又在一些Android 2.x機器上跑了一下這個測試。結論是,我最初的測試結果不太正確,Android 2.x表現很好,我最初測試的那個平臺有問題。這不只僅對於開發者來講是個好消息,對我本人來講更是恢復了對人類的信心。。。。。。。

可是這依然不夠,你將須要對IE8如下瀏覽器提供替代方案,那些版本的瀏覽器不支持media query,因此沒有圖片會被顯示。固然,這個問題能夠用條件註釋來簡單的兼容一下。

測試六:背景圖片display:none(max-device-width)

運行測試

本測試和測試二相似,可是使用了max-device-width來替代max-width。HTML和CSS代碼以下:

1
<div id="test6"></div>
1
2
3
4
5
6
7
8
9
10
#test6 {
	background-image:url('images/test6.png');
	width:200px;
	height:75px;
}
@media all and (max-device-width: 600px) {
	#test6 {
		display:none;
	}
}

結論

好吧,不用浪費時間了,這個測試結果和測試二的基本一致。

測試七:層疊覆蓋高分辨率

運行測試

最後一個測試,是爲了new ipad提供的,它使用了retina屏幕,這樣它就要使用更高分辨率的圖片了。

本例中,一個div被給到一個背景圖片。而後,經過使用min-device-pixel-ratio屬性,若是比例大於1.5,一個新的背景圖片將會被用到。

HTML和CSS代碼以下:

1
<div id="test7"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#test7 {
	background-image:url('images/test7-lowres.png');
	width:200px;
	height:75px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
	#test7 {
		background-image:url('images/test7-highres.png');
		width:200px;
		height:75px;
	}
}

測試結果

瀏覽器 同時請求
Android 2.1-3.0? 請求
Android 4.0 不請求
Blackberry 6.0 不請求
Blackberry 7.0 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 不請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari 4.0+ 不請求

結論

爲了安全,這個方案能夠多測試一些。看起來這種方法在絕大多數狀況下是可用的。可是不幸的是,貌似Android 2.x會同時下載兩個圖片若是設備像素比大於或等於1.5時(或者你在media query中設置的別的任何值)。因此,在本例中,若是你使用了一個高分辨率的Android 2.x的設備,會比較苦逼。。。

好消息是,到目前位置,我還沒據說有那一款Android 2.x的設備的屏幕比例超過1.5.因此若是你的項目面向使用retina屏幕的ios設備,你能夠將min-device-pixel-ratio設置到2或者更高,這樣會比較安全一點兒。。。

推薦

  • 若是你要隱藏一張內容圖片,display:none是無效的,因此我推薦使用javascript方案或者服務器端實現;
  • 若是你要隱藏一張背景圖片,最好的方法是隱藏其父級元素。若是你不方便這樣作,那就用一個層疊樣式覆蓋掉它吧(就像上面的第五個方案),而後將設置background-image:none;
  • 若是你要切換多張圖片,就把他們所有用media query定義吧。

關於響應式設計的思考

媒體查詢如今最大的用處就是響應式設計了,神飛翻譯這篇文章也是由於最近在思考響應式設計的效率問題。經過這些測試結果,咱們在實現響應式設計的網站時,最好先處理移動設備,而後再向高分辨率設備升級。而後使用圖片等外部資源的選擇器,必定要寫到媒體查詢中去。

反饋

若是你以爲這些測試結果有任何錯誤的地方,歡迎在評論中提出,而後這些測試用例Tim都在GitHub上開源了,感興趣的話能夠fork下。。。

相關文章
相關標籤/搜索