前端響應式詳解

老王前端發表於2020-03-11

前端響應式詳解

一兩年以前,我發現,很多人都被響應式搞得很懵逼。

現在,我依然發現,還是有很多人,依舊被響應式搞得很懵逼。

所以,我也很懵逼。

到底是哪個環節出了問題,讓這麼多學習前端的同學對於這個響應式很懵逼呢?

我想,平時總是會百度過響應式這個關鍵詞吧,數以萬計的教程,難道就沒有一個能讓自己頓悟的?

所以,我不信,為了天下沒有難學的程式設計,我打算繼續為這萬分之一添磚加瓦。


什麼是響應式?


很多人之所以對響應式很懵逼,最基本的一個原因就是,壓根就不懂什麼是響應式。

廢話,要是懂的話,我還有啥好問的?

沒錯,你說得很有道理。

所以,我打算用下文,來詳細講解,什麼是響應式。

任何行業,都喜歡創造術語,同樣地,響應式就是其一。

所謂的術語,必然和專業,高深,冷酷,無情掛鉤。

你想百般親近它,但是它卻對你不理不睬。

為了打破你們二者之間的僵局,我打算揭下響應式這一層神祕的面紗。

響應式:響應不同螢幕裝置合適地展現網頁效果的方式或著手段。

沒錯,不僅僅是方式,而且還有手段,請先對這個詞有個印象,後面我們會和它,再次相遇。


前端響應式詳解


我不知道,同學們在查詢資料的時候,文章裡是怎麼解釋響應式的。

可以看到,我這句解釋,非常妙。


前端響應式詳解


響應響應,何謂響應?我喊你,你回應我,這就是響應,響應了我喊你這件事。

我打你,你反過來打我。這不對,雖然這沒有違揹物理規律,但是這不夠尊老愛幼。

那麼同樣的,我喊你,你回答:哎,哥,咋了?

你媽媽喊你,你回答:哎,媽,又怎麼了?

你老爸喊你,你回答:哎,老爸,有啥事啊?

你老妹,老弟喊你,你回答:喊什麼喊,一遍玩去,我忙著呢。

所以,從這裡可以得知,什麼是響應式?就是說,不同的螢幕,它不能一成不變地顯示一樣的內容,得根據螢幕大小,顯示合適的內容。

記住合適這個詞,你不能說你媽媽喊你,你也回答:哎,哥,咋了?對不對?

見人說人話,見鬼說鬼話,不然你行走江湖兩行淚,痛苦不堪又受罪。

所以,要理解一個術語,咬文嚼字是有必要的。

其次,我們來看一下,這個不同螢幕的含義。

這個地方,很容易讓人哭笑不得。

我遇到過不止一個同學,絞盡腦汁地在思考,如果使用者縮放百分比,滑鼠拖動螢幕調整大小,我該怎麼響應式?

兄die!你的響應式是要適應天地萬物,比孫悟空的七十二般變化還能變嗎?

那我只能說一句:牛逼!

所以,這裡要牢記,響應式並不是孫悟空,它所要適應的,就是那些,正常情況下的響應式。

那種非人類的使用者,拿著瀏覽器,網頁百分比調個不停,網頁大小滑鼠拖了個不亦樂乎,這種使用者你留著他幹嘛?留著他炒個青椒炒肉不放辣椒嗎?

所以,同學們啊,你們是在花錢,花時間,花精力學程式碼啊,頭腦要靈活一點啊!

一頓痛批之後,我們來總結一下:總結如上。


一個響應式板磚的響應式歷程


扯了那麼多,我相信,同學們最關心的還是這裡。

no b b,show code.

同學們這種實事求是的精神,搞得我幾度都想再多BB一下。

不過,為了同學們的前途著想,我決定,暫時先小聲BB。


前端響應式詳解


首先呢,我們從最簡單的開始。

畢竟,我不想讓大家一口吃個大胖子,更加不想讓大家一口吃癟。

更何況,吃個大胖子還是違法的。

為了廣大胖友的利益,我們先來畫一塊板磚。


前端響應式詳解


儘管我一直以來,都堅信我們的中國漢字,博大精深,源遠流長。

但是,自從遇見了百度翻譯,我沒想到,原來我們的漢語拼音,更加博大精深!


 /* 板磚div */
<div class="MLGB"></div>複製程式碼


 /* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 板磚 */
.MLGB {
    width: 800px;
    height: 500px;
    background-color: antiquewhite;
}複製程式碼


前端響應式詳解


沒辦法,我是一個相信緣分的人,天意如此,我也只能順其自然。

所以呢,這就是一個普通的,有高度,有寬度的,div。

你說這div,它又長又寬,它像不像磚?


前端響應式詳解


為了讓大家更清楚地看到全貌,我們將瀏覽器整體調整一下。

那麼,這麼一調整呢,問題就來了。

大家發現沒有,底部居然出現了可惡的橫向滾動條!

什麼鬼?!這一點都不響應式!


 /* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 板磚 */
.MLGB {
    width: 100%;
    height: 500px;
    background-color: antiquewhite;
}複製程式碼


前端響應式詳解


解決它,把寬度變成百分比,就,設定成100%好了。

完美,一個響應式的板磚,應天時地利,涅槃重生!

那麼,同學們,響應式是不是很簡單?

我們甚至有N種方法,讓這個板磚響應式。


 /* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 板磚 */
.MLGB {
    width: 1rem;
    height: 500px;
    background-color: antiquewhite;
}複製程式碼


document.documentElement.style.fontSize = window.innerWidth + "px";複製程式碼


前端響應式詳解


沒錯,就是這麼囂張,直接1rem。

那麼,這個1rem等於多寬呢?

就是我們的100%寬度,也就是等於,html標籤裡font-size設定的字型大小的值。

所以,1rem等於html根元素的font-size的數值大小。

不信的話,我們可以設定寬度為0.5rem。


/* 板磚 */
.MLGB {
    width: 0.5rem;
    height: 500px;
    background-color: antiquewhite;
}複製程式碼


前端響應式詳解


一圖勝千言,本文瞬間可以少寫1000字,開心。

那麼,除了rem,百分比,還有什麼辦法呢?

記住這一點,js是無所不能的。


 /* 板磚 */
.MLGB {
    /* 寬度不見啦! */
    height: 500px;
    background-color: antiquewhite;
}複製程式碼


document.getElementsByClassName("MLGB")[0].style.width = window.innerWidth + "px";複製程式碼


前端響應式詳解


所以大家看到沒有,我們直接用萬能的js,直接給板磚設定等於視窗內容的寬度,不就行了?

所以,大家還記得前面的那個詞語,手段,嗎?

不是你不會響應式,是因為,你的手段不夠毒辣!

你百分百掌握著響應式的法術,卻無法施展,為啥呢?你缺乏心法。

還好,我這有無數的心法,關注我,我教你心法。


情況當然沒這麼簡單


真正的歷練,才剛剛開始。


前端響應式詳解


假設我們接到這樣一個,開發天貓雙十一主戰場頁面...的異想天開的任務。


<div class="MLGB">
    <!-- 頭部 -->
    <div class="header">
        歡迎大家來到,雙十一天貓主會場!
    </div>
    <!-- 分會場入口 -->
    <div class="nav">
        <a class="box" href="##">鞋子</a>
        <a class="box" href="##">箱包</a>
        <a class="box" href="##">數碼</a>
        <a class="box" href="##">服裝</a>
        <a class="box" href="##">樂器</a>
        <a class="box" href="##">戶外</a>
        <a class="box" href="##">傢俱</a>
        <a class="box" href="##">傢俱</a>
        <a class="box" href="##">影視</a>
        <a class="box" href="##">美食</a>
    </div>
</div>複製程式碼


/* 搬磚 */
.MLGB {
    height: 500px;
    background-color: antiquewhite;
}
.header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.nav {
    height: 100px;
}
.box {
    display: block;
    width: 10%;
    float: left;
    height: 100px;
    line-height: 100px;
    text-align: center;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


前端響應式詳解


我們刷刷刷,幾個分會場入口就佈局完了。

然後,我們一邊欣賞這個10分鐘之內創造的藝術品,一邊品嚐這我們前面的青椒炒肉不放辣椒的時候。

測試跑了過來...


前端響應式詳解


雞哥,雞哥,出問題了!

嗯!你眼露殺氣,在測試和他的手機之間,以每秒300赫茲的頻率,來回掃描。

不,這不可能,我是一個合格的高階前端工程師,你這是什麼手機?哼,我拿自己的瞧瞧。

於是,10秒鐘後...

小李啊,你回去吧,這個BUG,我來解決。


 /* 搬磚 */
.MLGB {
    height: 500px;
    background-color: antiquewhite;
}
.header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.nav {
    height: 100px;
}
.box {
    display: block;
    width: 100%;
    max-width:187px;
    float: left;
    height: 100px;
    line-height: 100px;
    text-align: center;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


前端響應式詳解


你陷入了沉思,經過短短3個小時的深思熟慮,將CSS改成如上。

你發現,入口雖然排版變好看了,但是,入口元素高度卻超出板磚盒子範圍了,而且,nav的高度也是固定的。

於是,你動手優化了起來。


 /* 搬磚 */
.MLGB {
    /* height: 500px; */
    background-color: antiquewhite;
}
.header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.nav {
    /* height: 100px; */
}
.nav::after{
    content:"";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
.box {
    display: block;
    width: 100%;
    max-width: 187px;
    float: left;
    height: 100px;
    line-height: 100px;
    text-align: center;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


前端響應式詳解


但是,你很快發現,測試又來了。

你有點懷疑,她是不是喜歡你?但是,手機上的測試效果,讓你暫時打消了這懷疑。


前端響應式詳解


沒錯,她的是iphone5,而你的是iphone6。

你很快發現了,那個box的寬度不能寫死。

彌留,哦,不,迷茫之際,你想起了昨天仔細研究過的《高階前端必會的flex佈局》。


 /* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 搬磚 */
.MLGB {
    /* height: 500px; */
    background-color: antiquewhite;
}
.header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.nav {
    /* height: 100px; */
    display: flex;
    flex-wrap: wrap;
}
.nav::after {
    content: "";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
.box {
    display: flex;
    justify-content: center;
    flex: 1 1 auto;
    min-width: 160px;
    height: 100px;
    line-height: 100px;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


前端響應式詳解


你的iphone6


前端響應式詳解


她的iphone5

你發現,你的iphone6,她的iphone5都正常了。


同時,更復雜的需求又來了


領導說,要做一個,使用者購物車,收藏,設定,檢視過的商品側邊欄,類似QQ那樣。PC端預設顯示,手機端預設隱藏,而且在頭部區域,顯示一個能夠點選彈出側邊欄的按鈕。


 /* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 搬磚 */
.MLGB {
    /* height: 500px; */
    background-color: antiquewhite;
}
.header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.nav {
    /* height: 100px; */
    display: flex;
    flex-wrap: wrap;
}
.nav::after {
    content: "";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
.box {
    display: flex;
    justify-content: center;
    flex: 1 1 auto;
    min-width: 160px;
    height: 100px;
    line-height: 100px;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


<div class="MLGB">
    <!-- 頭部 -->
    <div class="header">
        歡迎大家來到,雙十一天貓主會場!
    </div>
    <!-- 主要內容區域 -->
    <div class="main">
        <!-- 左側選單 -->
        <div class="menu">
            <div class="li">購物車</div>
            <div class="li">我的收藏</div>
            <div class="li">瀏覽記錄</div>
            <div class="li">已經購買</div>
            <div class="li">設定</div>
            <div class="li">退出</div>
        </div>
        <!-- 分會場入口 -->
        <div class="nav">
            <a class="box" href="##">鞋子</a>
            <a class="box" href="##">箱包</a>
            <a class="box" href="##">數碼</a>
            <a class="box" href="##">服裝</a>
            <a class="box" href="##">樂器</a>
            <a class="box" href="##">戶外</a>
            <a class="box" href="##">傢俱</a>
            <a class="box" href="##">傢俱</a>
            <a class="box" href="##">影視</a>
            <a class="box" href="##">美食</a>
        </div>
    </div>
</div>複製程式碼


前端響應式詳解


很快,PC端的效果就實現了。

令人頭疼的移動端該怎麼做呢?

萬能的js大人肯定是有辦法解決的,但是,殺雞焉用牛刀,難道就沒有更簡單的方法嗎?


前端響應式詳解


偉大的CSS大人,從來不會讓我們高階前端難堪。

它傳之於世的《CSS聖經》中,早已準備好了一切。

果然,亂軍從中,被你找到了蛛絲馬跡。

媒體查詢(@media),這個專為響應式而生的時勢英雄,終於要從塵封的歷史遺蹟中走出來了。


/* 重置一下 */
* {
    padding: 0;
    border: 0;
    margin: 0;
    outline: 0;
    box-sizing: border-box;
}
 /* 搬磚 */
.MLGB {
    /* height: 500px; */
    background-color: antiquewhite;
}
.header {
    display: flex;
    align-items: center;
    height: 50px;
    font-size: 18px;
    padding: 0 10px;
    color: #fff;
    text-align: center;
    background-color: #f97c7c;
}
.main {
    display: flex;
}
/* 切換選單的按鈕 */
.toggle-menu {
    height: 30px;
    line-height: 30px;
    text-align: center;
    width: 30px;
    font-size: 14px;
    background-color: #607d8b;
    margin-right: 10px;
}
/* 選單 */
.menu {
    flex: 0 0 140px;
    background-color: #5ed5e4;
}
.menu .li {
    height: 30px;
    line-height: 30px;
    padding: 0 10px;
    border-bottom: 1px solid #91dfe8;
}
.nav {
    /* height: 100px; */
    display: flex;
    flex-wrap: wrap;
    flex: 1 1 100%;
}
.nav::after {
    content: "";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
.box {
    display: flex;
    justify-content: center;
    flex: 1 1 auto;
    min-width: 160px;
    height: 100px;
    line-height: 100px;
    text-decoration: none;
    font-size: 18px;
    border: 1px solid #ddd;
}複製程式碼


<div class="MLGB">
    <!-- 頭部 -->
    <div class="header">
        <div class="toggle-menu">菜</div>
        <div class="title">歡迎大家來到,雙十一天貓主會場!</div>
    </div>
    <!-- 主要內容區域 -->
    <div class="main">
        <!-- 左側選單 -->
        <div class="menu">
            <div class="li">購物車</div>
            <div class="li">我的收藏</div>
            <div class="li">瀏覽記錄</div>
            <div class="li">已經購買</div>
            <div class="li">設定</div>
            <div class="li">退出</div>
        </div>
        <!-- 分會場入口 -->
        <div class="nav">
            <a class="box" href="##">鞋子</a>
            <a class="box" href="##">箱包</a>
            <a class="box" href="##">數碼</a>
            <a class="box" href="##">服裝</a>
            <a class="box" href="##">樂器</a>
            <a class="box" href="##">戶外</a>
            <a class="box" href="##">傢俱</a>
            <a class="box" href="##">傢俱</a>
            <a class="box" href="##">影視</a>
            <a class="box" href="##">美食</a>
        </div>
    </div>
</div>複製程式碼


前端響應式詳解


首先呢,你沒有管其他亂起八遭的東西,先簡單粗暴地讓這個選單顯示出來。

因為,作為一個擁有高階思維的高階前端,你知道,想那麼多是沒用的。

接下來你要幹嘛呢?你要把這個選單,隱藏起來,因為目前是PC端。


@media screen and (min-width: 500px) {
    .header .toggle-menu {
        display: none;
    }
}複製程式碼


前端響應式詳解


十分完美,@media果然厲害。

再接下來要幹嘛呢?

移動端按鈕顯示,選單隱藏。


 /* PC端要做的 */
@media screen and (min-width: 500px) {
    .header .toggle-menu {
        display: none;
    }
}
/* 移動端要做的 */
@media screen and (max-width: 500px) {
    .header .toggle-menu {
        display: block;
    }
    .menu {
        display: none;
    }
}複製程式碼


前端響應式詳解


看起來十分完美,不用費javascript一兵一卒就搞定了。

更何況,這個方法,比寫一堆js優雅多了。

接下來要幹嘛呢?給按鈕繫結點選事件,點選切換選單的display值就行了。

那麼,這裡呢,就暫且不表。

由於時間關係呢,站長還有很多事做,堅持每天寫一篇對於目前來說,已經有點難度了。

也是因為時間的關係,本文並沒有更加詳細地講述關於響應式的方方面面和各種解決方法,各種坑。

不過,也足以拋磚引玉,解決同學們的一部分關於響應式的疑惑。

記住那個妙言:響應不同螢幕裝置合適地展現網頁效果的方式或著手段。

響應式是一種解決不同螢幕正確且合適地顯示網頁內容的思想和方法,它並不等於框架,更不等於bootstrap。

知其然,知其所以然。


前端時空技術社群:前端網紅集結號,傳遞一線全棧技術,帶你穿越前端時空。

網站:www.fest.plus

語雀:www.yuque.com/fest

Github: www.githun.com/fest-plus

作者:前端時空-陳隨易

小編:前端時空-Jack Wang

更多精彩文章,請掃碼關注公眾號「前端時空」

                                           qrcode_for_gh_11f860dcf461_258.jpg


相關文章