網頁設計

第 2 章    CSS

(1) 層疊樣式單

∗ 層疊樣式單 (Cascading style sheet, CSS)

▸ 利用一致性的格式設定,使文件的呈現一致化,亦即相同的元素使用相同的格式

▸ 利用 CSS 可統一設定文字對齊、字型、背景、顏色等,使整份文件看來非常一致

▸ CSS 樣式由 2 部分組成並以冒號分隔,此稱為樣式宣告 (Style declaration),格式如下:

property:value
✶ 其中 property 是某項 CSS 樣式特性, 而 value 是該樣式的值,也就是視覺效果, 例如:color:blue

∗ CSS 歷史

▸ 1996:CSS1

▸ 1998:CSS2

▸ 1999:CSS3

∗ 網頁文字的尺寸單位

▸ 早期網頁設計者以 em 為網頁文字大小的單位,因為當時瀏覽器不支援像素單位

✶ em 為活版印刷 (Typography) 技術裡的文字寬度單位 (em: equal to the width of the capital "M"), 1em 就等於目前環境所設定的文字大小

▸ 瀏覽器開始支援像素單位後,許多人就以像素為單位

▸ 使用 em 的優點:非常方便。如果網頁設定 <body> 的字體尺寸為 100%, 所有文字均使用 em,日後如果要改變字體大小,就只要改 <body> 的字體大小, 其餘文字就會自動按比例縮放,例如:

<body>
<h1>...</h1>
<p>...<span>...</span>...</p>
</body>
字體尺寸設定如下:
<body>:16px
<h1>:1.2em
<p>:0.8em
<span>:0.8em
字體實際尺寸:<h1> 為 19.2 px (16×1.2), <p> 為 12.8 px (16×0.8), <span> 則為 10.24 px (12.8×0.8)

∗ CSS 設定樣式的方式:

▸ 行內樣式 (Inline style)、內部樣式單 (Internal style sheet)、及外部樣式單 (External style sheet)

∗ 行內樣式

▸ 在一份文件中對於某元素加入樣式設定,格式如下:

style="property:value;"

▸ 例如以下將某段落設定為置中對齊,text-align 是文字對齊的樣式, center 為置中:

<p style="text-align:center;">使用行內樣式的段落</p>

▸ 利用分號設定多個行內樣式,例如:

<p style="text-align:center; color:red;">使用多個行內樣式的段落</p>

▸ 練習:將 dessert1-8.html 另存為 dessert1-9.html 並如下修改:

1. 修改 <h1> 標籤:
<h1 style="color:red;">甜點商店</h1>
2. 修改 <h2> 標籤 (共 5 處):
<h2 style="color:olive;">
dessert1-9

▸ 行內樣式缺點:

✶ 無法提供相同文件中的其他元素使用,亦無法提供其他文件使用
✶ 個別元素需做個別設定,非常繁瑣而且效率很差

▸ 若非絕對必要,建議不要使用行內樣式

∗ 內部樣式單

▸ 所設定的樣式可提供整份文件裡的元素使用

▸ 產生內部樣式單:在 <head> 元素中加入 <style> 元素,如下:

<style>
style declarations (樣式宣告)
</style>

▸ 在樣式宣告中,每個樣式設定格式如下:

selector {
  property1: value1;
  property2: value2;
  ...
}
其中 selector 可以是標籤,例如將整份文件的段落均設為藍色
p {
  color: blue;
}

▸ 練習:將 dessert1-9.html 另存為 dessert1-10.html 並如下修改:

1. 在 <head> 元素中加入以下之 <style> 元素, 並刪除所有行內樣式設定
...
<head>
...
<style>
h1 {
  color: red;
  font-size: 2em;
}

h2 {
  color: olive;
  font-size: 1.5em;
}
</style>
</head>
...
2. 檢查結果是否相同

▸ 針對多個選項設定相同特性時,以逗號區隔,例如:

<style>
h1, h2, h3 {
  color: navy;
}
</style>

▸ 內部樣式單的缺點:無法提供其他文件使用

▸ 若非絕對必要,建議不要使用內部樣式單

∗ 外部樣式單

▸ 獨立文字檔,內含樣式宣告,可提供許多檔案分享,使所有檔案的格式均一致

▸ 檔案內容僅包含樣式設定,且檔案之副檔名為 .css

▸ 在 HTML 文件中,在 <head>元素中利用<link> 元素來連結外部樣式單

▸ 建議網頁樣式的設定均使用外部樣式單

▸ 練習:

✶ 將 dessert1-10.html 另存為 dessert2-1.html 並如下修改:
1. 建立 <...>/webdesign/css/ 子目錄
2. 建立新檔 <...>/webdesign/css/dessert2-1.css,將 <style> 元素的 內容 複製到該檔中
3. 將 dessert2-1.html 裡的 <style> 元素刪除
4. 在 <head> 元素中加入:
<link rel="stylesheet" href="css/dessert2-1.css">
# link:將外部資源連結到本文件
# rel:外部資源與本文件的關係 (Relation)
檢查結果是否相同

∗ 利用標籤的 id 與 class 設定格式

id 可用來指定某一個特定標籤,不可重複,例如:

<p id="myParagraph">這是我的段落</p>

class 可用來指定許多標籤,例如:

<p class="similar">這是段落1</p>
<p class="similar">這是段落2</p>
<div class="similar">這是區塊1</div>
<div class="similar">這是區塊2</div>

▸ 樣式設定時,使用井號 (#) 來選擇 id; 使用點號 (.) 來選擇 class

▸ 例如:CSS 樣式設定

#myParagraph {
  font-weight: bold;
  margin-top: 1em;
  text-align: center;
}

p.similar {
  color: blue;
  text-align: justify;
}

.similar {
  background-color: yellow;
  line-height: 2em;
}

∗ CSS 註解:

/* ... */

∗ 加強瀏覽器對於 HTML5 與 CSS3 的支援

▸ 大多數現代的瀏覽器都支援 HTML5 及 CSS3 (但仍有些實做上的不同)

normalize.css:將所有瀏覽器的預設樣式統一

✶ 建議:所有網頁的第一個樣式連結 <link rel="stylesheet" href="css/normalize.css">

polyfills: 舊 IE 不認得 HTML5 的語意標籤,但是可以利用 JavaScript 來讓這些新標籤在舊 IE 的頁面運作 (但不表示你一定要解決此問題 ;-)

Modernizr:能偵測瀏覽器支援 HTML5 或 CSS3 的能力,對於無法支援的功能則以程式加以補強

Boilerplate:包含 normalize.css, polyfills, 及 modernizr

(2) CSS 的元素選擇

∗ HTML 子元素與後裔元素

▸ 子元素 (Child element):A 元素直接包含 B 元素,則 B 為 A 的子元素,例如:

<ul>
  <li> ... </li>
  <li> ... </li>
</ul>
liul 的子元素

▸ 後裔元素 (Descendant element):A 元素直接或間接包含 B 元素,則 B 為 A 的後裔元素,例如:

<ul>
  <li> ... </li>
</ul>
liul 的後裔元素
<ul>
  <li> ... <a ... > ... </a> ... </li>
</ul>
aul 的後裔元素

∗ CSS 選擇器 (Selector)

▸ 元素型態、類別、ID 選擇器

選擇意義範例
通用選擇
(Universal selector)
適用所有元素
* { 
  ...
}
型態選擇
(Type selector)
對應元素名稱
<h1>...</h1>
<h2>...</h2>
h1, h2 {
  ...
}
類別選擇
(Class selector)
對應類別屬性
<div class="note">
<p class="note">
.note {
   ...
}
p.note {
  ...
}
ID 選擇
(ID selector)
對應 ID 屬性
<p id="intro"> ... </p>
#intro {
  ...
}
子元素選擇
(Child selector)
對應直接子元素
<ul>
  <li>A</li>
  <li>B
    <ol>
      <li>C</li>
      <li>D</li>
    </ol>
  </li>
  <li>E</li>
</ul>
ul > li {
  ...
}      A, B, E
後裔選擇
(Descendant selector)
對應後裔元素
(HTML 同上)
ul li {
  ...
}      A, B, C, D, E
✶ 例如:
HTML:
<ul id="account">
  <li>註冊</li>
  <li>登入</li>
  ...
</ul>

...

<ul id="branch">
  <li>台中店</li>
  <li>台南店</li>
  ...
</ul>
CSS: 設定分店的文字為藍色 (不影響「註冊」與「登入」)
#branch li {
  color: blue;
}

▸ 屬性選擇器 (Attribute selector)

選擇 意義 範例
存在選擇
(Existence selector)
有該屬性 input[name] 可選到 <input type="text" name="username">
相等選擇
(Equality selector)
屬性值相等 input[name="username"] 可選到 <input type="text" name="username">
前綴選擇
(Prefix selector)
屬性值以某個字串開頭 input[name^="user"] 可選到 <input type="text" name="username">
後綴選擇
(Suffix selector)
屬性值以某個字串結尾 input[name$="name"] 可選到 <input type="text" name="username">

▸ 例如:

HTML:
<form method="post" action="#">
  <p>姓名:<input type="text" name="name"></p>
  <p>
    性別:
    <label><input type="radio" name="sex" value="F">女</label> 
    <label><input type="radio" name="sex" value="M">男</label>
  </p>
  <p><input type="submit" value="送出"></p>
</form>
CSS:
input[type="text"] {
  padding: 1em 2em;    /* 上下及左右內填充 */
  border: 1px solid blue;  /* 藍色外框 */
  color: blue;
  border-radius: 5px;    /* 圓角方框 */
  outline: none;    /* 刪除外框 */
}

input[type="text"]:focus {    /* 聚焦 */
  color: #ff00ff;
  background-color: lightyellow;
}

input[type="submit"] {
  background-color: lightblue;
}

input[type="submit"]:hover {    /* 滑鼠縈繞 */
  background-color: #9991f5;
}

∗ CSS 設定的優先順序

▸ 如果兩個選擇對應到相同元素,優先順序如下,例如:<p id="note"> ... </p>

✶ 有加 !important 者最優先
#note {
  color: red !important;    /* 優先 */
}
p {
  color: blue;
}
✶ 其次:較明確者優先
p#note {
  color: blue;    /* 優先 */
}
p {
  color: red;
}
✶ 再其次:後者優先 (覆蓋前者)
p {
  color: red;
}
p {
  color: blue;    /* 優先 */
}

▸ 在瀏覽器頁面按下 F12:開啟 Web Developer 插件,可以觀察 CSS 樣式的作用,並可動態設定樣式

(3) 設定背景顏色及影像

∗ 顏色設定之方式:

▸ 顏色名稱,例如:color: red;

▸ HEX 碼,例如:color: #ee3e80;

▸ RGB 值,例如:color: rgb(100, 100, 90);

▸ HSL 值,例如:color: hsl(120, 100%, 50%);

∗ 設定背景顏色

simplest.html

<!doctype html>
<html>
<head>
<title>Simplest page</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/simplest.css">
</head>
<body>

</body>
</html>

simplest.css

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;    /* 至少和瀏覽器一樣高 */
}

body {
  background-color: lightblue;
}

∗ 設定背景影像

▸ 重複式背景影像 (利用 background.jpg)

html, body {
  ...
}

body {
  background: url("../img/background.jpg");
}

▸ 不重複式:加上 background-repeat

...

body {
  ...
  background-repeat: no-repeat;
}

▸ 涵蓋式:加上 background-size

...

body {
  ...
  background-size: 100% 100%;
}

▸ 固定式 (不隨捲軸滑動):加上 fixed (先在 body 中加上大量文字)

...

body {
  background: url("../img/background.jpg") fixed;
  ...
}

(4) 文字字型

∗ 設定文字字型 (Font)

▸ font-family:設定字型系列

body {
  font-family: Georgia, Times, serif;
}
h1, h2 {
  font-family: Arial, Verdana, sans-serif;
}
h3 {
  font-family: "Courier New", Courier, monospace;
}

▸ 使用者的電腦或手持裝置必須安裝字型

▸ 字型系列確保如果使用者未安裝某個字型,還有其他可以適用

▸ 通常在字型系列的最後加上最基本的字型 (serif, sans-serif, monospace, …)

▸ 設計師的建議:網頁中最多不要超過 3 種字型,如此頁面才會美觀

∗ 設定文字尺寸 (Font size)

body {
  font-size: 2em;    /* 或 200%, 32px */
}

∗ 設定文字效果

▸ 字體

font-weight: bold;
font-style: italic;    /* 或 normal, oblique */

▸ 文字轉換

text-transform: uppercase;    /* 或 lowercase, capitalize */

▸ 文字裝飾

text-decoration: underline;    /* 或 overline, line-through, blink, none */

∗ 設定文字排版效果

▸ 行高、間距、對齊、縮排

line-height: 1.4em;
letter-spacing: 0.2em;
word-spacing: 1em;
text-align: justify;       /* 或 left, right, center */
vertical-align: text-top;  /* 或 baseline, sub, super, top, middle, bottom, text-bottom */
text-indent: 4em;

▸ 段落首字及首行

p:first-letter {
  font-size: 200%;
}
p:first-line {
  font-weight: bold;
}

▸ 陰影

text-shadow: 1px 1px 0 #000000; /* 陰影水平位置、陰影垂直位置、模糊度 (到無陰影的距離)、顏色 */
✶ 多個陰影
p#first {
  font-size: 10em;
  text-shadow: 0 0 3px #ff0000, 0 0 5px #0000ff;
}
✶ 範例: Design Shack, Line25
shadow1
shadow2
shadow3
shadow4
shadow5
shadow6
✶ FIRE 範例:
#fire {
  text-align: center;
  font-family: "League-Gothic", Courier;
  font-size: 15em;
  text-transform: uppercase;
  color: #fff;
  text-shadow:
     0     0   20px #fefcc9,
    10px -10px 30px #feec85,
   -20px -20px 40px #ffae34,
    20px -40px 50px #ec760c,
   -20px -60px 60px #cd4606,
     0   -80px 70px #973716,
    10px -90px 80px #451b0e;
}

∗ 連結之滑鼠效果

a:link {
  color: deeppink;
  text-decoration: none;
}
a:hover {
  color: deepskyblue;
  text-decoration: underline;
}
a:active {
  color: darkcyan;
}

∗ 鼠標變化

a {
  cursor: auto;    /* 或 crosshair, default, pointer, move, text, wait, help */
}
a {
  cursor: url(...) 10 10, auto;    /* 影像鼠標 (長寬分別為 10 及 10 像素,原始影像尺寸需小於 32x32),auto:如果 url 無法正確顯示,則回復預設值 */
}

▸ 作業 1

(5) 方框

∗ 設定方框 (Box) 尺寸

▸ 尺寸單位:像素值、百分比、em

▸ 寬度 width,最小寬度 min-width,最大寬度 max-width

▸ 高度 height,最小高度 min-height,最大高度 max-height

▸ 例如:

✶ HTML:
<div>
  <p>不管甜點是由法國那個地區所供應,形式是簡單的鄉村口味或是精細的宴會甜點, 法式甜點永遠使用最高品質的原料, 最新鮮與當令食材。法國甜點有著長久歷史,現代的甜點的來源也是法國。</p>
</div>
✶ CSS:
div {
  width: 30em;
  height: 20em;
  background-color: #7f7f7f;
}
p {
  width: 75%;
  height: 75%;
  background-color: #d2d2d2;
}
box1

▸ 影像亦可用相同方法設定尺寸:

✶ HTML:
<img id="myImg" src="myImg.png">
✶ CSS:
img#myImg {
  width: 12em;
  height: 12em;
}
✶ 或 (寬度隨包含元素縮放,高度隨寬度作等比例縮放)
img#myImg {
  width: 100%;
  height: auto;
}

∗ 方框屬性:邊線 (Border)、邊距 (Margin)、與填充 (Padding)

▸ 定義如下圖:

a: border-top-width, b: border-right-width, c: border-bottom-width, d: border-left-width
e: margin-top, f: margin-right, g: margin-bottom, h: margin-left
i: padding-top, j: padding-right, k: padding-bottom, l: padding-left
box2

▸ 邊線:方框的周圍,可設定可見、不可見、寬度、顏色、形式

border-width: 3px;
border-style: solid;    /* 或 dotted, dashed, double, groove, ridge, inset, outset */
border-color: #0088dd;
border: 3px dotted #0088dd;
✶ 各樣式均可分成四個邊線
# border-top-width, border-right-width, border-bottom-width, border-left- width
# border-top-style, border-right-style, border-bottom-style, border-left-style
# border-top-color, border-right-color, border-bottom-color, border-left- color

▸ 邊距:方框外圍與其他元素的距離

▸ 填充:方框內緣與所包含資訊的距離

▸ 例如:

p {
  margin-top: 1em;
  border-width: thin;    /* 或 medium, thick */
}
div {
  border-width: 2px;        /* 上下左右:2px */
  border-width: 2px 1px;    /* 上下:2xp,左右:1px */
  border-width: 2px 1px 1px 2px;    /* 上、右、下、左 */
  padding: 3px;
}

∗ 圓角框

border-radius 可設定方框為圓角框

▸ 例如:

HTML:
<p class="one">圓角框</p>
CSS:
p {
  border: 5px solid #ee3e80;
  padding: 1.5em;
  width: 6em;
  border-radius: 10px;
}

▸ 方框的四個角:

border-radius: 10px;         /* 四個角 */
border-radius: 10px 20px;    /* 左上右下, 右上左下 */
border-radius: 10px 20px 30px 40px;    /* 左上, 右上, 右下, 左下 */

∗ 資料滿溢 (Overflow)

▸ 如果方框中的資料量超過方框所能容納

hidden:隱藏不顯示
scroll:自動出現捲軸

▸ 例如:

p {
  overflow: hidden;
}
div {
  overflow: scroll;
}

∗ 區塊的對齊

▸ 預設:靠左

▸ 置中: margin: 0 auto; (0 為隨意值)

▸ 靠右:float: right;

∗ 區塊元素與行內元素的特性

▸ 區塊元素:

✶ 預設寬度:與環境寬度相同
✶ 預設高度:由內容決定
✶ 預設排列:由新行開始

▸ 行內元素:

✶ 預設寬度:由內容決定
✶ 預設高度:由內容決定
✶ 預設排列:由左至右接續

∗ 呈現區塊或行內模式

▸ 利用 display 將行內元素以區塊模式呈現或將區塊元素以行內模式呈現

display: inline 以行內模式呈現,特性像一個文字,左右並排,例如將 <li> 橫向排列
display: block 以區塊模式呈現,特性像一個區塊,上下排列,例如將 <a> 以區塊呈現
display: inline-block 以行內區塊模式呈現,特性像一個區塊,左右並排
display: none 將元素隱藏

▸ 例如製作導航按鈕:

✶ HTML: navButton.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Navigation buttons</title>
<link rel="stylesheet" href="css/navButton.css">
</head>
<body>

<nav>
  <ul>
    <li><a href="#">首頁</a></li>
    <li><a href="#">產品介紹</a></li>
    <li><a href="#">服務</a></li>
    <li><a href="#">關於我們</a></li>
    <li><a href="#">聯絡我們</a></li>
  </ul>
</nav>

</body>
</html>

✶ CSS: navButton.css
body {
  background-color: lightblue;
}

nav ul {
  margin: 0;
  padding: 0;
  text-align: center;
}

nav li {                    /* 做最少量的設定,大多數的設定在 <a> */
  display: inline-block;    /* 行內區塊顯示,因此允許橫向排列 */
  margin-right: 1em;        /* 按鈕間距 */
}

nav li a {                  /* 大多數的按鈕外觀在此設定 */
  display: block;           /* 區塊顯示,因此允許設定 padding */
  color: black;
  text-decoration: none;
  padding: 0.5em 2em;       /* 按鈕尺寸由 <a> 撐開 */
  background-color: lightgray;
  border-radius: 10px;
  border: 1px solid black;  
}

▸ 結果:

navButton.png

▸ 練習:製作以下導航按鈕

navButton2.png
✶ 規格:所有按鈕緊接,第一個按鈕左方圓角,最後一個按鈕右方圓角
✶ 提示:
# 消除 <li> 行內元素之間隔:開始標籤緊接著上一個結束標籤
<li><a href="#">首頁</a></li><li>
    <a href="#">產品介紹</a></li><li>
    <a href="#">服務</a></li><li>
# 設定第一個及最後一個 <li> 裡的 <a> 元素:
nav ul li:first-child a {
  ...
}

nav ul li:last-child a {
  ...
}

∗ 方框陰影

box-shadow:為方框加上陰影

▸ 例如:

✶ HTML:
<p class="one">各種不同形式的陰影,段落1</p>
<p class="two">各種不同形式的陰影,段落2</p>
<p class="three">各種不同形式的陰影,段落3</p>
<p class="four">各種不同形式的陰影,段落4</p>
<p class="five">各種不同形式的陰影,段落5</p>
✶ CSS:
p {
  margin-left: 1.5em;
  background-color: rgb(244, 218, 176);
  padding: 1.5em;
  width: 10em;
  display: inline-block;
}

.one {
  box-shadow: -5px -5px #555555;
}

.two {
  box-shadow: 5px 5px 5px #555555;
}

.three {
  box-shadow: 5px 5px 5px 5px #555555;
}

.four {
  box-shadow: 0 0 10px #555555;
}

.five {
  box-shadow: inset 0 0 10px #555555;
}

▸ 說明

✶ 三組數字:水平偏移 (Horizontal offset),垂直偏移 (Vertical offset),陰影顏色
✶ 四組數字:水平偏移,垂直偏移,模糊距離 (Blur distance),陰影顏色
✶ 五組數字:水平偏移,垂直偏移,模糊距離,陰影分散 (Spread of shadow),陰影顏色

▸ 結果:

shadow7

∗ 練習:設定背景顏色與影像加陰影

▸ 將 dessert2-1.htmldessert2-1.css 分別另存為 dessert2-2.htmldessert2-2.css,並如下修改:

✶ HTML:
# 更改 CSS 連結:<link rel="stylesheet" href="css/dessert2-2.css">
# 在 <img> 元素中加上 id<img id="dessertImg" src="img/dessert.jpg" alt="甜點影像">
✶ CSS:
# 背景顏色改為淡藍色
# 為影像添加黑框、圓角框、及上述「段落 3」的效果
dessert2-2

(6) 清單

∗ 設定清單樣式

list-style-type:設定清單編號或符號的格式

ol {
  list-style-type: decimal;    /* or: decimal-leading-zero, lower-alpha, upper-alpha, lower-roman, upper-roman */
}
ul {
  list-style-type: disc;    /* or: none, circle, square */
}

list-style-image:以影像取代清單編號或符號

ul {
  list-style-image: url("../img/star.png");
}

▸ 練習:將 dessert2-2.htmldessert2-2.css 分別另存為 dessert2-3.htmldessert2-3.css,並如下修改:

✶ 下載 star.png star.png 檔案並存到 img/ 目錄
✶ HTML:如下修改
# 更改 CSS 連結:<link rel="stylesheet" href="css/dessert2-3.css">
# 在 <ul> 元素中加上 id<ul id="open">
✶ CSS:將「開店時間」設定以星星影像為清單符號,拉開上下距離
dessert2-3

(7) 表格

∗ 設定表格樣式

▸ 表格樣式的建議

✶ 儲存格內一定要有填充,以免資料接觸儲存格邊線,難以閱讀
✶ 表格標題列應與其他列有所不同 (例如加粗體)
✶ 隔一列加上陰影,使每列資料有所區隔,方便閱讀
✶ 數字應對齊

▸ 練習:將 dessert2-3.htmldessert2-3.css 分別另存為 dessert2-4.htmldessert2-4.css,並如下修改:

✶ HTML:
# 更改 CSS 連結:<link rel="stylesheet" href="css/ dessert2-4.css">
# 表格加上 id 以便 CSS 選擇 <table id="branch">
✶ CSS:做以下設定
# 表格:總寬度 (width)、 上下邊線、內部不要格線
# 標題列的字型大小、對齊、背景顏色 (font-size, border-top, border-bottom, text-align, background-color)
# 其餘各列的背景以不同顏色顯示 (even, odd),滑鼠移至某列時變色 (hover)
# 儲存格填充 (padding)
...

/* Table styles */
table#branch {
  width: ...;
  border-bottom: ...;
  border-collapse: collapse; 
}

table#branch th {
  text-align: ...;
  font-size: ...;
  border-top: ...;
  border-bottom: ...;
  background-color: ...;
}

table#branch tr:nth-child(odd) {
  background-color: ...;
}

table#branch tr:nth-child(even) {
  background-color: ...;
}

table#branch tr:hover {
  background-color: ...;
}

table#branch th,
table#branch td {
  padding: ...;
}
✶ 結果:
dessert2-4

▸ 作業 2

(8) 漸層

∗ 顏色漸層型態

▸ 線性漸層

✶ 背景顏色從上到下漸層
background: linear-gradient(<color1>, <color2>);
background: linear-gradient(to bottom, <color1>, <color2>);
✶ 由左到右
background: linear-gradient(to right, <color1>, <color2>);
✶ 由左上到右下
background: linear-gradient(to bottom right, <color1>, <color2>);
✶ 多種顏色
background: linear-gradient(<color1>, <color2>, <color3>);

▸ 輻射漸層

✶ 等距輻射漸層
background: radial-gradient(red, green, blue);
✶ 不等距
background: radial-gradient(red 5%, green 15%, blue 60%);

(9) 表單

∗ 設定表單樣式

▸ 沒有人喜歡填表單,因此,表單一定要設計得很吸引人

▸ 經常設定樣式的表單元素:文字輸入、文字區塊、送出按鈕、控制項的標籤

▸ 範例:將 dessert2-4.htmldessert2-4.css 分別另存為 dessert2-5.htmldessert2-5.css,並如下修改:

✶ HTML:
# 更改 CSS 連結 <link rel="stylesheet" href="css/dessert2-5.css">
# 註冊會員:在性別資訊之後增加三個欄位
<p>行動電話:<input id="mobile" type="text" name="mobile"></p>
<p>電子信箱:<input id="email" type="email" name="email"></p>
<p>個人網頁:<input id="web" type="text" name="web"></p>
Fig.2-1
✶ CSS:
# 設定文字輸入欄的樣式為淡黃色背景、圓角框、內填充、有三個小圖示、滑鼠縈繞時顯示紅色框
formStyle1
formStyle2
# HTML:設定輸入欄的 classid 以便 CSS 選擇
- 將表單加上 id 以便 CSS 選擇:<form id="member" ...>
- 設定需設黃色底色的文字輸入元素的類別 text (name = username, password, mobile, email, web):
<input class="text" type="text" ...>
- 需設背景小圖示的文字輸入元素再加一個類別 padding (name = mobile, email, web):
<input id="mobile" class="text padding" type="text" ...>
<input id="email" class="text padding" type="email" ...>
<input id="web" class="text padding" type="text" ...>
# CSS:設定各式 inputselect 元素的效果 (font-size, color, background-color, border-radius, margin-bottom, background-position, background-repeat)
- 文字效果:
/* Form styles */
#member .text {
  font-size: ...;
  color: ...;
  ...
}
- inputselect 類別的聚焦及滑鼠縈繞時的邊線變化 (:focus, :hover)
#member .text:focus,
#member .text:hover,
#member select:hover {
  border: ...;
}
- mobile, email, web 欄位:個別設定背景圖 (mobile.png mobile.png, email.png email.png, web.png web.png), 並設定填充使輸入點避開背景圖 (background-image, padding)
#member input#mobile {
  background-image: ...;
  background-repeat: ...; 
  background-position: ...; 
}
#member input#email {
  background-image: ...;
  ... 
}
#member input#web {
  background-image: ...;
  ... 
}
#member input.padding {
  padding: ...;
}
- 設定 <select> 字體尺寸、填充、圓角 (font-size, padding, border-radius)
#member select {
  font-size: ...;
  ...
}
# 設定送出按鈕樣式如下圖:
btn1
- 設定按鈕文字顏色、填充、背景顏色、漸層背景 (color, padding, background-color, linear-gradient)
#member input[type="submit"] {
  color: ...;
  padding: ...;
  background: linear-gradient(...);
}
- 設定滑鼠移至按鈕:顏色、邊線、上邊線、背景顏色、漸層背景 (color, border, border-top, background-color, background)
    btn2
#member input[type="submit"]:hover {
  background: linear-gradient(...);
}
# 設定 <fieldset><legend> 元素樣式如下圖:
fieldset
- <fieldset>:寬度、邊線、圓角、填充、文字對齊 (width, border, border-radius, padding, text-align)
- <legend>:背景顏色、邊線、圓角框、填充、文字對齊 (background-color, border, border-radius, padding, text-align)
/* Fieldset settings */
#member fieldset {
  width: ...;
  ...
}
#member legend {
  background-color: ...;
  ...
}

▸ 作業 3

(10) 網頁佈局

▸ HTML 將每個 HTML 元素視為一個方框 (Box)

▸ HTML 元素可以是區塊方框 (Block box) 或是行內方框 (Inline box)

▸ 如果一個區塊元素內含另一個區塊元素,則外部元素稱為包含元素 (Containing element) 或父元素 (Parent element)

▸ 正常流動 (Normal flow):

✶ 區塊方框預設的特性是從新行開始,所有區塊僅能縱向排列, 且區塊的寬度等於其包含元素的寬度
✶ 行內方框可以存在一行內,並與周圍文字一起流動

▸ 方框的另一重要屬性:構成網頁的佈局 (Layout)

∗ 設定元素位置的方式:

▸ 相對定位 (Relative positioning):相對於該區塊的 原始位置 可設定 top, bottom, left, right 距離,區塊原始空間會保留, 並且不影響到其他元素的位置

▸ 絕對定位 (Absolute positioning):相對於 參考元素 位置可設定 top, bottom, left, right 距離,區塊元素退出正常流動模式, 且其原始空間不保留

✶ 參考元素:
# 如果其上層元素有設定定位 (relative, absolute, 或 fixed),則參考該元素 (一層層向上搜尋)
# 如果其所有上層元素都沒有設定定位,則參考 <body> 元素

▸ 固定定位 (Fixed position):相對於 瀏覽器視窗位置 可設定 top, bottom, left, right 距離,因位置固定因此不會隨捲軸移動, 區塊元素退出正常流動模式,且其原始空間不保留

▸ 範例:bicycle.html (文章來源)

<!doctype html>
<html>
<head>
<title>單車的演進</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bicycle.css">
</head>  
<body>

<div>
  生命就像騎單車,要維持平衡就必須不斷前進。  -愛因斯坦
</div>

<div id="position">
  西元1817年,Baron von Drais 發明了一種走路機器,讓他在皇家花園裡能快速移動:
  有兩個同樣大小排成直線的輪子,前輪可操縱方向。該裝置透過你的腳朝地面踩動而產生動力,
  將你和車子一同向前推去,就像滑行走路一般。
</div>

<div>
  該機器後來被稱為 Draisienne (Dandy horse) 或興趣馬 (Hobby horse)
  ,它是完全用木頭做成的。這種車子曾短暫的流行,但必須在維護很好的路面上才能行走,
  例如在公園或花園。
</div>

<div>
  之後兩輪騎乘機器在 1865 年再次出現,踏板直接接在前輪,這種機器被稱為 Velocipede
  (快腳),但大家也都知道它是「骨頭振動器」,因為它也是用木頭做成,後來改為金屬輪胎。
  它行走在當時鵝卵石路上,的確非常不舒適。但它們後來也成為了一種時尚,
  在當時的大城市裡都可以看到可以在室內騎,類似於現在滾輪溜冰場。
</div>

</body>
</html>


bicycle.css
所有 div 設定內填充與邊線, div#position 設定顏色、無邊線,所有區塊預設正常流動
div {
  padding: 0.5em;
  border: 1px solid blue;
}

div#position {
  color: red;
  border: none;
}
✶ 相對定位:將 div#position 設為相對定位,並設定上方與左方距離 div#position 依舊維持正常流動 (僅更改位置),其餘 div 位置不動
bicycle.css
...

div#position {
  ...
  top: 1em;
  left: 6em;
  position: relative;
}
✶ 絕對定位:將 div#position 設為絕對定位, 參考位置為 body div#position 退出正常流動,其位置由之後的元素取代
bicycle.css
...

div#position {
  ...
  position: absolute;
}
✶ 固定定位:將 div#position 區塊設為固定定位,參考位置為瀏覽器 div#position 退出正常流動,其位置由下一個元素佔據,且不隨捲軸移動
bicycle.css
...

div#position {
  ...
  position: fixed;
}
✶ 區塊重疊:區塊位移後,有可能會和其他區塊重疊,可利用 z-index 屬性決定該顯示那個區塊 (註:區塊必須要設定 position 屬性才能使用 z-index 屬性)
div {
  ...
  border: 1px solid blue;
  position: relative;
  z-index: 10;
  background-color: lightblue;
}
...

div#position {
  ...
  z-index: 5;
  background-color: lightgreen;
}
# z-index 值越高,區塊在越上層

∗ 設定元素流動

▸ 流動元素 (Floating element):區塊元素設定流動後,該區塊退出正常流動,但其後元素的 內容 會相對流動,亦稱為「文繞圖」

▸ 範例 (bicycle.html 相同):

bicycle.css
div {
  padding: 0.5em;
  border: 1px solid blue;
}

div#position {
  float: left;
  width: 15em;
  color: red;
  border: none;
}
div#position 區塊退出正常流動, 其位置由下一個元素取代,但之後區塊的元素會圍繞流動

▸ 包含元素崩潰 (Collapse of the containing element)

✶ 當設定元素流動後,該元素就會跳出包含元素 (父元素),造成包含元素崩潰 (Collapse),例如以下 <ul> 裡的所有 <li> 元素均設為流動,則 <ul> 裡就沒有任何元素了:
floatMenu.html
<!doctype html>
<html>
<head>
<title>流動元素:防止父元素崩潰</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/floatMenu.css">
</head>
<body>

<ul id="nav">
  <li><a href="#">首頁</a></li>
  <li><a href="#">圖示</a></li>
  <li><a href="#">設計</a></li>
  <li><a href="#">工具</a></li>
</ul>

</body>
</html>
floatMenu.css
ul#nav {
  margin: 0;
  padding: 0;
  border: 1px solid red;
}

ul#nav li {
  float: left;
  list-style: none;
  margin-right: 2em;
}
<ul> 區塊裡沒有內容,因此沒有高度:
floatMenu
✶ 防止包含元素崩潰可參考 這裡這裡,解決方案之一:設定包含元素 overflow: auto;
floatMenu.css
ul#nav {
  ...
  overflow: auto;
  border: 1px solid red;
}
<ul> 區塊可以保有其高度:
floatMenu2

∗ 左側固定選單佈局

fixedMenu.html

<!doctype html>
<html>
<head>
<meta charset="utf8">
<link rel="stylesheet" href="css/fixedMenu.css">
</head>  
<body>

<div id="menu">
  <h1>選單</h1>
  <p><a href="#">交通資訊</a></p>
  <p><a href="#">住宿資訊</a></p>
  <p><a href="#">用餐資訊</a></p>
</div>

<div id="content">
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
  <p>網頁內容</p>
</div>

</body>
</html>

fixedMenu.css:

html, body {
  padding: 0;
  margin: 0;
}

#menu {
  position: fixed;
  width: 6em;
  background-color: lightblue;
}

#content {
  margin-left: 6em;
  background-color: lightgreen;
}

p {
  margin: 0;
  padding: 0;
}

position

∗ 利用 Float 佈局

▸ 設定連續區塊元素的流動特性,就可以讓區塊左右排列

layoutFloat.html:
<!doctype html> 
<html> 
<head> 
<meta charset="utf-8"> 
<link rel="stylesheet" href="css/normalize.css"> 
<link rel="stylesheet" href="css/layoutFloat.css"> 
</head> 
<body> 

<div id="wrapper">
  <nav>這是 nav</nav>
  <header>這是 header</header>
  <div id="container">
    <aside>這是 aside</aside>
    <div id="content">這是 content</div>
  </div>
  <footer>這是 footer</footer>
</div>

</body>
</html>
#wrapper 元素包含所有元素:nav, header, #container, footer
#container 元素包含:aside, #content

▸ 擬佈局樣式

layout

css/layoutFloat.css:

* {
  box-sizing: border-box;
}

hmtl, body {
  height: 100%;
}

div#wrapper {
  margin: 0 auto;
  width: 80%;
}

nav {
  height: 4em;
  border: 1px solid red;
}

header {
  height: 6em;
  border: 1px solid blue;
}

div#container {
  overflow: auto;
}

aside {
  width: 20%;
  height: 20em;
  float: left;
  border: 1px solid green;
}

div#content {
  width: 80%;
  height: 20em;
  float: left;
  border: 1px solid brown;
}

footer {
  border: 1px solid olive;
}
✶ 所有區塊都設定邊線,以便觀察佈局是否正確
box-sizing:方框尺寸的計算是包含邊線,以免加上邊線會增加其寬度
html, body:高度與瀏覽器高度相同,無邊界與內填充
#wrapper:所有資料的最外框,用來做整體設定,並且置中與設定 80% 比例寬度
nav, header:設定高度
#container:防止崩潰
aside:設定 20% 寬度 (相對 #wrapper 而言),設定固定高度,並向左流動
#content:設定 80% 寬度,高度與 aside 相同,也設定向左流動因此會和 aside 並排

∗ 利用 Flex 佈局

Flex 是 Flexbox 的簡寫,亦即彈性區塊

▸ 佈局樣式與前述相同

▸ HTML:類似 layoutFloat.html

layoutFlex.html
...
<link rel="stylesheet" href="css/layoutFlex.css">

...

layoutFlex.css (類似 layoutFloat.css):

...

div#container {
  display: flex;
  flex-direction: row;
}

aside {
  height: 20em;
  flex: 1 2 20%;
  background-color: green;
}

div#content {
  height: 20em;
  flex: 1 1 80%;
  border: 1px solid brown;
}

...
display: flex;:設定該區塊使用 Flex 佈局
flex-direction:需搭配 Flex 佈局使用,預設就是 row (列並排),不過習慣上我們還是會寫一下標明清楚
flex: 1 2 20%; 意思是自動擴展 (與其他元素比例為 1)、當寬度不足時縮小 2 倍、基礎寬度佔父元素的 20%,也可以如下撰寫:
flex-grow: 1;       /* 0 表示不擴展,1 表示與其他元素依照 1:1 的比例擴展 */
flex-shrink: 2;     /* 寬度不足時縮小兩倍 */
flex-basis: 20%;    /* 基礎佔寬 20% */

∗ 利用 Grid 佈局

Grid 是網格佈局,將網頁視為許多網格

▸ 佈局樣式與前述相同

▸ HTML:類似 layoutFlex.html

...
<link rel="stylesheet" href="css/layoutGrid.css">

...

layoutGrid.css (類似 layoutFlex.css):

...

div#container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

aside {
  height: 20em;
  border: 1px solid green;
}

div#content {
  height: 20em;
  border: 1px solid brown;
}

...
display: grid;:設定該區塊使用 Grid 佈局
grid-template-columns;:需搭配 Grid 佈局使用, 讓裡面區塊元素的寬度分別為 1/4 與 3/4 (Fraction)

▸ 作業 4

(11) CSS 預處理器與框架

∗ CSS 預處理器 (Preprocessor)

▸ CSS 預處理器有自己的語法,將程式設計的概念導入,使樣式設定更有邏輯、效能更高,設計完畢最後再產生 CSS 檔案

▸ 產品:Less, Sass, Stylus, ...

▸ Stylus 範例:

✶ 省略大括號、冒號、與分號
body
  background-color blue
✶ 變數
blue = #475cd1
red = #be2525
body
  background-color blue
  color red
  border 1px solid @color
✶ 函式與參數
background-color(color)
  background-color color

body
  background-color(blue)

∗ CSS 框架 (前端框架, CSS framework, front-end framework)

▸ CSS 框架:已設計好許多樣式,只要在 HTML 元素裡加上類別即可

▸ 產品:Bootstrap, Foundation, Bulma, ...