前端響應式佈局原理與實踐

前言

做爲一個前端開發者,響應式網站開發是必備技能之一。響應式有它的很好的優勢,也有它必定的缺點。這就須要咱們在開發的時候作出取捨。對於內容較少、主要爲展現類網站,故採用響應式;對於內容多,管理類的網站採用分開開發的方式,不一樣設備採用不一樣的一套代碼。本文會主要探討響應式佈局原理和技巧,並結合實例來加深印象。javascript

響應式與自適應

咱們不少人其實把這響應式和自適應兩種網站當成一回事,但事實上這兩種網站的佈局方式是有必定的區別的。咱們能夠來看看這兩種方法的概念以及分別對應解決的問題。css

什麼是響應式佈局?

響應式佈局就是一個網站可以兼容多個終端,能夠根據屏幕的大小自動調整頁面的的展現方式以及佈局,咱們不用爲每個終端作一個特定的版本。響應式網站的幾個標誌:html

  1. 同時適配PC + 平板 + 手機等;
  2. 標籤導航在接近手持終端設備時改變爲經典的抽屜式導航;
  3. 網站的佈局會根據視口來調整模塊的大小和位置;

在這裏插入圖片描述

什麼是自適應佈局?

自適應佈局是指網頁可以在不一樣大小的終端設備上自行適應顯示,也就是讓一個網站在不一樣大小的設備上顯示同同樣的頁面,讓同一個頁面適應不一樣大小屏幕,根據屏幕的大小,自動縮放。自適應佈局的幾個標誌:前端

  1. 大多隻是適配單個終端的主流N個主流視口;
  2. 當視口大小低於設置的最小視口時,界面會出現顯示不全,而且出現橫向滑動條;
  3. 整體框架不變,橫線佈局的版塊太多會有所減小。

在這裏插入圖片描述

如何選擇

總的來講,這兩種方式的原來是類似的,都是先檢測設備,根據不一樣的設備採用不一樣的CSS。那開發中咱們該如何去選擇?這就要結合響應式與自適應的優缺點來看。java

響應式佈局的優勢:
一、靈活性強;二、可以快捷解決多設備顯示適用問題。css3

缺點:
一、效率較低,兼容各設備工做量大;二、代碼較爲累贅,加載時間會加長;三、在必定程度上改變了網站原有的佈局結構。git

自適應佈局的優勢:
一、對網站複雜程度兼容更大;二、代碼更高效;三、測試和運營都相對容易和精準。github

缺點:
一、同一個網站須要爲不一樣的設備開發不一樣的頁面,增長的開發的成本。web

上面兩種方法各有本身的優缺點,因此咱們在開發的時候,要從實際的項目出發。對於頁面不是太複雜的狀況下,咱們能夠利用響應式佈局;而對於頁面中信息較多,佈局較爲複雜的狀況,咱們能夠採用自適應佈局的方式。瀏覽器

響應式佈局設計步驟

介紹完基本的概念,咱們來看看響應式佈局的基本步驟,主要分爲下面幾步:
1.設置meta標籤

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

2.使用@Media查詢來設置樣式,這是響應式佈局的核心

@media screen and (max-width: 1920px) { ... }

3.設置佈局分界點,即經過設置多種視圖寬度樣式來控制頁面佈局

@media screen and (max-width: 1920px) { ... }

@media screen and (max-width: 1700px) { ... }

其實仍是很簡單的,就是在適配的時候稍微有點點繁瑣。

佈局分界點

對於@Media查詢的分界點,這個能夠根據本身的項目來調整,設置合適本身項目的佈局分界點。在設置分界點時,要注意前後順序,當使用max-width數值大的在前面,數值小的在後面;當使用min-width時,數值小的放前面,數值大的放後面。下面列出了我在項目開發時所設置的部分佈局分界點:

@media screen and (max-width: 1920px) { ... }

@media screen and (max-width: 1700px) { ... }

@media screen and (max-width: 1600px) { ... }

@media screen and (max-width: 1440px) { ... }

@media screen and (max-width: 1280px) { ... }

@media screen and (min-width: 992px) and (max-width: 1200px) { ... }

@media screen and (min-width: 768px) and (max-width: 991px) { ... }

@media screen and (max-width: 767px) { ... }

那咱們何時用min-width,何時用max-width呢?一般來講,若是是移動端優先,則用min-width;若是是PC端優先,則用max-width

佈局單位

熟悉經常使用的佈局單位仍是很重要的,經常使用的佈局單位包括像素(px),百分比(%),emremvw/vh。咱們能夠合理的運用這些佈局解決方案,來提升咱們開發時的效率和質量。

像素

像素是網頁佈局的基礎,一個像素表示計算機屏幕所能顯示的最小區域。像素分爲兩種類型:css像素和物理像素。二者區別以下:

css像素:爲web開發者提供,在css中使用的一個抽象單位;
物理像素:只與設備的硬件密度有關,任何設備的物理像素都是固定的。

百分比

當瀏覽器的寬度或者高度發生變化時,經過百分比單位可使得瀏覽器中的組件的寬和高隨着瀏覽器的變化而變化,從而實現響應式的效果。通常咱們的直觀理解都會認爲子元素的百分比徹底相對於直接父元素,這種理解沒問題,好比heightwidth屬性。可是在css的盒模型中不止有heightwidth屬性,還有paddingbordermargin等屬性,因此這就值得咱們去具體分析一下。

咱們先寫好html代碼,而後經過不一樣的css代碼來看看會呈現出什麼樣的狀況:

<div class="parent">
    <div class="child">子元素</div>
</div>

1.子元素的height和width

當子元素的heightwidth使用百分比時,是相對於直接父元素的heightwidth進行變化的。

.parent{
    width: 200px;
    height: 200px;
    background: #aaaaaa;
}
.child{
    width: 50%;
    height: 50%;
    background: red;
}

在這裏插入圖片描述

2.子元素的top、bottom 、left和right

子元素的topbottom若是設置百分比,則相對於直接非static定位(默認定位)的父元素的高度;
子元素的leftright若是設置百分比,則相對於直接非static定位(默認定位的)父元素的寬度。

.parent{
    width: 200px;
    height: 200px;
    background: #aaaaaa;
    position: relative;
}
.child{
    width: 50%;
    height: 50%;
    background: red;
    position: absolute;
    top: 50%;
    left: 50%;
}

在這裏插入圖片描述

3.子元素的padding

子元素的padding若是設置百分比,不管是垂直方向或者是水平方向,都相對於直接父親元素的width,而與父元素的height無關。

.parent{
    width: 300px;
    height: 400px;
    background: #aaaaaa;
}
.child{
    width: 50%;
    height: 50%;
    background: red;
    padding-top: 20%;
    padding-left: 20%;
}

在這裏插入圖片描述

打開控制檯,查看子元素,咱們能夠看見padding-toppadding-left都爲父元素width的20% ——60px:
在這裏插入圖片描述

4.子元素的margin

子元素的marginpadding是同樣的,子元素的margin若是設置成百分比,不管是垂直方向仍是水平方向,都相對於直接父元素的width

5.子元素的border-radius

border-radius設置爲百分比則是相對於自身的寬度

.parent{
    width: 200px;
    height: 200px;
    background: #aaaaaa;
}
.child{
    width: 50%;
    height: 50%;
    background: red;
    border-radius: 50%;
}

在這裏插入圖片描述

em和rem

emrem相對於px更具靈活性,他們都是相對長度單位,而他們之間的區別能夠用一句話來歸納:em相對於父元素,rem相對於根元素。
em是相對於父元素的font-sizerem則是相對於html元素的font-size

vw/vh

vw/vh是與視圖窗口有關的單位,vw表示相對於視圖窗口的寬度,vh表示相對於視圖窗口高度,除了vwvh外,還有vminvmax兩個相關的單位。

單位 含義
vw 相對於視窗的寬度,視窗寬度是100vw
vh 相對於視窗的高度,視窗高度是100vh
vmin vw和vh中的較小值
vmax vw和vh中的較大值

這個單位和百分比很相似,可是仍是有區別的:

單位 含義
% 大部分相對於祖先元素,也有相對於自身的狀況好比(border-radius、translate等)
vw/vm 相對於視窗的尺寸

響應式佈局實踐

好了,說了這麼多,咱們如今能夠結合上面的理論知識,來完成一個響應式佈局的demo。下面我會貼出部分代碼來說一些思路,完整的代碼放在了個人github上面。

初始佈局

首先,咱們進行總體的佈局,這個demo主要分爲三部分:頭部、內容、底部,相似於簡單的企業官網。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>響應式佈局實踐</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="root">
    <!-- 頭部 -->
    <header>
        <div class="header-box">
            <div class="logo">
                logo
            </div>
            <nav class="main-nav">
                <ul class="nav-list">
                    <li id="nav-item" class="main-nav-item">
                        <ul class="nav-main-list">
                            <li class="list-item">首頁</li>
                            <li class="list-item">文章</li>
                            <li class="list-item">論壇</li>
                            <li class="list-item">娛樂</li>
                            <li class="list-item">聯繫</li>
                        </ul>
                    </li>
                    <li class="main-nav-login">
                        <div class="login-box">登陸 | 註冊</div>
                    </li>
                </ul>
            </nav>

        </div>
    </header>

    <!-- 內容 -->
    <div id="container">
        <div class="container-header"></div>
        <div class="content">
            <!-- 內容一-->
            <div class="content-box content-box1">
                <div class="content-box1-text"></div>
                <div class="content-box1-img">
                    <div class="img-radius"></div>
                </div>
            </div>
            <!-- 內容二-->
            <div class="content-box content-box2">
                <div class="content-box2-text"></div>
                <div class="content-box2-text"></div>
                <div class="content-box2-text"></div>
            </div>
            <!-- 內容三-->
            <div class="content-box content-box3">
                <div class="content-box3-text"></div>
                <div class="content-box3-text"></div>
                <div class="content-box3-text"></div>
                <div class="content-box3-text"></div>
                <div class="content-box3-text"></div>
                <div class="content-box3-text"></div>
            </div>
        </div>
    </div>

    <!-- 底部 -->
    <footer></footer>
</div>

</body>
</html>

在這個demo中,最初的css代碼是在1920px下進行編寫的,這個就是咱們的初始樣式。
初始樣式代碼比較長,就不貼在文章裏面了,看這裏>>> index.css
咱們先來看看初始的效果:
在這裏插入圖片描述
在實際開發的時候,有些模塊中包含的內容,使得這些模塊不能無限制的進行縮小。因此在index.css的初始佈局中,咱們對一些模塊的大小進行了限制,設置了min-width

中大屏適配

前面咱們提到,佈局分界點是要根據實際的項目來進行劃分的,我針對這個項目進行了如下的劃分,你們也能夠根據本身的想法來進行劃分。

1201px~1280px

咱們先看看把寬度調到1201px時會出現什麼狀況:
在這裏插入圖片描述
咱們能夠看見部分模塊超出了父元素的寬度,使得頁面變得良莠不齊了,因此咱們就要對佈局進行調整了:

@media screen and (max-width: 1280px) {
     /* 內容一  */
    .content-box1{
        flex-wrap: wrap;
        height: 650px;
    }
    .content-box1-text{
        width: 90%;
        margin: 0 auto;
    }
    .content-box1-img{
        display: flex;
        align-items: center;
        margin: 0 auto;
    }
}

再來看佈局狀況:
在這裏插入圖片描述

992px~1200px

這時候出現的狀況:
在這裏插入圖片描述
咱們看到,佈局又混亂了,而後咱們須要繼續調整佈局:

@media screen and (min-width: 992px) and (max-width: 1200px) {
    /* 內容二 */
    .content-box2{
        height: 400px;
    }
    .content-box2-text{
        height: 300px;
        min-width: 200px;
    }

    /* 內容三 */
    .content-box3{
        justify-content: space-around;
    }
}

再來看看佈局狀況:
在這裏插入圖片描述

768px~991px

在這個分界點時,一樣會出現佈局問題,因此要進一步實現調整,由於是重複操做,這裏就不貼圖和代碼了。咱們能夠重點看看下面的適配。

手機端適配

在boostrap的柵格系統中,把<768px的屏幕歸爲手機。咱們也能夠以此做爲參考。此時佈局調整不只僅是內容的調整,咱們的導航欄也要發生改變——由橫向導航欄變爲點擊出現的縱向導航欄(具體需求,具體實現,這裏只是提出一種廣泛的變換方法)。以下圖所示:
在這裏插入圖片描述
要想實現上圖中的效果咱們須要作哪些事情呢?

  1. 寫一個按鈕,如右圖右上角的按鈕,樣子是否是很熟悉;
  2. 導航條樣式重寫,由橫向導航條變爲縱向導航條;
  3. 利用js實現點擊按鈕,導航條顯示與隱藏的切換。

按鈕

咱們先在類名爲nav-list的末尾加入如下HTML代碼:

...

<li class="phone-show">
    <div id="nav-btn" class="nav-btn">
        <span></span>
        <span></span>
        <span></span>
    </div>
</li>

...

而後對按鈕樣式進行美化:

@media screen and (max-width: 767px){
    ...
    .phone-show{
        display: block;
        height: 60px;
        width: 60px;
    }
    .nav-btn{
        height: 100%;
        width: 100%;
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        justify-content: space-around;
    }
    .nav-btn span{
        display: inline-block;
        height: 10px;
        width: 60px;
        background: coral;
    }
}

看看效果:
在這裏插入圖片描述

導航樣式修改

這個咱們能夠巧妙的運用一個相對定位和絕對定位的關係實現導航條樣式和位置的修改:

@media screen and (max-width: 767px){
    .header-box{
        position: relative;
    }
    
    ...
    
    /* 手機端樣式 */
    .main-nav-item{
        display: none;
        position: absolute;
        width: 10rem;
        right: 0;
        top: 8rem;
        border-radius: 0 0 .5rem .5rem;
    }
    .nav-main-list{
        width: 100%;
        background: #ffffff;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        border-radius: 0 0 .5rem .5rem;
    }
    .list-item{
        width: 100%;
        margin: 0 1rem;
        border-bottom: 1px solid #eeeeee;
    }
}

看看效果:
在這裏插入圖片描述

導航條顯示和隱藏切換

利用js來控制切換的思路很簡單,咱們在網頁打開時,先把導航隱藏掉,而後定義一個變量hide,初始值爲true,點擊按鈕時進行判斷:若是hide值爲true,則讓導航顯示;反之隱藏。

let btn = document.getElementById("nav-btn");
let  nav =  document.getElementById("nav-item");

let hide = true;

btn.addEventListener('click', function () {
    if (hide){
        nav.style.display = "block";
        hide = false;
    } else {
        nav.style.display = "none";
        hide = true;
    }
});

手機端按鈕切換效果.gif
最後再進行一些細節方面的調整,咱們的響應式佈局demo就初步完成了。咱們在平常的開發的時候,通常來說不會這麼簡單,因此仍是也根據實際狀況去進行調整,以知足實際的需求。
完整demo點擊這裏——demo地址

參考

自適應和響應式的區別有哪些你知道嗎?
響應式和自適應有什麼區別?
響應式佈局的經常使用解決方案對比(媒體查詢、百分比、rem和vw/vh)

最後

文中如有不許確或錯誤的地方,歡迎指出~

相關文章
相關標籤/搜索