一個簡單,響應式,流動式導覽
Chinese (Traditional) (中文(繁體)) translation by Erica Wong (you can also view the original English article)
我們將構建一個簡單,響應式的網頁菜單選項。這個方法將有助在設計手機界面時把重點放在網頁的內容上。我們將不會用上JavaScript,而我們先從設計流動式界面開始。
流動式導覽
如果你讀過 Luke Wroblewski's Mobile First 你會比較熟悉他的想法是:
一般的規則是,內容理應比手機的導覽優先。
他指的是手機用戶往往是想即時找出回答;他們希望直接找到他們想要的,而不是更多的選項。
很多網站,甚至是響應式的,都習慣把導覽應該放在所有網頁的頂部,但這種方法可能會導致高親合力的問題。因為手機用戶往往缺乏兩樣東西:屏幕空間和時間。如果主導覽被放置在網頁的頂部,很有可能它會掩蓋整個手機屏幕。當導覽的鏈接為手機用戶變得更大更容易接時,問題更是變得嚴重。往往迫使手機用戶一直滾動至不見導覽才看到內容。
這個便是一個例子 London & Partners:

一個很好的響應式設計,但在標準的手機屏幕尺寸( 320px x 480px )你只能看到導覽菜單。當然,我也會想在首頁看到導覽菜單以外的東西吧?這不只是 London & Partners - 而是有很多類似的響應式網頁。
那麼有什麼解決方法呢?
我們也經常看到設計師們用jQuery來解決這個問題,來看看Chris Coyier's explanation 裡的 Five Simple Steps 響應下拉式菜單吧。



大屏幕,小屏幕。
用jQuery 複製出一個 <select> 的下拉式菜單,然後把這個複製出的菜單隱藏起來。在小屏幕下,media queries 便會把原有的菜單隱藏,呈現複製的下拉式菜單。這是很好的方法,因為下拉式菜單只佔用很小的位址和善用手機特有的界面(像iPhone的滾動條)。
或者,你可以隱藏導覽菜單,然後當點擊"菜單"的按鈕時才出現。Twitter 的 latest Bootstrap 有這樣的示範。



在較小的屏幕導覽菜單會被隱藏,並顯示一個"列表"的圖標(很快便成為公認"菜單"標示),當點擊它是真正的導覽菜單便會出現。手機用戶不但可以看到想看到的內容,同時也有導覽菜單讓他們可以看到更多內容。



純CSS解決方法
以下我們將會使用 Luke 討論的方法,使用CSS和優先處理流動式導覽。優先處理流動式是什麼意思?簡單地說,是要先設計一個小屏幕的界面,然後才設計大屏幕的界面。我們會用 media queries 偵測屏幕的尺寸變更,然後逐步添加樣式和功能。
這表示當用戶用手機瀏覽時,只會有少量的CSS和所需的檔案會被下載。這也意味著,舊版本的IE瀏覽器(不支援 media queries)會出現手機網頁的界面。Joni Korpi 的 Leaving Old Internet Explorer Behind 裡有更多這方面的說明。
步驟1 :基本標籤
以下我會慢慢為你解釋這個做法背後動機。現在,我們先開啟一個新的 HTML 5文件檔,開始吧!
1 |
<html lang="en"> |
2 |
<head>
|
3 |
|
4 |
<meta charset="utf-8"> |
5 |
<title>Mobile First Responsive Navigation</title> |
6 |
<meta name="description" content="CSS only mobile first navigation"> |
7 |
<meta name="author" content="Ian Yates"> |
8 |
|
9 |
<!--Mobile specific meta goodness :)-->
|
10 |
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
11 |
|
12 |
<!--css-->
|
13 |
<link rel="stylesheet" href="styles.css"> |
14 |
|
15 |
<!--[if lt IE 9]>
|
16 |
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
17 |
<![endif]-->
|
18 |
|
19 |
<!-- Favicons-->
|
20 |
<link rel="shortcut icon" href="img/favicon.ico"> |
21 |
|
22 |
</head>
|
23 |
<body id="home"> |
24 |
|
25 |
|
26 |
</body>
|
27 |
</html>
|
Having done that, we'll add some page structure. Straight-forward stuff and all for the purposes of our demonstration. I've used filler text from Monty Python's Holy Grail (thanks Chris Valleskey) which is a nice way to put a smile on your face whilst you're working :)
現在,我們來寫一些網頁的結構吧。這些都是簡單和直截了當的東西。我也用上了 Monty Python 的 Holy Grail(感謝 Chris Valleskey)的文章當成這網頁的字,這令你的工作更方便 :)1 |
<body id="home"> |
2 |
|
3 |
<div class="wrapper"> |
4 |
|
5 |
<header>
|
6 |
|
7 |
<h1 class="logo"><a href="">Nav</a></h1> |
8 |
|
9 |
</header>
|
10 |
|
11 |
<article>
|
12 |
|
13 |
<h2>Blue. No, yel…</h2> |
14 |
|
15 |
<p>Shut up! Will you shut up?! But you are dressed as one… Camelot! You don't vote for kings.</p> |
16 |
|
17 |
</article>
|
18 |
|
19 |
<article>
|
20 |
|
21 |
<h2>We want a shrubbery!!</h2> |
22 |
|
23 |
<p>Look, my liege! Shut up! But you are dressed as one…</p> |
24 |
|
25 |
<ul>
|
26 |
<li>The nose?</li> |
27 |
<li>Shh! Knights, I bid you welcome to your new home. Let us ride to Camelot!</li> |
28 |
<li>Look, my liege!</li> |
29 |
</ul>
|
30 |
|
31 |
</article>
|
32 |
|
33 |
<article>
|
34 |
|
35 |
<h2>Help, help, I'm being repressed!</h2> |
36 |
|
37 |
<p>Why? Listen. Strange women lying in ponds distributing swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony. Be quiet! A newt?</p> |
38 |
|
39 |
</article>
|
40 |
|
41 |
<footer>
|
42 |
|
43 |
<p>Copyright ©2012 Ian Yates <a href="http://webdesign.tutsplus.com">Webdesigntuts+</a></p> |
44 |
|
45 |
</footer>
|
46 |
|
47 |
</div><!--end wrapper--> |
48 |
|
49 |
</body>
|
步驟2 :導覽菜單標籤
我們已經有了一個基本的html頁面,所以現在我們要開始這文章的重點 - 主導覽菜單..
1 |
|
2 |
<nav id="primary_nav"> |
3 |
|
4 |
<ul>
|
5 |
|
6 |
<li><a href="">Portfolio</a></li> |
7 |
|
8 |
<li><a href="">About Me</a></li> |
9 |
|
10 |
<li><a href="">Nonsense</a></li> |
11 |
|
12 |
<li><a href="">Services</a></li> |
13 |
|
14 |
<li><a href="">Contact</a></li> |
15 |
|
16 |
<li><a href="#home">Top</a></li> |
17 |
|
18 |
</ul>
|
19 |
|
20 |
</nav><!--end primary_nav--> |
你沒看錯,我們將老加在第68行,在最後一篇文章之後。不要忘了,我們正在設計小屏幕的界面,後面才開始討論大屏幕。我們把導覽放置在網頁的底部,那樣它便不會蓋住內容。然後在網頁的頂部放置一個鏈接,這樣用戶就可以找到導覽菜單了。
1 |
|
2 |
<header>
|
3 |
|
4 |
<h1 class="logo"><a href="">Nav</a></h1> |
5 |
|
6 |
<a class="to_nav" href="#primary_nav">Menu</a> |
7 |
|
8 |
</header>
|
步驟3:重設CSS
這步可跟你的個人喜好以定,我的步驟可能跟你的會有點一樣。我覺得Eric Meyer的重置檔案很仔細,尤其是他剛修改過的,有不錯的基礎。我們將會加入他的設定:
1 |
/* http://meyerweb.com/eric/tools/css/reset/
|
2 |
v2.0b1 | 201101
|
3 |
NOTE: WORK IN PROGRESS
|
4 |
USE WITH CAUTION AND TEST WITH ABANDON */
|
5 |
|
6 |
html, body, div, span, applet, object, iframe, |
7 |
h1, h2, h3, h4, h5, h6, p, blockquote, pre, |
8 |
a, abbr, acronym, address, big, cite, code, |
9 |
del, dfn, em, img, ins, kbd, q, s, samp, |
10 |
small, strike, strong, sub, sup, tt, var, |
11 |
b, u, i, center, |
12 |
dl, dt, dd, ol, ul, li, |
13 |
fieldset, form, label, legend, |
14 |
table, caption, tbody, tfoot, thead, tr, th, td, |
15 |
article, aside, canvas, details, figcaption, figure, |
16 |
footer, header, hgroup, menu, nav, section, summary, |
17 |
time, mark, audio, video { |
18 |
margin: 0; |
19 |
padding: 0; |
20 |
border: 0; |
21 |
outline: 0; |
22 |
font-size: 100%; |
23 |
font: inherit; |
24 |
vertical-align: baseline; |
25 |
}
|
26 |
/* HTML5 display-role reset for older browsers */
|
27 |
article, aside, details, figcaption, figure, |
28 |
footer, header, hgroup, menu, nav, section { |
29 |
display: block; |
30 |
}
|
31 |
body { |
32 |
line-height: 1; |
33 |
}
|
34 |
ol, ul { |
35 |
list-style: none; |
36 |
}
|
37 |
blockquote, q { |
38 |
quotes: none; |
39 |
}
|
40 |
blockquote:before, blockquote:after, |
41 |
q:before, q:after { |
42 |
content: ''; |
43 |
content: none; |
44 |
}
|
45 |
|
46 |
/* remember to highlight inserts somehow! */
|
47 |
ins { |
48 |
text-decoration: none; |
49 |
}
|
50 |
del { |
51 |
text-decoration: line-through; |
52 |
}
|
53 |
|
54 |
table { |
55 |
border-collapse: collapse; |
56 |
border-spacing: 0; |
57 |
}
|
步驟4:基本樣式
目前,我們的網頁很平淡..



..所以我們來添加一些簡單的樣式吧。
1 |
/*begin our styles*/
|
2 |
|
3 |
body { |
4 |
font: 16px/1.4em 'PT Sans', sans-serif;; |
5 |
color: #1c1c1c; |
6 |
}
|
7 |
|
8 |
p, |
9 |
ul { |
10 |
margin: 0 0 1.5em; |
11 |
}
|
12 |
|
13 |
ul { |
14 |
list-style: disc; |
15 |
padding: 0 0 0 20px; |
16 |
}
|
17 |
|
18 |
a { |
19 |
color: #1D745A; |
20 |
}
|
21 |
|
22 |
h1 { |
23 |
|
24 |
}
|
25 |
|
26 |
h2 { |
27 |
font-family: 'PT Serif', serif; |
28 |
font-size: 32px; |
29 |
line-height: 1.4em; |
30 |
margin: 0 0 .4em; |
31 |
font-weight: bold; |
32 |
}
|
33 |
|
34 |
/*layout*/
|
35 |
|
36 |
.wrapper { |
37 |
}
|
38 |
|
39 |
article { |
40 |
border-bottom: 1px solid #d8d8d8; |
41 |
padding: 10px 20px 0 20px; |
42 |
margin: 10px 0; |
43 |
}
|
44 |
|
45 |
/*header*/
|
46 |
|
47 |
header { |
48 |
background: #1c1c1c; |
49 |
padding: 15px 20px; |
50 |
}
|
51 |
|
52 |
/*shorter clearfix http://nicolasgallagher.com/micro-clearfix-hack/*/
|
53 |
header:before, |
54 |
header:after { |
55 |
content:""; |
56 |
display:table; |
57 |
}
|
58 |
|
59 |
header:after { |
60 |
clear:both; |
61 |
}
|
62 |
|
63 |
/* For IE 6/7 (trigger hasLayout) */
|
64 |
header { |
65 |
zoom:1; |
66 |
}
|
67 |
|
68 |
h1.logo a { |
69 |
color: #d8d8d8; |
70 |
text-decoration: none; |
71 |
font-weight: bold; |
72 |
text-transform: uppercase; |
73 |
font-size: 20px; |
74 |
line-height: 22px; |
75 |
float: left; |
76 |
letter-spacing: 0.2em; |
77 |
}
|
78 |
|
79 |
a.to_nav { |
80 |
float: right; |
81 |
color: #fff; |
82 |
background: #4e4e4e; |
83 |
text-decoration: none; |
84 |
padding: 0 10px; |
85 |
font-size: 12px; |
86 |
font-weight: bold; |
87 |
line-height: 22px; |
88 |
height: 22px; |
89 |
text-transform: uppercase; |
90 |
letter-spacing: 0.1em; |
91 |
-webkit-border-radius: 2px; |
92 |
-moz-border-radius: 2px; |
93 |
border-radius: 2px; |
94 |
}
|
95 |
|
96 |
a.to_nav:hover, |
97 |
a.to_nav:focus { |
98 |
color: #1c1c1c; |
99 |
background: #ccc; |
100 |
}
|
<header>中傾向右側的。



:focus的狀態。它跟:hover的狀態是一樣的,:focus會在觸摸屏上出現狀態,讓用戶知道他們已經成功按下了菜單的按鈕。
不管怎樣,點擊它,你就會被帶到菜單,讚!



現在讓我們把菜單變得更漂亮吧。
步驟5:菜單樣式
其實,我們將會把我們的菜單設計得像之前的 London & Partners 的示範一樣,只是我們把它放在網頁的底部..
1 |
/*navigation*/
|
2 |
|
3 |
#primary_nav ul { |
4 |
list-style: none; |
5 |
background: #1c1c1c; |
6 |
padding: 5px 0; |
7 |
}
|
8 |
|
9 |
#primary_nav li a { |
10 |
display: block; |
11 |
padding: 0 20px; |
12 |
color: #fff; |
13 |
text-decoration: none; |
14 |
font-weight: bold; |
15 |
text-transform: uppercase; |
16 |
letter-spacing: 0.1em; |
17 |
letter-spacing: 0.1em; |
18 |
line-height: 2em; |
19 |
height: 2em; |
20 |
border-bottom: 1px solid #383838; |
21 |
}
|
22 |
|
23 |
#primary_nav li:last-child a { |
24 |
border-bottom: none; |
25 |
}
|
26 |
|
27 |
#primary_nav li a:hover, |
28 |
#primary_nav li a:focus { |
29 |
color: #1c1c1c; |
30 |
background: #ccc; |
31 |
}
|
32 |
|
33 |
/*footer*/
|
34 |
|
35 |
footer { |
36 |
font-family: 'PT Serif', serif; |
37 |
font-style: italic; |
38 |
text-align: center; |
39 |
font-size: 14px; |
40 |
}
|
好多了。我們所做的菜單鏈接不錯,大(Luke Wroblewski 的博客有更多關於Touch Target Sizes的說明),並再次確定:focus的狀態提示。



我們也包括了一個"top"的鏈接,方便用戶點到網頁頂部。
步驟6:放大吧
OK,我們已經處理好小屏幕的界面了,那麼現在我們要加入 media queries。這樣當屏幕變大時,就可以隱藏小屏幕的樣式用點大屏幕的了。
但是在什麼時候它變得不合適呢?有很多不同 media queries 的做法,我們以一個手機屏幕大小是320px x 480px為基礎 。這是把手機垂直看時寬度是320px,橫看便是480px,所以我們就把第一個 media queries 檢測設定為任何尺寸大過 480px。
這可是,接下來的是平板電腦設定。而iPad的解像度是980px x 768px,所以我們可以設定任何比768px小的便適合用上小屏幕的樣式,而任何大於768px的便可以做類似跟桌面界面差不多的樣式。
在我們開始加入不同的樣式設定,先來建立 media query:
1 |
|
2 |
/*media queries*/
|
3 |
|
4 |
@media only screen and (min-width: 768px) { |
5 |
|
6 |
}
|
當屏幕的寬度只少有768px時,這個 media query 會執行所有在內的樣式設定。注意當中的only是關鍵字,它將確保Internet Explorer 8能正常執行樣式設定。可看這裡,有我之前解說過的。
我們來讓"菜單"的按鈕消失吧:
1 |
|
2 |
@media only screen and (min-width: 768px) { |
3 |
|
4 |
a.to_nav { |
5 |
display: none; |
6 |
}
|
7 |
|
8 |
}
|



只要把瀏覽器的寬度變大,"菜單"按鈕就會不見了。
步驟7:移動菜單
現在我們需要把主要的導覽切換到網頁的頂部。先把它取出,然後用 position: absolute 把它頂至頂部。
1 |
|
2 |
@media only screen and (min-width: 768px) { |
3 |
|
4 |
a.to_nav { |
5 |
display: none; |
6 |
}
|
7 |
|
8 |
.wrapper { |
9 |
position: relative; |
10 |
width: 768px; |
11 |
margin: auto; |
12 |
}
|
13 |
|
14 |
#primary_nav { |
15 |
position: absolute; |
16 |
top: 5px; |
17 |
right: 10px; |
18 |
background: none; |
19 |
}
|
20 |
|
21 |
#primary_nav li { |
22 |
display: inline; |
23 |
}
|
24 |
|
25 |
#primary_nav li a { |
26 |
float: left; |
27 |
border: none; |
28 |
padding: 0 10px; |
29 |
-webkit-border-radius: 2px; |
30 |
-moz-border-radius: 2px; |
31 |
border-radius: 2px; |
32 |
}
|
33 |
|
34 |
}
|
首先,我們必須在 media query 或 css 的開端把它所屬的標籤(.wrapper)設為 position: relative。
只要菜單被設定為 position: absolute,我們需要刪除一些標籤的設定,把列表顯示為 display: inline 和刪除邊框和標籤的距離便可以。當然,不用修改之前定立的 hover 狀態。



步驟8:最後一件事
你可能會注意到我們有個"頂至"的鏈接 - 還需要嗎?
有多種可以將其刪除的方法,但為確保一切正常,讓我們先為每個列表的項目添加一個 class:
1 |
|
2 |
<li class="top"><a href="#home">Top</a></li> |
這樣我們就不用 media query 也能把它刪除:
1 |
|
2 |
#primary_nav li.top { |
3 |
display: none; |
4 |
}
|



結論
完成!這些只是一些基本的設定,往後如果你的網頁需要支援更多的樣式,你可以繼續添加一些 media queries。一個簡易,響應式,為手機擾先設想的網頁設計,還需要什麼呢?!
更多資源
這些是以上提到的有用鏈接:
- Luke Wroblewski's Mobile First
- Chris Coyier's jQuery-based responsive dropdown menu
- Five Simple Steps
- Twitter Bootstrap
- Joni Korpi's Leaving Old Internet Explorer Behind
- Don't Forget the Viewport Meta Tag!
- Chris Valleskey's Monty Python (amongst other things) filler text
- Eric Meyer's reset revisited
- Luke Wroblewski's Touch Target Sizes
- My explanation of the media query 'only' keyword
- Brad Frost's responsive navigation patterns
- Aaron Gustafson's Build a smart mobile navigation without hacks on .net Magazine



