TimHsu 已發佈 2019-10-29

RWD-off-canvas 側邊選單練習

images

這次來練習一個比較進階的練習,是 RWD + off-canvas 側邊選單練習

這次練習會使用到 jQueryaddClassremoveClass 的語法,
對我來說 jQuery 雖然已經是包裝過的套件,但邏輯思維還是需要再努力,
這次也會有透過 JS 的設定在 body 裡面新增 class 的技巧。

這次要呈現的畫面在 PC 螢幕中如下圖,其實跟一般頁面相同,

images

在 pad 螢幕下呈現也會有漢堡選單(如下圖),但這邊的漢堡選單寫的內容與之前的那一篇 RWD 漢堡選單練習-讓漢堡顯示在 header 上有點不同,

images

這次 off-canvas 側邊選單有趣的地方是,點選漢堡選單後,會從左側滑出,可以更清楚看到選項(如下圖),

images

HTML

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="css/all.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css">
    <script src="js/jquery-3.4.1.min.js"></script>
    <script src="js/all.js"></script>
    <title>offcanvas_menu</title>
</head>

head 標籤內有幾個需要放入的資訊:

  1. 首先是為了響應式要放的 viewport 的這一行,一定要打上去喔!
  2. 這次有使用 fontawesome,新版的版本可以到這邊找對應的 CDN,這樣才能在網頁上正確的顯示
  3. script 標籤置入 jQuery 還有 建立 JS 資料夾,方法可以在這一篇找到。

要寫的網頁架構如下,註解的地方是這次需要注意的,有特別為行動版寫了兩行 a 連結按鈕,並用 fontawesome 作為圖示。

<div class="container">
        <div class="aside">
            <a href="#" class="mobile_close"><i class="fas fa-window-close"></i></a>
            <!-- 作為關閉選單用 -->
            <ul class="aside_menu">
                <li><a href="#">選單</a></li>
                <li><a href="#">選單</a></li>
                <li><a href="#">選單</a></li>
                <li><a href="#">選單</a></li>
            </ul>
        </div>
        <!-- aside end -->

        <div class="main">
            <!-- PC 顯示的目錄 -->
            <div class="header">
                <a href="#" class="mobile_open"><i class="fas fa-bars"></i></a>
                <!-- 作為手機版的側邊選單按鈕 -->
                <ul class="menu">
                    <li><a href="#">選單</a></li>
                    <li><a href="#">選單</a></li>
                    <li><a href="#">選單</a></li>
                    <li><a href="#">選單</a></li>
                </ul>
            </div>

            <div class="content">
                <h2>期間令人,在這另外。</h2>
                <p>就好隨意崇拜也在幾天專業上去材料不但禁止同時沒想到恐怖,本類告知體驗一週不在味道資料庫富岡包裝,和平上一頁,西部貨幣激烈國人採訪兒童取得反映衛生著名充分寂寞都有承擔,教程少女政策涉及出版社出來職務臺中太多規定各自我都還不,預計顏色未經出去城市,規格落實個。
                </p>
                <h2>期間令人,在這另外。</h2>
                <p>就好隨意崇拜也在幾天專業上去材料不但禁止同時沒想到恐怖,本類告知體驗一週不在味道資料庫富岡包裝,和平上一頁,西部貨幣激烈國人採訪兒童取得反映衛生著名充分寂寞都有承擔,教程少女政策涉及出版社出來職務臺中太多規定各自我都還不,預計顏色未經出去城市,規格落實個。
                </p>
                <h2>期間令人,在這另外。</h2>
                <p>就好隨意崇拜也在幾天專業上去材料不但禁止同時沒想到恐怖,本類告知體驗一週不在味道資料庫富岡包裝,和平上一頁,西部貨幣激烈國人採訪兒童取得反映衛生著名充分寂寞都有承擔,教程少女政策涉及出版社出來職務臺中太多規定各自我都還不,預計顏色未經出去城市,規格落實個。
                </p>
            </div>
        </div>

    </div>

    </div>
    </div>

重頭戲之一就在這裡,SCSS 有點複雜

下面這部分是基本的全域設定。

$primary-color:#ffbe0b;

body {
    background-color: #cfcfcf;
}

a {
    text-decoration: none;
    font-size: $font-m;
}

h2 {
    font-size: $font-l;
    font-weight: bold;
    padding-left: 16px;
    padding-top: 1em;
}

p {
    line-height: 1.8;
    padding: 1em;
}

//全域設定

HTML 所示,最外層是一個 container,為了讓 aside 一開始不要出現,
所以用了 overflow: hidden,這個語法,因為 aside 也是一個 div,會占滿上面的空間,所以先把它隱藏起來。
下方的 position: relative 是為了等等 aside 所做的相對定位。

.container {
    max-width: 1200px;
    margin: 0 auto;
    height: auto;
    overflow: hidden;
    position: relative;
}

開關按鈕的寫法

針對兩個 a 連結按鈕做的設定,特別拉出來寫的原因,避免程式碼過長。

.mobile_close,
.mobile_open {
    display: inline-block;
    // 使用 inline-block 才可以調整大小
    font-size: $font-m;
    padding: 1px;
    color: $primary-color;
    line-height: 50px;
}
// pad 螢幕以下 a 連結按鈕的共用設定(漢堡選單跟關閉)

.mobile_open {
    display: none;

    @include pad {
        display: inline-block;

    }
}

.fas {
    padding: 1em;
}
//pad 螢幕以下按鈕設定

aside

針對 aside 的設定,這一段是之前沒有遇到過的,
這邊使用 transform: translateX 的語法,在效能上會比較好。

.aside {
    overflow: hidden;
    // 在 PC 時隱藏
    width: 270px;
    background-color: #333;
    transform: translateX(-270px);
    // 在 PC 顯示下,往左邊推擠到 container 外
    position: absolute;
    top: 0;
    bottom: 0;
    // 將 aside 選單絕對定位在 container 上,並且使用上方與下方都為 0px ,靠左邊對齊,讓 header 可往上移動


    @include pad {
        display: block;
        border-right: 3px solid $primary-color;
        transition: all 0.5s;

        li {
            margin: 1em;
            // 在 pad 螢幕用 margin 推擠出 li 的空間

            a {
                display: block;
                // 在 pad 螢幕下屬性改成 block 佔滿整行
                color: $primary-color;
                border-bottom: 1px dashed $primary-color;
                padding: 1em;

                &:hover {
                    background-color: $primary-color;
                    color: #333;
                    transition: 0.3s;
                }
            }
        }
    }
}
.main{
    transform: translateX(0px);
    transition: all 0.5s;
    // 讓 aside 在收闔時,可以同步收闔
}

.header {
    background-color: #333;
    height: 50px;
    border-bottom: 3px solid $primary-color;

    .menu {
        float: right;
        margin-right: 1em;

        li {
            float: left;

            a {
                color: $primary-color;
                font-size: $font-m;
                padding-right: 1em;
                padding-left: 1em;
                line-height: 50px;

                &:hover {
                    background-color: $primary-color;
                    padding-top: 17px;
                    padding-bottom: 15px;
                    color: #333;
                    transition: all 0.3s;
                    // 滑鼠移過去有漸變效果
                }
            }
        }
    }

    @include pad {
        .menu {
            display: none;
            // 在 pad 螢幕以下會不顯示選單
            transition: all 0.5s;

            li {
                float: left;

                a {
                    display: block;
                    // pad 螢幕以下 aside 選單內的 a 連結顯示占滿整行
                    color: $primary-color;
                    line-height: 50px;
                    border-bottom: 1px dashed $primary-color;
                    transition: all 0.5s;

                    &:hover {
                        background-color: $primary-color;
                        color: #333;
                    }
                }
            }
        }
    }
}

寫到這邊感受到 SCSS + RWD 的強大威力,程式碼很直觀,也非常直覺的思考
用過 SCSS 真的很難回去直接單純寫 CSS。

因為要透過 jQuery 在網頁點擊觸發事件時,自動在 body 上命名一個 class
讓選單可以做收闔的功能,所以特別寫了這行 CSS。

// 透過 jQuery 增加 class open 觸發選單
.open {
    .main {
        transform: translateX(270px);
        // 當觸發 .open 時,main 會跳出選單
        transition: all 0.5s;
    }

    .aside {
        transform: translateX(0);
        // 當觸發 .open 時, aside 會打開
        transition: all 0.5s;
    }
}

jQuery

最後附上 jQuery 語法

$(document).ready(function () {
    $('.mobile_open').click(function (e) {
        $('body').addClass('open');
        // 用 click 監聽 .mobile_open,當 click 觸發功能,會把 body 中的側邊選單打開       
    });

    $('.mobile_close').click(function (e) {
        $('body').removeClass('open')
        //用 click 監聽 .mobile_close,當 click 觸發功能,會把 body 中的側邊選單關閉

    });
});

//使用 JS 增加 class 名稱,不需要加上 .class

附上 codepen
https://codepen.io/hnzxewqw/pen/XWWaMwb

關於筆者

暱稱:TimHsu

介紹:前端工程師

Vue.js AngularJS

文章列表 文章列表