第 3 章 流動佈局 (1) 網頁佈局規劃的沿革 - 早期, 大多利用表格 (Table) 規劃佈局 (Layout) * 很難撰寫, 修改困難 - 接著, 區域長寬度以比例設定, 例如 : 左方欄 20%, 內容 80% * 不同螢幕寬度或瀏覽器會造成非常不一樣的呈現結果 ( 寬螢幕造成變形 ) - 然後, 利用像素來設定區域寬高 * 由於螢幕是以像素組成, 因此以像素來固定區域長寬度, 可以使所有螢幕或瀏覽器呈現相同結果, 終於解決呈現不同的困擾 * 網頁寬度大多以螢幕最小寬度為準 ( 約 1,000 像素 ) * 但手持裝置出現, 打破了這個理想狀態 - 近期回應式網頁的需求 * 查詢視域像素, 再設定不同視域的彈性頁面結構 * 問題 : 若視域尺寸在所設定的門檻之間, 頁面還是會產生捲軸 - 未來回應式網頁的需求 * 未來可能各種視域都會出現, 以像素計算並設定門檻方式還是太過粗糙 * 終極解決方案 : 回到 比例設定 方式, 讓頁面元素相對於視域尺寸而縮放, 直到另一個媒體查詢修改樣式 流動佈局 (Fluid layout) (2) 比例設定公式 - 將固定寬度像素轉換為百分比例的公式 ( 結果寬度 = 目標物寬度 / 環境寬度 ): result = target / context - 將 得獎者不是 網頁佈局改為流動百分比例設定 * 初始之 HTML 如下 : <!-- the wrapper --> <div id=wrapper> <!-- the header and navigation --> <div id=header> <div id=navigation> <ul> <li><a href=#> 為什麼?</a></li> <li><a href=#> 劇情簡介 </a></li> </ul> <!-- the sidebar --> <div id=sidebar> 3-1
<!-- the content --> <div id=content> <!-- the footer --> <div id=footer> * 主要的佈局 CSS 元素如下 ( 僅列出結構元素, 其餘樣式省略 ): #wrapper { margin-right: auto; margin-left: auto; width: 960px; #header { margin-right: 10px; margin-left: 10px; width: 940px; #navigation { margin-top: 26px; margin-left: -10px; padding-right: 10px; padding-left: 10px; padding-bottom: 25px; width: 940px; #navigation ul li { display: inline-block; #sidebar { margin-top: 58px; padding-right: 10px; margin-right: 10px; margin-left: 10px; float: left; width: 220px; border-right-color: #e8e8e8; border-right-style: solid; border-right-width: 2px; #content { margin-top: 58px; margin-right: 10px; float: right; width: 698px; #footer { margin-top: 20px; margin-right: 10px; margin-left: 10px; float: left; clear: both; width: 940px; * 將 oscar2-4.html 與 oscar2-4.css 分別另存新檔為 oscar3-1.html 與 oscar3-1.css, 並修改 html 裡的 <link href=oscar3-1.css> 元素 * 目前所有的距離設定均使用像素, 現在從最外圍元素改成以百分比例設定 - 設定外圍區塊 wrapper * 我們需要一個能夠容納所有比例元素 (content, sidebar, footer, ) 的環境, 亦即 wrapper 區塊的寬度必須與視域尺寸相關 ( 有兩處 ): #wrapper { width: 96%; * 目前若視域較寬時,sidebar 及 content 會分別向左右流動, - 設定其他區塊 * 原先 wrapper 寬 960px, 現將各個區塊的寬度依其原寬度除以 wrapper 原寬度的方式 改為比例值 : #header { width: 97.9166667%; /* 940/960 */ #navigation { width: 97.9166667%; /* 940/960 */ #content { width: 72.7083333%; /* 698/960 */ 3-2
#footer { width: 97.9166667%; /* 940/960 */ * 因 sidebar 尚有 2px 寬的邊界, 擬設定此邊界為固定, 因此區塊的原寬度為 218: #sidebar { width: 22.7083333%; /* 218/960 */ * 設定所有的 10px 寬度為 1.0416667%; /* 10/960 */ * 設定 navigation ul li a 的 25px 寬度 : margin-right: 2.6595745%; /* 25/940 */ * 在 navigation ul li 加上 25px 之按鈕間隔 : #navigation ul li { margin-right: 2.6595745%; /* 25/940 */ * 以 1,000px 寬度視域檢視如右圖 (3) 活版印刷 以 em 為單位 - 網頁文字的尺寸單位 * 早期網頁設計者以 em 為網頁文字大小的單位, 因為當時瀏覽器不支援像素單位 # em: 活版印刷 (Typography) 裡的文字寬度單位,1 em 就等於目前環境所設定的文字大小 (em: equal to the width of the capital "M") * 瀏覽器開始支援像素單位後, 許多人就以像素為單位 * 使用 em 的優點 : 非常方便 # 例如 : 如果網頁設定 <body> 的字體尺寸為 100%, 所有文字均使用 em, 日後如果要改變字體大小, 就只要改 <body> 的字體大小, 其餘文字就會自動按比例縮放 - 將 oscar3-1.html 與 oscar3-1.css 分別另存新檔為 oscar3-2.html 與 oscar3-2.css, 並修改 html 裡的 <link href=oscar3-2.css> 元素 * 將所有以 px 為單位的字體設定全改為 em * 目前所有現代瀏覽器的預設字體大小都是 16px, 因此下列設定 <body> 字體大小的方式均得到相同結果 font-size: 100% font-size: 16px; font-size: 1em; * 將 px 改為 em, 並依比例計算 height: 2.625em; /* 42/16 */ line-height: 1.5555555em; /* 42/27 行高設定為直接與字體大小關聯 */ font-size: 1.6875em; /* 27/16 */ #logo { 3-3
font-size = 3em; /* 48/16 */ #content h1 { font-size: 2.125em; /* 34/16 */ #content h1 span { line-height: 1.4285714em; /* 40/28 行高設定為直接與字體大小關聯 */ font-size: 0.8235294em; /* 28/34 外部環境 (#content h1) 字體大小為 34px */ (4) 流動影像 - 流動影像 (Fluid image) * 讓影像的大小自動與包含它的元素尺寸一樣 img { max-width: 100%; * 其他多媒體亦同 img, object, video, embed { max-width: 100%; * 此法雖然能自動縮放影像, 但下載影像的資料量還是一樣 * 影像尺寸在最大視域呈現時應該還是能呈現良好品質 - 將 oscar3-2.html 與 oscar3-2.css 分別另存新檔為 oscar3-3.html 與 oscar3-3.css, 並修改 html 裡的 <link href=oscar3-3.css> 元素 * 在 CSS 檔加入 img { max-width: 100%; * 因目前 #sidebar 裡的影像均明確設定寬度及高度 (width="99" height="135"), 故設定 maxwidth: 100%; 並不會產生效果, 需將所有影像的寬高度均刪除 <a ><img src="img/midnightrun.jpg"></a> <a ><img src="img/wyattearp.jpg"></a> <a ><img src="img/moulinrouge.jpg"></a> <a ><img src="img/kingkong.jpg"></a> * 結果如下圖 (a), 影像已自動填滿整個 #sidebar 區域的寬度, 但我們需要兩個檔案並列, 可以在 CSS 中設定寬度比例, 結果如下圖 (b).sideblock img { max-width: 45%; 3-4
(a) * 既然 #sidebar 已設定影像自動縮放, 影像 oscar.png 的寬高度設定即可刪除, 取而代之也是設定其依照比例自動縮放 HTML: <img class=oscarmain src=img/oscar.png> CSS:.oscarMain { width: 28.9398281%; /* 698 202 */ * 另一問題, 縮放頁面時,oscar.png 可能變得很大而顯得難看, 如下圖 (a), 因其原始寬度為 202px, 因此可以設定其最大寬度, 以避免縮放過大, 結果如下圖 (b).oscarmain { max-width: 202px; (b) (a) * 此外, 為防止各個元素無限制地放大, 也可以設定 #wrapper 的最大寬度如下, 也就是說,#wrapper 設定為視域的 96% 寬, 但最大寬度僅到 1414px #wrapper { width: 96%; max-width: 1414px; (5) 回應式影像 - 回應式影像 (Responsive image): 依據視域大小提供不同影像尺寸, 主要技術 : * Matt Wilcox 適應性影像 (Adaptive image) # 系統動態產生適當的影像尺寸, 網頁設計師不需要事先產生各種尺寸的影像 # 環境需求 :Apache 2 PHP 5.x GD Lib (b) 3-5
* Scott Jehl 的圖片填充 (Picturefill) # HTML: <head> <meta name=viewport content="width=device-width,initial-scale=1"> <script src=js/matchmedia.js></script> <script src=js/picturefill.js></script> </head> <body> <span data-picture> <span data-src=img/small.jpg></span> <span data-src=img/medium.jpg data-media=(min-width:400px)></span> <span data-src=img/large.jpg data-media=(min-width:800px)></span> <span data-src=img/extralarge.jpg data-media=(min-width:1000px)></span> <!-- Fallback content for non-js browsers. Same img src as the initial, unqualified source element. --> <noscript> <img src=img/small.jpg alt="a giant stone face at The Bayon temple in Angkor Thom, Cambodia"> </noscript> </span> # JavaScript: matchmedia.js, picturefill.js # Images: small.jpg (180x240), medium.jpg (375x500), large.jpg (480,640), extralarge.jpg (768x1024) * HTML5 ( 期待中 ): <picture id=images> <source media=(min-width:45em) srcset="large1.jpg 1x, large2.jpg 2x"> <source media=(min-width:18em) srcset="medium1.jpg 1x, medium2.jpg 2x"> </picture> - 在 oscar3-3.html 將 oscar.png 影像設為回應式 * 在 <head> 元素中加入 <meta name=viewport content="width=device-width,initial-scale=1"> <script src=js/matchmedia.js></script> <script src=js/picturefill.js></script> * 建立 js 子目錄, 並將 matchmedia.js picturefill.js 兩檔案複製至該目錄 * 將 oscar.png 重新命名為 oscarlarge.png, 利用影像編輯器 ( 例如 :Gimp) 產生 oscarmedium.png (150x394) 與 oscarsmall.png (100x263) 兩影像 * 將原先的 <img class=oscarmain src=img/oscar.png> 如下修改 : <div id="content"> <span class=oscarmain data-picture data-alt= 奧斯卡金人 > <span data-src=img/oscarsmall.png data-media=(min-width:400px)></span> <span data-src=img/oscarmedium.png data-media=(min-width:600px)></span> <span data-src=img/oscarlarge.png data-media=(min-width:768px)></span> <noscript> <img src=img/oscarsmall.png alt= 奧斯卡金人 > </noscript> </span> <h1> 每年 <span> 我觀賞奧斯卡金像獎頒獎典禮時, 都覺得很生氣 </span></h1> (6) 字體大小配合視域調整 - 將 oscar3-3.html 與 oscar3-3.css 檔案分別複製為 oscar3-4.html 與 oscar3-4.css, 並將 3-6
oscar3-4.html 裡的 css 連結改為 <link href=oscar3-4.css> - 將 @media (max-width: 768px) 元素中的區塊 px 寬度改為比例計算 #navigation { border-top-width: 0.5208333%; /* 4/768 */ padding-top: 2.6041667%; /* 20/768 */ #content, #sidebar { margin-top: 2.6041667%; /* 20/768 */ padding-right: 1.3020833%; /* 10/768 */ padding-left: 1.3020833%; /* 10/768 */ width: 94.791666%; /* 728/768 */.oscarmain { margin-right: 3.90625%; /* 30/768 */ margin-top: 0%; width: 19.53125%; /* 150/768 */ height: 51.3020833%; /* 394/768 */ #sidebar { padding-top: 2.6041667%; /* 20/768 */ margin-bottom: 2.6041667%; /* 20/768 */.overhyped { margin-top: 0%; margin-left: 6.5104167%; /* 50/768 */ - 將 @media (max-width: 768px) 元素中的行高 px 單位改為 em line-height: 3.75em; /* 60/16 */ font-size: 40px; - 可在 CSS 中加上更多範圍與字體樣式 : 刪除 #navigation ul li a 中之字體設定, 並加入其他媒體查詢字體設定 : font-size: 40px; @media screen and (min-width: 1001px) and (max-width: 1080px) { font-size: 1.4em; @media screen and (min-width: 805px) and (max-width: 1000px) { font-size: 1.25em; 3-7
@media screen and (min-width: 769px) and (max-width: 804px) { font-size: 1.1em; 3-8