響應(yīng)式網(wǎng)站建設(shè)的思路中,一個(gè)重要的因素是怎樣處理圖片方面的問(wèn)題。有很多同比縮放圖片的技術(shù),其中有不少是簡(jiǎn)單易行的。其中,由Richard Rutter最先嘗試的一種做法比較流行,即使用CSS的max-width屬性。這個(gè)方法在Ethan Marcotte的液態(tài)圖片一文中也有提到。
1 | img {max-width:100%;} |
只要沒(méi)有其他涉及到圖片寬度的樣式代碼覆蓋掉這一行規(guī)則,頁(yè)面上所有的圖片就會(huì)以其原始寬度進(jìn)行加載,除非其容器可視部分的寬度小于圖片的原始寬度。上面的代碼確保圖片最大的寬度不會(huì)超過(guò)瀏覽器窗口或是其容器可視部分的寬度,所以當(dāng)窗口或容器的可視部分開(kāi)始變窄時(shí),圖片的最大寬度值也會(huì)相應(yīng)的減小,圖片本身永遠(yuǎn)不會(huì)容器邊緣隱藏和覆蓋。實(shí)際上,就像Jason Grigsby在他的CSS Media Query for Mobile is Fool’s Gold一文中提到的,“液態(tài)圖片背后的思路,就是無(wú)論何時(shí),都確保在其原始寬度范圍內(nèi),以最大的寬度同比完整的顯示圖片。我們不必在樣式表中為圖片設(shè)置寬度和高度,只需要讓樣式表在窗口尺寸發(fā)生變化時(shí)輔助瀏覽器對(duì)圖片進(jìn)行縮放?!?一種簡(jiǎn)而美的方法。
圖片本身的分辨率及加載時(shí)間是另外一個(gè)需要考慮的問(wèn)題。雖然通過(guò)上面的方法,可以很輕松的縮放圖片,確保在移動(dòng)設(shè)備的窗口中可以被完整瀏覽,但如果原始圖片本身過(guò)大,便會(huì)顯著降低圖片文件的下載速度,對(duì)存儲(chǔ)空間也會(huì)造成沒(méi)有必要的消耗。
響應(yīng)式圖片
由Filament Group提出的“響應(yīng)式圖片”技術(shù)思想,有助于解決上面提到的問(wèn)題:不僅要同比的縮放圖片,還要在小設(shè)備上降低圖片自身的分辨率。可以看下demo頁(yè)面先。
這個(gè)技術(shù)的實(shí)現(xiàn)需要使用幾個(gè)相關(guān)文件,我們可以在Github上獲取。包括一個(gè)JavaScript文件(rwd-images.js),一個(gè).htaccess文件,以及一些范例資源文件。具體使用方法可以參考Responsive Images的說(shuō)明文檔。大致的原理是,rwd-images.js會(huì)檢測(cè)當(dāng)前設(shè)備的屏幕分辨率,如果是大屏幕設(shè)備,則向頁(yè)面head部分中添加BASE標(biāo)記,并將后續(xù)的圖片、腳本和樣式表加載請(qǐng)求定向到一個(gè)虛擬路徑“/rwd-router”。當(dāng)這些請(qǐng)求到達(dá)服務(wù)器端,.htacces文件會(huì)決定這些請(qǐng)求所需要的是原始圖片還是小尺寸的“響應(yīng)式圖片”,并進(jìn)行相應(yīng)的反饋輸出。對(duì)于小屏幕的移動(dòng)設(shè)備,原始尺寸的大圖片永遠(yuǎn)不會(huì)被用到。
這項(xiàng)技術(shù)支持多數(shù)的現(xiàn)代瀏覽器,包括IE8+、Safari、Chrome和Opera,以及這些瀏覽器的移動(dòng)設(shè)備版本;在FireFox及一些舊瀏覽器中,則會(huì)優(yōu)雅降級(jí):我們?nèi)钥傻玫叫D片的輸出,但同時(shí),原始大圖也會(huì)被下載。
禁用iPhone中的圖片自動(dòng)縮放
在iPhone及iPod Touch中,頁(yè)面會(huì)被自動(dòng)的同比例縮小至最適合屏幕大小的尺寸,x軸不會(huì)產(chǎn)生滾動(dòng)條,用戶(hù)可以上下拖拽瀏覽全部頁(yè)面,或在需要的時(shí)候放大頁(yè)面的局部。這里會(huì)產(chǎn)生一個(gè)問(wèn)題,即使我們運(yùn)用響應(yīng)式Web設(shè)計(jì)的思想,專(zhuān)門(mén)為iPhone的小屏輸出小圖片,它同樣會(huì)隨著整個(gè)頁(yè)面一起被同比例縮小,如下圖左側(cè)所示。
我們可以使用蘋(píng)果專(zhuān)有的一些meta標(biāo)記來(lái)解決類(lèi)似的問(wèn)題。在頁(yè)面的
部分添加以下代碼(詳情可以參考Think Vitamin的相關(guān)文章): 1 | |
將initial-scale的值設(shè)定為“1”,即可覆寫(xiě)默認(rèn)的縮放方式,保持原始的尺寸及比例。更多關(guān)于viewport meta標(biāo)記的用法,可以參考蘋(píng)果官方的文檔。
響應(yīng)式網(wǎng)站建設(shè)打造布局結(jié)構(gòu)
當(dāng)頁(yè)面所需要適應(yīng)的不同設(shè)備的屏幕尺寸差異過(guò)大時(shí),除了圖片方面,我們也應(yīng)該考慮到整個(gè)布局結(jié)構(gòu)的響應(yīng)式調(diào)整;我們可以使用獨(dú)立的樣式表,或者更有效的,使用CSS media query。這不會(huì)引起多大的麻煩,多數(shù)樣式設(shè)定不會(huì)被影響和改變,只有一些特定的元素會(huì)通過(guò)浮動(dòng)、寬度和高度等的設(shè)置來(lái)改變位置。
我們可以使用一個(gè)默認(rèn)主樣式表來(lái)定義頁(yè)面的主要結(jié)構(gòu)元素,比如#wrapper、#content、#sidebar、#nav等的默認(rèn)布局方式,以及一些全局性的配色和字體方案。
我們可以監(jiān)測(cè)頁(yè)面布局隨著不同的瀏覽環(huán)境而產(chǎn)生的變化,如果它們變的過(guò)窄過(guò)短或是過(guò)寬過(guò)長(zhǎng),則通過(guò)一個(gè)子級(jí)樣式表來(lái)繼承主樣式表的設(shè)定,并專(zhuān)門(mén)針對(duì)某些布局結(jié)構(gòu)進(jìn)行樣式覆寫(xiě)。我們來(lái)看下代碼示例:
下面的代碼可以放在默認(rèn)主樣式表style.css中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* Default styles that will carry to the child style sheet */ ? html,body{ ???background... ???font... ???color... } ? h1,h2,h3{} p, blockquote,pre,code, ol, ul{} ? /* Structural elements */ #wrapper{ ????width:80%; ????margin:0auto; ? ????background:#fff; ????padding:20px; } ? #content{ ????width:54%; ????float:left; ????margin-right:3%; } ? #sidebar-left{ ????width:20%; ????float:left; ????margin-right:3%; } ? #sidebar-right{ ????width:20%; ????float:left; } |
下面的代碼可以放在子級(jí)樣式表mobile.css中,專(zhuān)門(mén)針對(duì)移動(dòng)設(shè)備進(jìn)行樣式覆寫(xiě):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #wrapper{ ????width:90%; } ? #content{ ????width:100%; } ? #sidebar-left{ ????width:100%; ????clear:both; ? ????/* Additional styling for our new layout */ ????border-top:1pxsolid#ccc; ????margin-top:20px; } ? #sidebar-right{ ????width:100%; ????clear:both; ? ????/* Additional styling for our new layout */ ????border-top:1pxsolid#ccc; ????margin-top:20px; } |
大致的視覺(jué)效果如下圖所示:
Media Queries
CSS3支持CSS2.1所支持的所有媒體類(lèi)型,例如screen、print、handheld等,同時(shí)添加了很多涉及媒體類(lèi)型的功能屬性,包括max-width(最大寬度)、device-width(設(shè)備寬度)、orientation(屏幕定向,橫屏或豎屏)和color。在CSS3發(fā)布之后出現(xiàn)的新玩具,如iPad或Android相關(guān)設(shè)備,都可以完美的支持這些屬性。所以我們可以通過(guò)media query為新設(shè)備設(shè)置獨(dú)特的樣式,而忽略那些不支持CSS3的臺(tái)式機(jī)中的舊瀏覽器。
在Ethan的文章中,我們能看到一段media query使用實(shí)例:
1 2 3 | ????media="screen and (max-device-width: 480px)" ????href="shetland.css"/> |
代碼本身可以很好的說(shuō)明工作機(jī)制:如果頁(yè)面通過(guò)屏幕呈現(xiàn)(非打印一類(lèi)),并且屏幕寬度不超過(guò)480px,則加載shetland.css樣式表。要了解更多關(guān)于CSS3媒體新屬性的信息,可以參考“The Orientation Media Query”一文。
我們可以創(chuàng)建多個(gè)樣式表,以適應(yīng)不同設(shè)備類(lèi)型的寬度范圍。Ethan的文章中的“Meet the media query”部分有更多的范例及解釋。更有效率的做法是,將多個(gè)media queries整合在一個(gè)樣式表文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* Smartphones (portrait and landscape) ----------- */ @media onlyscreen and (min-device-width :320px) and (max-device-width :480px) { /* Styles */ } ? /* Smartphones (landscape) ----------- */ @media onlyscreen and (min-width :321px) { /* Styles */ } ? /* Smartphones (portrait) ----------- */ @media onlyscreen and (max-width :320px) { /* Styles */ } |
上面的代碼來(lái)自于Andy Clark創(chuàng)建的可以兼容各種主流設(shè)備的免費(fèi)模板。這樣整合多個(gè)media queries于一個(gè)樣式表文件的方式,與通過(guò)media queries調(diào)用不同樣式表的方式之間的區(qū)別與聯(lián)系,可以參考“Hardboiled CSS3 Media Queries”一文。
CSS3 Media Queries
上面演示的一些代碼范例是CSS2.1與CSS3通吃的?,F(xiàn)在讓我們來(lái)看看怎樣使用CSS3專(zhuān)有的media queries功能來(lái)創(chuàng)建響應(yīng)式Web設(shè)計(jì)。其中某些方法在當(dāng)前就有切實(shí)的使用價(jià)值,不久的將來(lái)則一定會(huì)全部派上用場(chǎng)。
min-width和max-width這兩個(gè)屬性很靠譜。通過(guò)min-width的設(shè)置,我們可以在瀏覽器窗口或設(shè)備屏幕寬度高于這個(gè)值的情況下,為頁(yè)面指定一個(gè)特定的樣式表;max-width則反之。
下面的幾個(gè)示例中,我們使用的是將多個(gè)media queries整合在單一樣式表中進(jìn)行編碼的句法。如前文所述,這樣做更加高效,減少請(qǐng)求數(shù)量。
1 2 3 4 5 6 | @mediascreenand (min-width:600px) { ?????.hereIsMyClass { ??????????width:30%; ??????????float:right; ?????} } |
上面代碼中定義的類(lèi)(hereIsMyClass)只有在瀏覽器或屏幕寬度超過(guò)600px時(shí)才會(huì)有效。
1 2 3 4 5 6 | @mediascreenand (max-width:600px) { ?????.aClassforSmallScreens { ??????????clear:both; ??????????font-size:1.3em; ?????} } |
?????? 而這段代碼的作用則相反:aClassforSmallScreens類(lèi)只有在瀏覽器或屏幕寬度小于600px時(shí)才會(huì)有效。
可以看出min-width和max-width可以同時(shí)判斷設(shè)備屏幕尺寸與瀏覽器實(shí)際寬度。有些時(shí)候,我們希望通過(guò)media queries作用于某種特定的設(shè)備,而忽略其上運(yùn)行的瀏覽器是否由于沒(méi)有最大化而在尺寸上與設(shè)備屏幕尺寸產(chǎn)生不一致的情況。這時(shí),我們需要使用min-device-width與max-device-width,用來(lái)判斷設(shè)備本身的屏幕尺寸。
1 2 3 4 5 | @mediascreenand (max-device-width:480px) { ?????.classForiPhoneDisplay { ??????????font-size:1.2em; ?????} } |
1 2 3 4 5 6 | @mediascreenand (min-device-width:768px) { ?????.minimumiPadWidth { ??????????clear:both; ??????????margin-bottom:2pxsolid#ccc; ?????} } |
還有一些其他方法,可以幫我們有效的使用media queries鎖定某些指定的設(shè)備??梢詤⒖枷旅鎯善鲎訲homas Maier的文章:
- CSS for iPhone 4 (Retina display)
- How To: CSS for the iPad
對(duì)于iPad來(lái)說(shuō),orientation屬性尤其有用。它的值可以是landscape(橫屏)或portrait(豎屏)。
1 2 3 4 5 6 | @mediascreenand (orientation:landscape) { ?????.iPadLandscape { ??????????width:30%; ??????????float:right; ?????} } |
1 2 3 4 5 | @mediascreenand (orientation:portrait) { ?????.iPadPortrait { ??????????clear:both; ?????} } |
不幸的是,這個(gè)屬性目前確實(shí)只在iPad上有效。對(duì)于其他可以轉(zhuǎn)屏的設(shè)備,譬如iPhone,可以使用min-device-width和max-device-width來(lái)變通實(shí)現(xiàn);詳情可以參考“Determine iPhone orientation using CSS”一文。
我們還可以將上述屬性組合使用,來(lái)鎖定某個(gè)屏幕尺寸范圍:
1 2 3 4 5 6 7 | @mediascreenand (min-width:800px) and (max-width:1200px) { ?????.classForaMediumScreen { ??????????background:#cc0000; ??????????width:30%; ??????????float:right; ?????} } |
上面的代碼可以作用于瀏覽器窗口或屏幕寬度在800px至1200px之間的所有設(shè)備。
其實(shí),很多設(shè)計(jì)師和開(kāi)發(fā)者仍會(huì)選擇使用多個(gè)樣式表的方式來(lái)實(shí)現(xiàn)media queries。如果從資源的組織和維護(hù)的角度出發(fā),其益處確實(shí)高于效率的損耗的話(huà),那么這樣做也完全不壞:
1 2 3 | |
所以吶,凡事沒(méi)有絕對(duì),最好根據(jù)實(shí)際情況決定使用media queries的方式。比如,對(duì)于iPad,我們可以將多個(gè)media queries直接寫(xiě)在一個(gè)樣式表中。因?yàn)閕Pad用戶(hù)隨時(shí)有可能切換屏幕定向,這種情況下,要保證頁(yè)面在極短的時(shí)間內(nèi)響應(yīng)屏幕尺寸的調(diào)整,我們必須選擇效率最高的方式。
JavaScript
JavaScript也是我們的武器之一,特別是當(dāng)某些舊設(shè)備無(wú)法完美支持CSS3的media query時(shí),它可以作為后備支援。幸運(yùn)的是,已經(jīng)有專(zhuān)門(mén)的JS庫(kù)來(lái)幫助舊瀏覽器(IE 5+,F(xiàn)irefox 1+,Safari 2等)支持CSS3的media queries。使用方法很簡(jiǎn)單,下載css3-mediaqueries.js并在你的頁(yè)面中調(diào)用它。
而下面的代碼則演示了怎樣使用簡(jiǎn)單的幾行jQuery代碼來(lái)檢測(cè)瀏覽器寬度,并為不同的情況調(diào)用不同的樣式表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ? |
類(lèi)似這樣的解決方案還有很多。所以我們要清楚,media queries不是一個(gè)絕對(duì)唯一的答案,它只是一個(gè)以純CSS方式實(shí)現(xiàn)響應(yīng)式Web設(shè)計(jì)思路的手段。借助JavaScript,我們則可以實(shí)現(xiàn)更多的變化。這篇“Combining Media Queries and JavaScript”向我們展示了JavaScript配合media queries的更多細(xì)節(jié)信息。