響應式開發心得

什麼是響應式?響應式的頁面在不一樣的屏幕有不一樣的佈局,換句話說,使用相同的html在不一樣的分辨率有不一樣的排版。以下圖所示:css


響應式佈局是爲了解決適配的問題,傳統的開發方式是PC端開發一套,手機端再開發一套,而使用響應式佈局只要開發一套就行了。由於它是用的一樣html,因此它的JS邏輯交互也只需寫一套就行了,缺點是CSS比較重。

傳統的手機端適配常見有三種解決方案,第一種是bootstrap的columns佈局;第二種是使用全局的rem,先根據屏幕換算1rem等於多少個px,而後設置html標籤的font-size爲多少個rem,屏幕越大,則font-size越大,而後頁面全部的元素的寬高和字體大小都用rem等比例縮放;第三種是阿里的flex box,這種方案和第二種相似,不一樣點是頁面內容的字體大小是用的px,而不是比例縮放的rem。第一種須要額外引入一個框架。第三種相對第二種來講應該更合理點,由於正文的字體經常使用的爲14px或者16px,若是一個頁面在這個手機字號是15.5px,在另一個手機又變成了14.9px,這樣可能會有點奇怪。html

而使用響應式佈局就不須要進行rem的換算,下面經過上圖的那個例子一步一步地分析怎麼作響應式。前端

1. 設置不一樣分辨率頁面兩邊留白

首先一個頁面的主體內容有最大的寬度,當屏幕超過這個寬度時這個中間的主體內容最大就這麼大了,不會再變大了,也就是說它固定一個最大寬度,而後居中顯示,如最大爲1080px。而後當大於1024px時,頁面主體內容最小寬爲960px,兩邊自動留白;在500px到1024px之間兩邊保持留白40px;而當小於500px時就認爲是手機,兩邊留白20px。因此計算一下,container的代碼以下:android


整體的思想是留白要合適,既不能留太多,致使中間內容太窄,也不能讓中間的內容顯得太大。這個其實和bootstrap的container思想一致,只是你可能要根據你本身的業務特色、用戶人羣等作不一樣留白策略。

2. 屏幕變小時,一頭變窄,另外一頭不變

當屏幕變小或者瀏覽器窗口拉小時,中間內容的寬度就不能保持1080px,它得跟着變小,而在變小的過程當中,每每要保持一邊不變,另外一邊隨頁面變窄,以下圖所示:bootstrap


右邊的結果欄寬度保持不變,左邊的表單欄寬度縮小。由於右邊一旦就窄很差看了,若是右邊變窄,那麼字體也要相應縮小,字號一縮小,右邊上下留白就變得太大,這樣就不美觀了,因此只能採起右邊保持不動的策略去縮小左邊的內容。這種場景比較常見,右邊若是是一個頭像的話,它也不能跟着縮小,它一縮小高度也要跟着縮小,致使上下太空,因此這種狀況也不能動。

3. 保持中間留白固定,縮小內容寬度

左欄的寬度變小應該怎麼變呢?有一個原則,就是要保持中間的間距固定,而兩邊的內容寬度相應縮小,以下圖所示:瀏覽器


因此就要藉助CSS3的calc,以下所示:

input{
    width: calc((100% - 20px) / 2)
}複製代碼

calc的兼容性IE10及以上支持,android 4及如下不支持,因此考慮到不支持的設備,能夠簡單作個兼容,以下代碼所示:框架

input{
    width: 48%;
    width: calc((100% - 20px) / 2);
}複製代碼

若是不支持calc就用48%,這樣差異其實不是很大,就是否是很精確。真的須要的話,你能夠多寫幾個媒體查詢變得更精確。佈局

4. 左右佈局變成上下佈局

當屏幕拉得很小的時候,左欄已經縮得很小了,再變小就不協調了,因此這個時候要把左右佈局改爲上下佈局,把右邊的內容往下面放。由於右欄在大屏的時候是float: right,因此在中屏的時候覆蓋掉這個浮動的屬性,變成float: none就能夠了。本來右欄的內容有四行,都比較短,能夠考慮把它下面的三行排成一行,即讓它們浮動。以下面代碼所示:字體

.cal-result{
    float: right;
    width: 330px;
}

@media (max-width: 800px){
    .cal-result{
        float: none;
        width: 100%;
    }
    .cal-result .result{
        float: left;
        width: 33%;
    }
}複製代碼

讓每個result佔1/3,而後浮動,效果以下:flex

5. 寬度過小時,自動換行

特別是當內容是列表ul形式的時候,排不下的li應當自動換到下一行。固然也能夠手動控制,以下:

@media (max-width: 800px){
    .result{
        width: 33%;
    }
}

@media (max-width: 400px){
    .result{
        width: 50%;
    }
}複製代碼

在屏幕寬度小於400的時候,每一個結果就佔50%,這樣就排成兩行了。這也是一種經常使用的辦法,可是在咱們這個例子,若是數字比較小,在iPhone6 375px的屏幕上仍是排得下的,若是能保持在一行相對比較美觀。並且固定50%,若是當數字比較大時也有可能會有重疊的危險,這個也有辦法,就是別寫死寬度,而是寫死min-width爲50%,這樣當內容比較長時,float的元素同一行排不下就會自動換行。可是最好仍是要個辦法讓它能根據內容長度自動換行,固然能夠用JS計算,可是有點麻煩。

這個時候flex就派上用場了,很簡單,只要設置兩個屬性:

.result-container{
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
}複製代碼

space-between讓子元素挨着容器的兩邊等間距排列,而wrap屬性讓子元素自動換行,當容器寬度不夠的時候,就有了如下的效果:


這樣還有一個小問題,就是當內容若是剛恰好佔滿時,兩個項之間就沒有間距了,以下圖所示:


這樣就貼在一塊兒了,因爲flex的space-between不能指定最小的space,因此只經過margin或者padding的方法,如給元素添加margin-right:

.result:not(:last-child) {
    margin-right: 10px;
}複製代碼

效果以下:


這樣比貼在一塊兒顯示的效果好。

還有從大屏變成成小屏的時候有些字號主要是標題的字號和間距要相應調小,這種變小是階梯變化的,而不是像rem同樣連續變化,並且這種階梯通常只要有兩個就夠了,一個大屏的,一個小屏的。若是你須要作不少階梯的話,那你的排版極可能有問題。

6. 使用響應式圖片

如相同的頭圖,在電腦上須要使用大圖,可是手機上面使用小圖就行了,否則會形成手機上加載慢浪費流量等問題,一個辦法是使用backgound-image結合媒體查詢,以下所示:

.banner{
    background-image: url(/static/large.jpg);
}

@media (max-width: 500px){
    background-image: url(/static/small.jpg);
}複製代碼

這種方法的缺點是對SEO不太友好,由於若是使用img標籤還能夠寫個alt屬性。
第二種經常使用辦法是使用img的srcset或者picture標籤作響應式圖片,這個我在《Effective前端7:加快頁面打開速度》已經提到,這裏再也不重複。

這種響應式圖片除了大小屏以外,還能夠兼顧視網屏即dpr爲2及以上的和普通屏dpr爲1的屏幕,即在高dpr的屏幕使用2倍圖,而普通屏幕使用1倍圖。

7. 其它問題處理

有些地方大小屏的排版差別比較大,例若有些內容大屏的時候是挨在一塊兒,而小屏離得比較遠,這個時候你可能得重複html,寫兩份的標籤,大屏的時候隱藏掉小屏的html標籤,小屏的時候隱藏掉大屏的html標籤。而且這種狀況不該該是常例,若是你常常要寫兩套,那說明你這個頁面可能不太適合寫響應式,還不如直接寫兩套呢。

還有個問題,有時候你可能要藉助rem/transform: scale作大小縮放,但這必定是下策,咱們的原則仍是要保持字號和間距不變,當屏幕的跨度不是很大的時候。使用transform的後果是屏幕拉小的時候,內容跟着變小了,可是因爲transform不會形成重排,它佔據的高度仍是那麼大,下面的內容不會跟上來。這樣就得手動計算內容的高度。另外若是使用rem,就和響應式的思想衝突了。若是頁面的一部分字號使用了rem,另外一部分字號使用了px,這樣就不協調了,若是你所有寫rem那就不須要使用響應式開發了。 這個時候你可能要想想,是否是UI出得有問題。讓UI從新調整。

還有,有時候可能會用到高度的媒體查詢,例如在高度小於多少的時候,不能讓彈框超出頁面的高度;在高度大於多少的時候,讓footer的定位fixed在底部,否則footer的下面可能會留白。

最後,本文總結了響應式開發的一些思想,它的好處是不用大屏寫一套,小屏寫一套,方便維護,縮短開發時間,缺點是兼容性不是特別好,而且效果沒有專門出一個小屏的UI和交互來得好。可是整體來講,使用響應式仍是頗有優點的,只要設計得好,小屏上也是挺好看的。如今響應式開發已經愈來愈流行,它能夠兼容PC/Pad/手機三端的屏幕,這個優勢是沒法超越的,你只需寫一套html和一套JS邏輯,無論多大的屏幕都能適用。

相關文章
相關標籤/搜索