
橫向頂部選單(導覽列)
橫向頂部選單通常用於網站的主要導覽,呈現在頁面頂部並水平排列多個導覽連結。這種導覽列在桌面裝置上能直觀地顯示網站各個主要章節的連結,而在行動裝置上則需要調整呈現方式以節省空間。例如,我們常在手機版網站上看到所謂的「漢堡選單」(☰ 漢堡圖示)——點擊該圖示後才展開選單項目。接下來,我們將分步實作一個橫向頂部選單,包含桌面版的水平連結排列,以及行動版的漢堡圖示切換功能。
Step 1:HTML 結構
首先,使用語意化的 <nav> 元素建立導覽區塊。在其中放入一系列導覽連結(例如以 <a> 包裝的頁面名稱)。另外,我們加入一個特殊的連結(或按鈕)元素作為漢堡選單圖示,用來在小螢幕裝置上切換選單的顯示。以下是範例 HTML:
<nav class="topnav" id="myTopnav">
<a href="#home" class="active">Home</a>
<a href="#news">News</a>
<a href="#contact">Contact</a>
<a href="#about">About</a>
<!-- 漢堡選單圖示(僅在小螢幕時可見) -->
<a href="javascript:void(0);" class="icon" onclick="myFunction()">☰</a>
</nav>
上述結構中,.topnav 是導覽列容器的 class。我們在最後一個 <a> 使用 class="icon" 並放入漢堡符號 ☰(☰),這個鏈結不導向任何頁面,而是在點擊時觸發 myFunction() JavaScript 函式來切換選單顯示。class="active" 可用於目前所在頁面的鏈結以高亮顯示。
Step 2:CSS 樣式
接著,為導覽列設計樣式。桌面寬度時,我們希望所有 <a> 連結橫向排列並平分在頂部橫列。行動裝置窄屏時,我們則將連結垂直堆疊並隱藏非必要項目,僅保留一個「菜單」圖示供使用者展開。以下是範例 CSS:
/* 頂部導覽列的基本樣式 */ .topnav { background-color: #333; overflow: hidden; /* 隱藏溢出的元素(用於小螢幕下展開時控制高度) */ } /* 導覽列內的連結樣式:預設橫向排列 */ .topnav a { float: left; /* 水平排列 */ display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; } /* 滑鼠懸停鏈結時 */ .topnav a:hover { background-color: #ddd; color: black; } /* 表示目前頁面的鏈結(active 類別) */ .topnav a.active { background-color: #04AA6D; color: white; } /* 小螢幕下隱藏除了第一個鏈結以外的所有項目,僅顯示漢堡圖示 */ @media screen and (max-width: 600px) { .topnav a:not(:first-child) { display: none; } .topnav a.icon { float: right; display: block; } } /* 小螢幕下展開選單時的樣式 */ @media screen and (max-width: 600px) { .topnav.responsive { position: relative; } .topnav.responsive a.icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } }
以上樣式設定了解決響應式需求:當畫面寬度小於600px時(可根據需求調整斷點),我們利用媒體查詢將 .topnav a:not(:first-child) 隱藏,只顯示第一個鏈結(通常可放品牌名稱或首頁)以及漢堡選單圖示 .topnav a.icon。點擊漢堡圖示後,我們會以 JavaScript 在 .topnav 元素上動態加入一個 responsive 類別,觸發第二段媒體查詢內的樣式。此時導覽列容器設為 position: relative,漢堡圖示定位在右上角,其餘鏈結則恢復為區塊顯示且取消浮動,垂直排列呈現,這樣在小螢幕上就能以下拉方式顯示完整選單。
Step 3:JavaScript 互動行為
有了上述結構和樣式,最後透過一小段 JavaScript 程式碼讓漢堡圖示控制選單的開合。實現方式是切換 .topnav 容器的類別名稱:
function myFunction() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive"; // 加上 "responsive" 類別
} else {
x.className = "topnav"; // 移除 "responsive" 類別
}
}
上述函式透過檢查 .topnav 元素當前的 className,在點擊時增減 "responsive" 類別。當使用者第一次點擊漢堡圖示時,類別從"topnav"變成"topnav responsive",對應的 CSS 會顯示出先前隱藏的連結;再次點擊則復原類別,隱藏選單。這種切換類別的方式非常簡潔,整段程式碼在幾行內即可完成選單的顯示/隱藏切換功能。另外,我們設定漢堡圖示(☰)浮於右上角,方便使用者點擊。一般來說,針對行動裝置的操作習慣,我們也確保點擊區域足夠大,方便手指點選——Apple 的官方指引建議可點擊元素至少應有約 44 點(約 57px)見方的區域。因此我們在 CSS 中給予鏈結適當的內距 (padding),以增加點擊熱區,提升行動端的使用體驗。
完成以上三步,一個簡單的響應式頂部導覽列就製作完成了。您可以在桌面瀏覽器中看到水平導航列,而當縮小瀏覽器寬度或在手機上查看時,僅會顯示漢堡選單圖示,點擊圖示即可展開完整選單。這種模式特別適合主要導覽項目不多的網站。如果選單項目很多,或者希望在小螢幕上採用不同呈現,則可以考慮側邊欄選單或其他模式,以下將繼續介紹。
側邊欄選單(Off-canvas 側滑選單)
側邊欄選單是一種從頁面側邊滑出的垂直導覽選單。常見於行動應用或網站的行動版,例如點擊漢堡圖示後,畫面從左側(或右側)推展出一個覆蓋全頁的選單列表。側邊欄選單適合導覽項目較多或階層結構較深的情況,因為垂直空間更充裕。此外,在桌面版網站中,側邊欄有時用作永久可見的導航欄(例如後台控制台或文件目錄)。接下來,我們介紹如何以 <nav> 和 CSS、JS 製作一個可切換的側邊欄選單。
Step 1:HTML 結構
側邊欄選單的 HTML 結構包含兩部分:側邊欄本體和觸發開啟的控制元件。我們使用 <nav id="mySidenav" class="sidenav"> 作為側欄容器,其中包含數個導覽用的 <a> 連結。另外在側欄內的頂部放一個關閉按鈕(這裡使用特殊字元 × 生成關閉叉叉"×"符號)。側邊欄以外,我們放一個元素(例如按鈕或<span>)作為開啟按鈕。範例如下:
<!-- 側邊欄導覽區塊 --> <nav id="mySidenav" class="sidenav"> <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a> <a href="#">About</a> <a href="#">Services</a> <a href="#">Clients</a> <a href="#">Contact</a> </nav> <!-- 頁面其他內容 --> <div id="main"> <span class="open-menu" onclick="openNav()">☰ 開啟選單</span> <h2>我的網站內容</h2> <p>...這是主要內容區域...</p> </div>
在上述結構中,<nav id="mySidenav" class="sidenav"> 是我們的側邊欄選單,預設情況下它是隱藏在畫面左側(或右側)的位置。側邊欄內第一個 <a> 帶有 class="closebtn" 且 href="javascript:void(0)",點擊時呼叫 closeNav() 來關閉選單,用 × 顯示關閉符號 ×。接下來是一系列導覽連結項目。側邊欄外部的 <span class="open-menu"> 則作為開啟按鈕,內容使用了漢堡圖示 ☰ 加上文字「開啟選單」,並在點擊時執行 openNav() 函式。這個開啟按鈕我們放在主要內容區塊 (#main) 內,實際項目中也可將它放在頁首 <header> 區域以符合設計需求。
Step 2:CSS 樣式
接下來,我們為側邊欄選單設計樣式,使其能夠滑入滑出頁面。核心思路是透過調整側邊欄容器的寬度來控制顯示與否。預設狀態寬度為0(隱藏側欄),點擊開啟時將寬度設為固定值(例如250px)讓其露出部分或全幅內容。以下是範例 CSS:
/* 側邊欄選單容器的基本樣式 */ .sidenav { height: 100%; /* 高度佔滿螢幕 */ width: 0; /* 初始寬度為0(隱藏) */ position: fixed; /* 固定定位在視窗 */ top: 0; left: 0; /* 靠左側出現(如需從右側滑出可設 right:0 並調整開啟按鈕位置) */ background-color: #111; overflow-x: hidden; /* 隱藏水平滾動(內容溢出時不水平捲動) */ transition: 0.5s; /* 添加過渡效果 (0.5秒) */ z-index: 1000; /* 確保側欄在最上層 */ } /* 側邊欄內部連結樣式 */ .sidenav a { display: block; color: #818181; padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; transition: 0.3s; } /* 滑鼠移過連結時變色 */ .sidenav a:hover { color: #f1f1f1; } /* 關閉按鈕 (叉叉) 的樣式,固定在側欄右上角 */ .sidenav .closebtn { position: absolute; top: 0; right: 25px; font-size: 36px; margin-left: 50px; } /* (可選)小螢幕優化:高度太小時調整內距和字體 */ @media screen and (max-height: 450px) { .sidenav { padding-top: 15px; } .sidenav a { font-size: 18px; } }
以上 CSS 使得側邊欄選單在初始時完全隱藏在左側,position: fixed 確保其脫離文檔流且覆蓋在畫面上。當 .sidenav 寬度從 0 增加到 250px 時,就會呈現一個側邊面板的效果,並透過 transition: 0.5s 使其具有平滑滑出的動畫。我們也設計了連結的樣式,預設字體顏色偏淡,在使用者懸停時變亮,強調連結的可點擊性。關閉按鈕 .closebtn 利用 position: absolute 固定在側欄內右上角,方便使用者關閉選單。
註:上述範例將側欄定位在左側(left:0)。如果您想要側邊欄從右側滑出,只需將 .sidenav 的 left: 0 改為 right: 0,同時確保開啟按鈕(漢堡圖示)放置在頁面右側即可,其他程式碼無需改動。
Step 3:JavaScript 互動
現在,透過 JavaScript 來控制側邊欄的開啟與關閉。原理很簡單:改變側邊欄元素的樣式屬性(寬度)即可。以下是 openNav() 和 closeNav() 的實作:
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
當使用者點擊漢堡圖示(開啟選單),openNav() 會將側邊欄容器的寬度設置為 250px,使其從螢幕邊緣滑出。這個寬度數值可依實際內容調整;250px 大約可容納幾個短連結字串。點擊側邊欄內的關閉叉叉時,closeNav() 將寬度重設為0,側欄隨即滑回隱藏。由於我們在 CSS 中設定了過渡效果,寬度變化會產生平滑的動畫。
上述方式屬於覆蓋式側欄,即側邊欄展開時覆蓋在主要內容上方。如果希望側欄展開時推移主內容(而非覆蓋),可以在開啟和關閉函式中同時調整主要內容容器(例如上例的 #main)的 margin-left,以配合側欄寬度推移。另外,也可以在開啟側欄時透過修改 document.body 的樣式加入半透明背景色,實現背景內容變暗的效果,以突出側欄。這些增強效果可以根據需求自行取捨。
現在,我們已完成一個基本的響應式側邊欄選單。當在行動裝置上,點擊「開啟選單」漢堡圖示,側欄會滑出呈現導覽項目列表;使用者點擊關閉按鈕或頁面其他區域即可收起選單。如果您希望在桌面寬度時始終顯示側邊欄,只需使用媒體查詢為較大螢幕設定 .sidenav { width: 250px; } 以及相應的主內容 margin,即可讓側欄固定展開充當側面導航列。
下拉式選單(階層選單)
下拉式選單通常用於具有子選單的導覽項目,讓使用者滑鼠懸停或點擊某個父選單時,展開一組相關的子選項列表。例如網站的主選單列中,「產品」或「服務」下可能還有更詳細的分類連結,這時就適合用下拉式選單來隱藏次級連結,按需顯示。以下我們將介紹如何以 HTML 列表和 CSS、JavaScript 實作一個簡單的下拉式選單。
Step 1:HTML 結構
下拉選單一般結構為巢狀的清單:主導覽項目中含有子項目列表。我們可以繼續利用語意化的 <nav> 和 <ul> 列表來標示這種階層關係。範例如下:
<nav class="dropdown-nav">
<ul>
<li><a href="#">Home</a></li>
<li class="dropdown">
<a href="javascript:void(0);" class="dropbtn" onclick="toggleMenu()">產品介紹 ▾</a>
<ul class="dropdown-content" id="myDropdown">
<li><a href="#">產品 A</a></li>
<li><a href="#">產品 B</a></li>
<li><a href="#">產品 C</a></li>
</ul>
</li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
在上述 HTML 中,我們建立了一個 .dropdown-nav 容器,包含主選單項目的清單。<li class="dropdown"> 表示這是一個帶有下拉子選單的父項目。裡面首先是一個 <a> 作為父選單的標題(例如「產品介紹」),我們給它 href="javascript:void(0);" 以避免點擊跳轉,並添加 class="dropbtn" 以及 onclick="toggleMenu()"。這個連結文字後面的符號 ▾ (▼)只是個下拉箭頭圖示,提示使用者此項目可展開子選單。接著是一個子清單 <ul class="dropdown-content" id="myDropdown">,其中包含若干子選單項目列表(產品 A/B/C)。我們將這個子選單 <ul> 設定了 id="myDropdown" 以便 JS 操作,並賦予 .dropdown-content 類別以應用下拉選單樣式。
這樣的結構清晰定義了層級:主 <ul> 下的某個 <li> 包含一個子 <ul>。接下來透過 CSS 和 JS 讓子選單預設隱藏、需要時顯示。
Step 2:CSS 樣式
下拉選單的關鍵在於隱藏和顯示子選單容器。我們希望平時子選單是看不見的,只有當使用者展開時才出現。因此,我們預先將 .dropdown-content 設為 display: none。同時,為了讓下拉層浮在其他內容之上,我們會使用 position: absolute 定位子選單容器。以下是範例 CSS:
/* 下拉式選單的父容器,需要相對定位以承接絕對定位的子選單 */ .dropdown { position: relative; display: inline-block; /* 讓.dropdown元素與其他導航項目並排 */ } /* 下拉選單按鈕的樣式 */ .dropbtn { background-color: #3498DB; color: white; padding: 16px; font-size: 16px; border: none; cursor: pointer; } /* 按鈕在滑鼠懸停或聚焦時的樣式變化 */ .dropbtn:hover, .dropbtn:focus { background-color: #2980B9; } /* 下拉選單的子清單容器,預設隱藏 */ .dropdown-content { display: none; position: absolute; background-color: #f1f1f1; min-width: 160px; /* 加一點陰影讓下拉層浮起來 */ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1000; } /* 下拉清單中的鏈結樣式 */ .dropdown-content a { display: block; color: black; padding: 12px 16px; text-decoration: none; } /* 滑鼠懸停在下拉清單鏈結時的背景變化 */ .dropdown-content a:hover { background-color: #ddd; } /* 顯示下拉清單:當我們用JS在.dropdown-content添加 .show 時 */ .show { display: block; }
上述 CSS 規定 .dropdown(父項目)使用 position: relative,這很重要——因為它的子元素 .dropdown-content 設為絕對定位時,將以 .dropdown 為參照定位。因此,下拉的子選單會正好定位在父選單按鈕的下方。.dropdown-content 本身背景色我們使用淡灰白色,並加上陰影效果讓它看起來像一個浮起的選單卡片。預設 .dropdown-content 是 display: none 隱藏的,只有當我們動態地在它元素上加上 .show 類別時,才切換為 display: block 顯示出來。
在 .dropbtn 的樣式中,我們將其外觀設計為一個按鈕風格(藍底白字,無邊框),並在 :hover 或 :focus 時改變底色,以提示此元素可互動。雖然這裡用了 <a> 元素作為按鈕,也可以直接使用 <button>,但無論哪種方式,cursor: pointer 都讓滑鼠經過時呈現手形圖示,強調可點擊性。
Step 3:JavaScript 互動
最後,用 JavaScript 來控制下拉子選單的顯示隱藏。我們將實作一個 toggleMenu() 函式,點擊父選單按鈕時切換子選單容器的 .show 類別;並在使用者點擊其他區域時自動關閉子選單,確保介面整潔。實作如下:
function toggleMenu() {
document.getElementById("myDropdown").classList.toggle("show");
}
// 使用者在頁面其他地方點擊時關閉下拉選單
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
// 如果點擊處不是 dropbtn,本頁所有下拉選單都收起
var dropdowns = document.getElementsByClassName("dropdown-content");
for (var i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
toggleMenu() 函式透過 DOM 選取子選單 <ul id="myDropdown"> 元素,切換它的 "show" 類別。當使用者點擊父選單(產品介紹)時,原本隱藏的 .dropdown-content 會被加上 .show 進而以 CSS 顯示出來;若再次點擊則移除類別隱藏。接著,window.onclick 事件監聽器用來捕捉全域點擊:當使用者點擊頁面上非下拉按鈕處時,我們遍歷所有可能打開的下拉選單,將帶有 .show 類別的元素一律移除該類別,確保所有下拉選單關閉。這段程式碼可以同時管理多個下拉選單的關閉行為(若頁面上有多個 .dropdown-content)。
現在,我們的下拉式選單功能已完整實現:在桌面裝置上,用戶可將滑鼠點擊「產品介紹」按鈕,子選單即下拉展現產品列表;在行動裝置上,由於沒有滑鼠懸停概念,一樣是透過點擊觸發展開,體驗一致。如果有需要,也可以改用滑鼠懸停觸發下拉(純 CSS:如 .dropdown:hover .dropdown-content { display: block; }),但須注意行動裝置上無法以 hover 觸發。此外,為了無障礙體驗,可以在按鈕元素上使用 aria-haspopup="true" 和 aria-expanded 等ARIA屬性,並在子選單上加上適當的 aria-label 做輔助描述;在本文範圍內我們重點講解實作原理,後續可再深入強化無障礙表現。
常見問答(Q&A)
Q1: 為什麼要使用 <nav> 元素來包裹導覽選單?可以直接用 <div>嵌套連結嗎?
A1: 可以使用其他容器標籤,但強烈建議使用 <nav>。<nav> 是 HTML5 引入的語意化元素之一,專門表示頁面的導航區塊。使用 <nav> 有利於搜尋引擎和輔助技術(如螢幕閱讀器)理解哪一區域是導航連結集合,從而提高可存取性和 SEO 表現。簡而言之,<nav> 讓程式碼更具語意且可讀性高,應優先考慮。
Q2: 漢堡選單圖示(☰)在桌面版網站上也適用嗎?
A2: 漢堡選單圖示主要流行於行動裝置上,因為小螢幕需要節省空間。在桌面版大螢幕上,一般建議直接展示完整的導覽列,而非隱藏在漢堡選單內。研究顯示,在桌面上強制使用漢堡選單可能降低使用者對網站功能的發現性,增加導航的摩擦。除非介面空間極為有限或設計上有特殊考量,否則應讓桌面使用者一眼就看到主要選單項目。當然,您也可以在超大畫面時展開所有選單、中等畫面時使用部分收合、小畫面完全收合,這就屬於響應式設計的調整範疇了。
Q3: 我可以不用 JavaScript,就純粹靠 CSS 實現上述選單效果嗎?
A3: 部分情況可以。例如利用 CSS 的 :hover、:focus-within 等選擇器可實現簡單的下拉選單互動,而漢堡選單的開合也有純 CSS 的「checkbox hack」或 :target 技巧。不過,純 CSS 解法往往在點擊外部區域關閉選單、觸控裝置支援等方面有侷限。為了提供更直覺可靠的體驗,通常還是會借助 JavaScript 控制狀態。當然,如果您的使用者群體可能禁用JavaScript,則需要為選單提供替代方案(例如在頁面底部放置傳統連結列表作為後備)。總的來說,CSS 能做基礎顯示隱藏,但 JavaScript 可以讓體驗更完善(如點擊外部區域關閉選單等功能),兩者各有所長,可以視需求結合使用。
Q4: 如何讓導覽選單更具美觀和動態效果?
A4: 您可以透過 CSS3 和一些額外的 JS 來增強視覺體驗。例如:
過渡與動畫:我們在側邊欄範例中用了 transition 來平滑寬度變化。同樣地,可對下拉選單使用 transition 或 animation 做淡入淡出效果,而非硬切換顯示。
圖示與字型:可引入圖示字型(如 Font Awesome)來使用更精美的漢堡菜單和關閉圖示,或下拉箭頭符號。範例中漢堡圖示我們直接用了 ☰,也可以 <i class="fa fa-bars"></i> 等等方式呈現。
主題樣式:透過 CSS 微調配色和版面,包含滑鼠懸停的效果、高亮當前頁的樣式、選單展開的陰影與邊框圓角等,都能讓導覽列更醒目美觀。
滾動與固定:讓導覽列在頁面滾動時固定在頂部(sticky效果)也是常見需求,可使用 position: sticky 或在滾動時以 JS 切換類別實現。
這些改進都不影響基本結構,但能提升使用者體驗。建議在掌握本文介紹的核心實作後,再逐步加入上述強化功能。
Q5: 如果網站有多級選單(下拉的子選單中還有子項),該如何處理?
A5: 多級選單(mega menu 或多重下拉)會大幅增加複雜度。可以考慮以下做法:
手風琴式:在行動裝置上,讓第2級選單以手風琴方式展開(點一下展開,再點一下收合),而不是滑鼠懸停。這需要在每個有子選單的項目上綁定點擊事件,切換對應子選單的顯示。
Mega Menu:在桌面端,如果子選單很多,可能以mega menu(大型展開面板)形式呈現,用更寬的下拉區域來容納多欄的連結列表。這需要較多的 CSS 佈局調整,可能運用 CSS Grid 或 Flexbox 來排版。
無障礙考量:多級選單更要注意鍵盤導航(如使用 Tab、方向鍵在菜單項間移動)以及ARIA屬性的正確運用,確保螢幕閱讀器用戶能理解選單層級。
由於多級選單實作較為繁瑣,建議先確定資訊架構是否需要如此多層次。很多情況下,可以透過簡化導航或在頁面內提供次級導航來避免過深的選單階層。如果確實需要多級下拉,考慮引用成熟的框架或元件庫也是不錯的選擇,它們通常已幫助處理好相容性和無障礙細節。
希望以上問答解答了您在實作響應式導覽選單時可能遇到的疑惑。透過這篇教學,我們學習了如何使用 <nav> 元素配合 HTML、CSS、JavaScript 打造三種常見的導覽選單:頂部橫向選單、側邊欄選單、以及下拉式子選單。這些範例強調了實務操作和互動體驗:從小螢幕漢堡選單的切換、側欄滑動效果、到子選單點擊展開/收合。我們也討論了各種情境下的設計考量和進階技巧。相信熟練掌握這些內容後,您可以靈活運用在自己的專案中,提供使用者流暢友好的導航體驗。祝您在前端開發之路上不斷進步,構建出出色的響應式網站!