前端響應式詳解


一兩年之前,我發現,不少人都被響應式搞得很懵逼。javascript

如今,我依然發現,仍是有不少人,依舊被響應式搞得很懵逼。html

因此,我也很懵逼。前端

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

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

因此,我不信,爲了天下沒有難學的編程,我打算繼續爲這萬分之一添磚加瓦。編程


什麼是響應式?


不少人之因此對響應式很懵逼,最基本的一個緣由就是,壓根就不懂什麼是響應式。bootstrap

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

沒錯,你說得頗有道理。bash

因此,我打算用下文,來詳細講解,什麼是響應式。前端工程師

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

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

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

爲了打破大家兩者之間的僵局,我打算揭下響應式這一層神祕的面紗。

響應式:響應不一樣屏幕設備合適地展示網頁效果的方式或着手段。

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



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

能夠看到,我這句解釋,很是妙。



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

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

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

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

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

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

因此,從這裏能夠得知,什麼是響應式?就是說,不一樣的屏幕,它不能一成不變地顯示同樣的內容,得根據屏幕大小,顯示合適的內容。

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

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

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

其次,咱們來看一下,這個不一樣屏幕的含義。

這個地方,很容易讓人啼笑皆非。

我遇到過不止一個同窗,絞盡腦汁地在思考,若是用戶縮放百分比,鼠標拖動屏幕調整大小,我該怎麼響應式?

兄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

相關文章
相關標籤/搜索