第 4 章 流動佈局
(1) 網頁佈局規劃的沿革
∗ 早期,大多利用表格 (Table) 規劃佈局 (Layout)
▸ 佈局僵化,無法彈性變化
▸ 修改非常困難
∗ 接著,區域長寬度以比例設定,例如:左方欄 20%,內容 80%
▸ 不同螢幕寬度或瀏覽器會造成非常不一樣的呈現結果 (頁面變形)
∗ 然後,利用像素來設定區域寬高
▸ 由於螢幕是以像素組成,因此以像素來固定區域長寬度,可以使所有螢幕或瀏覽器呈現相同結果,終於解決呈現不同的困擾
▸ 網頁寬度大多以螢幕最小寬度為準 (約 1,000 像素),較寬螢幕則左右留白
▸ 手持裝置出現,打破了這個理想狀態
∗ 近期回應式網頁的需求
▸ 查詢視域像素,再設定不同視域的彈性頁面結構
▸ 問題:若視域尺寸在所設定的門檻之間,頁面還是會產生水平捲軸
∗ 未來回應式網頁的需求
▸ 未來可能各種視域都會出現,以像素計算並設定門檻方式還是太過粗糙
▸ 終極解決方案:回到「比例設定」方式,讓頁面元素相對於視域尺寸而縮放,直到另一個媒體查詢修改樣式 → 流動佈局 (Fluid layout)
(2) 比例設定佈局元素的尺寸
∗ 將固定寬度像素轉換為百分比例的公式
▸ 結果寬度 = 目標物寬度/環境寬度:result = target/context
∗ 練習:將網頁佈局改為流動百分比例設定
▸ 目前 HTML 主要結構如下:
<div id="wrapper"> <header> <nav> </nav> </header> <div id="container"> <aside> </aside> <div id="content"> </div> </div> <footer> </footer> </div>
▸ 主要的佈局元素尺寸如下 (僅列出結構元素,其餘樣式省略):
#wrapper { width: 960px; margin: 0 auto; } header { padding: 60px 20px 20px 20px; } nav { padding: 20px 0; } div#container { display: grid; grid-template-columns: 1fr 3fr; } aside { margin-top: 50px; padding: 20px; } div#content { margin-top: 50px; padding: 20px; } footer { margin-top: 20px; padding: 20px 20px 60px 20px; }
▸ 練習:將 oscar3-4.html 及 oscar3-4.css 分別另存新檔為 oscar4-1.html 及 oscar4-1.css, 並如下修改:
✶ HTML:修改 CSS 連結 <link rel="stylesheet" href="css/oscar4-1.css">
✶ CSS:
# 設定外圍區塊的比例寬度
* 目前所有的距離設定均使用 px 為單位,現在從最外圍元素開始改為百分比例
* #wrapper 區塊的寬度必須隨視域寬度自動調整,
因此,假設螢幕寬度為 1000px,則 #wrapper 寬度比例為 96%:
#wrapper {
width: 96%; /* 960px */
}
* 目前若視域夠寬時,aside 及
#content 會分別向左右流動
# 比例設定時,是以其包含元素的寬度為基準,因此將各個區塊的寬度依其原寬度除以 #wrapper 原寬度的方式改為比例值:
* 除了 nav li a 以外,將其餘 margin
及 padding 均改為相對於 #wrapper 寬度的百分比:
10px: 1.04%; /* 10/960 */ 20px: 2.08%; /* 20/960 */ 50px: 5.21%; /* 50/960 */ 60px: 6.25%; /* 60/960 */
# 媒體查詢 (@media screen and (max-width: 800px) {):
* #wrapper 寬度設為 100%
@media screen and (max-width: 800px) {
div#wrapper {
width: 100%;
}
...
}
* h1#first 寬度設為比例值
aside h1#first {
margin-right: 5.21%;
}
✶ 測試:改變瀏覽器寬度,觀察頁面變化
(3) 流動影像
▸ 流動影像 (Fluid image):影像尺寸依包含元素之比例設定
▸ 練習:將 oscar4-1.html 及 oscar4-1.css 分別另存新檔為 oscar4-2.html 及 oscar4-2.css,並如下修改:
✶ HTML:修改 CSS 連結 <link rel="stylesheet" href="css/oscar4-2.css">
✶ CSS:
# 在側欄中,將影像寬度設為百分比
* 刪除 aside 中之 padding 設定
* aside 原寬度為 240px,假設左右均留 20px 之填充,故 h1
的寬度為 200px,百分比為 83.33% (200/240),並設定區塊與內部文字均置中,內填充亦改為比例
* aside 中的 p 設定內填充
* 將影像寬度設定為 h1 的 45% (兩張影像共 90%)
aside { ... margin-top: 5.21%; /* 50/960 */padding: 2.08%; /* 20/960 */} aside h1 { ... width: 83.33%; /* 200/240 */ margin: 0 auto; text-align: center; padding: 4.17% 0; /* 10/240 */ } aside p { padding: 4.17% 0; /* 10/240 */ } aside img.poster { width: 45%; }
# 影像 oscar.png 也設定其依照 #content 的寬度 (720px) 比例自動縮放
div#content img#oscar {
width: 27.78%; /* 200/720 */
}
# 另一問題,縮放頁面時,oscar.png 可能變得很大而顯得難看,因此可以設定其最大寬度,以避免縮放過大
div#content img#oscar {
width: 27.78%; /* 200/720 */
max-width: 200px;
}
# 此外,為防止各個元素無限制地放大,也可以設定 #wrapper 的最大寬度
#wrapper {
...
margin: 0 auto;
max-width: 1200px;
}
# 媒體查詢
* 將 h1 元素設為比例寬度,取消 h1#first
設定,並將影像設為比例式尺寸
@media screen and (max-width: 800px) { ... aside h1 { display: inline-block; width: 45%; }aside h1#first {margin-right: 5.21%; /* 50/960 */}aside img.poster { width: 40%; } }
* HTML: 取消 <h1 id="first"> 之 id 設定
oscar4-2.html
<h1id="first"> ... </h1>
(4) 回應式影像
▸ 回應式影像 (Responsive image):依據視域大小提供不同影像檔案
▸ 理想回應式影像策略應滿足以下目標
1. 適應螢幕:回應式策略應該要適性縮放影像,以回應裝置螢幕的尺寸
# 作法:設定流動式影像
2. 節省頻寬:高解析度影像品質很好,但使用過多頻寬,這對桌上型使用寬頻網路的電腦並無影響,但在低頻寬、小螢幕的裝置上顯然不適合,因此,回應適策略應該應該要提供不同影像檔案,以回應網路頻寬的特性
# 作法:事先製作不同解析度的影像,在不同視域提供不同檔案
3. 採取藝術路線:並非所有影像在縮小時均能維持畫質,尤其有許多細節部份的影像縮小後細節更為模糊紛亂,對於小螢幕裝置可能需要提供完全不同的影像,例如僅提供重要部份,其餘則裁切掉
# 作法:事先決定影像哪些部份是重要的,然後裁切下來
▸ 解決方案:picture 標籤,在不同的媒體特性,提供不同的影像檔案
<picture> <source media="(min-width:...)" srcset=...> <source media="(min-width:...)" srcset=...> ... <img src=... alt="原始影像"> </picture>
✶ 其中:
# source:指定影像來源
# media:視域條件
# srcset:一或多個影像位址
✶ 範例
<picture> <source media="(min-width:800px)" srcset="large.jpg"> <source media="(min-width:600px)" srcset="medium.jpg"> <source srcset="small.jpg"> <img src="small.jpg" alt="原始影像"> </picture>
▸ 練習:將 oscar4-2.html 及 oscar4-2.css 分別另存新檔為 oscar4-3.html 及 oscar4-3.css,並如下修改:
✶ 製作 oscarLarge.png (200x500)、oscarMedium.png (150x375)、oscarSmall.png (100x250) 及 oscarStandard.png (180x450) 四個影像檔
✶ HTML:
# 修改 CSS 連結 <link rel="stylesheet" href="css/oscar4-3.css">
# 在不同視域提供不同影像檔,若瀏覽器不支援 picture 標籤,則倒退到標準影像
... <div id="content"> <img id="oscar" src="img/oscar.png" alt="奧斯卡金人"> <picture> <source media="(min-width:900px)" srcset="img/oscarLarge.png"> <source media="(min-width:700px)" srcset="img/oscarMedium.png"> <source media="(min-width:500px)" srcset="img/oscarSmall.png"> <img src="img/oscarStandard.png" alt="奧斯卡金人"> </picture> ...
✶ CSS:
# 設定奧斯卡金人影像比例式尺寸
... div#content img#oscar { div#content picture { ... } div#content picture source, div#content picture img { width: 100%; height: 100%; } /* Aside */ ...
# 可再加上更多回應範圍:在不同視域顯示不同文字尺寸
... /* Responsive design */ /* At 1000px */ @media screen and (min-width: 1000px) { nav ul li a { font-size: 1.8em; } } @media screen and (max-width: 1000px) { nav ul li a { font-size: 1.6em; } } /* At 800px */ @media screen and (max-width: 800px) { ... nav ul li a { font-size: 1.4em; } } /* At 600px */ @media screen and (max-width: 600px) { nav ul li a { font-size: 1.2em; } }