CSS 的魔法
csszengarden 這網頁裡面的 HTML
是一模一樣的,只是載入不同的 CSS 樣式
而已
引入樣式的方法
-
內聯
<div style="color: red;"> 這是哪裡啊 </div>
-
內部引入
<head> <style> div { color: red; } </style> </head>
-
外部引入
<!-- 這裡是 index.html --> <head> <link rel="stylesheet" type="text/css" href="./index.css" /> </head>
/* 這裡是 index.css */ div { color: red; }
越靠近的,權重越高 => 內聯
CSS 語法
先選到你要改變的元素,再來套用規則
div {
color: red;
text-align: center;
}
選擇器
- id 選擇器
#myid { color: red; }
- class 選擇器
.myclass { color: red; }
- tag 選擇器
div { color: red; }
- 組合選擇器
- 後代選擇器
div p { color: red; }
- 兒子和孫子都會被選到
- 子代選擇器
div > p { color: red; }
- 只有兒子會被選到
- 相鄰選擇器
div + p { color: red; }
- 只有第一個弟弟才被選到
- 兄弟選擇器
div ~ p { color: red; }
- 後面的弟弟才被選到
- 後代選擇器
-
:hover
- 滑鼠在元素上的時候
:active
- 點擊元素的時候
:disabled
- 元素禁用的時候
:first-child
- 匹配到的第一個元素
:last-child
- 匹配到的最後一個元素
:nth-child(n)
- 匹配到的第 n 個元素
- 注意:n 從 1 開始算
- n 為
odd
代表 匹配到的第「奇數」個 - n 為
even
代表 匹配到的第「偶數」個
-
偽元素
- 「偽元素」之所以稱作「偽」,除了英文從「Pseudo」翻譯過來之外,就是因為它並不是真正網頁裡的元素,但行為與表現又和真正網頁元素一樣,也可以對其使用 CSS 操控
- 優點:
- 不佔用 DOM 節點,減少 DOM 節點數量
- 避免增加毫無意義的頁面元素
- 缺點: - 偽元素不真正在 HTML 內容中體現,只在視覺效果上體現,所以不能給偽元素添加具有實際意義的內容,這部分內容不會搜索引擎抓取
- 優點:
::before
預設在原本內容
前::after
預設在原本內容
後- 一定要具備
content
的屬性,不然顯示不了 - 為了和「偽類選擇器」做區隔
- W3C 定義「偽元素」使用
::
- 而「偽類選擇器」則使用
:
- 但現在瀏覽器就算寫一個冒號
:
也可以
- W3C 定義「偽元素」使用
- 「偽元素」之所以稱作「偽」,除了英文從「Pseudo」翻譯過來之外,就是因為它並不是真正網頁裡的元素,但行為與表現又和真正網頁元素一樣,也可以對其使用 CSS 操控
- 選擇器權重
!important
>id
>class
>tag
- 自己 > 爸爸 > 阿公
- 自己 id > 自己 class > 自己 tag > 爸爸 id > 爸爸 class > 爸爸 tag > 阿公 id > 阿公 class > 阿公 tag
字型
font
font-size
改變字體大小- 大部分瀏覽器預設是 16px
font-family
改變字型- 用逗號
,
隔開每個你想設定的字型,接著的工作就讓瀏覽器自己去判斷 - 字型設定並不會自動下載字型檔案,如果用戶端沒有你設定的字型,有可能無法正確顯示你要的效果,所以建議除了明確字型之外,最好要加上通用字型,以確保網頁呈現
- 用逗號
font-weight
改變粗體細體- bold
- 100、200、300…900
div {
font-size: 20px;
font-family: serif, sans-serif, cursive, fantasy, monospace;
font-weight: bold;
}
顏色
color
改變文字顏色background-color
改變背景顏色- 設定顏色
- 十六進制 Hex
- 例如
#FF0000
- 例如
- RGB
- 例如
RGB(255, 0, 0)
- 例如
- 常用的顏色
- 例如
red
、blue
、green
、yellow
、white
、black
等等
- 例如
- 十六進制 Hex
button {
color: #ffffff;
background-color: #4a86e9;
}
邊框
border
border-width
邊框粗細border-style
邊框類型solid
實線dashed
虛線
border-color
邊框顏色border-radius
邊框圓角
button {
border: 1px solid red;
border-radius: 16px;
}
/* 等價於這樣寫 */
button {
border-width: 1px;
border-style: solid;
border-color: red;
border-radius: 16px;
}
文字對齊
text-align
left
center
right
透明度
opacity
- 設定範圍 0 ~ 1
- 1 代表完全不透明
- 0 代表完全透明
游標
- cursor
- pointer 讓人看起來可以點
box-model 盒模型
每一個東西都是一個盒子(Box)
- margin 外面距離
- border 邊框
- padding 裡面距離
- width 寬度
- height 高度
margin 與 padding
margin
與padding
最大的差別?- 點擊範圍含
border
、padding
、width
、height
,不包含margin
- 點擊範圍含
margin
語法 (padding
一樣)- 1 個數值,
上下左右
- 2 個數值,
上下
左右
- 3 個數值,
上
左右
下
- 4 個數值,
上
右
下
左
,順時針 auto
,讓瀏覽器自己去設定
- 1 個數值,
button {
padding: 8px;
padding: 8px 16px;
padding: 8px 16px 10px;
padding: 8px 16px 10px 16px;
}
display
block
- 總是獨佔一行 (width 100%)
- div、form、h1、h2、h3、h4、h5、h6、hr、ol、p、table、ul、li
inline
- 看內容多大就多大,和別人併排
- 無法設定 width、height、padding-top、padding-bottom、margin-top、margin-bottom
- a、img、input、label、select、span、textarea
inline-block
- 看內容多大就多大,和別人併排
- 可以設定 width、height、padding-top、padding-bottom、margin-top、margin-bottom
隱藏元素
display: none
與 visibility: hidden
都可以隱藏元素
display:none
不會佔空間visibility:hidden
會保留原本的空間
寬度與高度
height
高度min-height
最小高度max-height
最大高度width
寬度min-width
最小寬度-
max-width
最大寬度 -
規則
height
>max-height
時,會吃max-height
height
<max-height
時,會吃height
min-height
>max-height
>height
時,會吃min-height
-
例如:試試看縮放視窗
div { width: 50%; min-width: 100px; max-width: 300px; }
-
設置
height: 100%
無效?- 原因
- 可能是因為父元素沒有設定
height
為px
或%
,此時父元素會根據子元素的高度而撐開,導致子元素的height: 100%
失去基準值而無效
- 可能是因為父元素沒有設定
- 解決
- 方法 1
- 幫父元素設置 height 且單位為
px
或%
或em
或rem
- 幫父元素設置 height 且單位為
- 方法 2
- 一路從
<html>
、<body>
、…、父元素(全部祖先)都設置height: 100%
- 一路從
- 方法 1
- 參考資料
- 原因
-
如何讓 height 與 width 變成實際的長寬?
box-sizing: border-box
讓height (width) = border + padding + height (width)
長度單位
px
- pixels 像素
- 相對於顯示設備,相對於「顯示設備 pixel 的高度/寬度」
-
%
-
以父容器高 / 寬度作為基準
屬性 100% 的基準 padding 父容器寬度 margin 父容器寬度 width 父容器寬度 height 父容器高度
-
vw
- 以瀏覽器可視寬度作為基準
- 1vw = 瀏覽器可視寬度的 px / 100
vh
- 以瀏覽器可視高度作為基準
- 1vh = 瀏覽器可視高度的 px / 100
-
em
-
當下
font-size
的字母(大寫)M
寬<head> <style> body { font-size: 14px; } .parent { font-size: 1.5em; /* 14px * 1.5 = 21px */ } .child { font-size: 1.3em; /* 21px * 1.3 = 27.3px */ } </style> </head> <body> <div class="parent"> parent <div class="child"> child </div> </div> </body>
-
-
rem
-
相對於「根元素字型的大小」,等同於相對
<body>
的em
<head> <style> body { font-size: 14px; } .parent { font-size: 1.5rem; /* 14px * 1.5 = 21px */ } .child { font-size: 1.1rem; /* 14px * 1.1 = 15.4px */ } </style> </head> <body> <div class="parent"> parent <div class="child"> child </div> </div> </body>
-
定位元素
-
position
static
- 原本的位置 (預設)
relative
- 相對原本的位置
absolute
- 絕對定位
- 對齊點最近「非
static
」特性的祖先 (就是 relative、absolute) - 沒找到的話,就去對
<body>
fixed
- 相對瀏覽器的位置
- 無視捲軸的滾動,就是固定在那裡
sticky
relative
與fixed
合體- 一開始為
relative
,滾輪滾到某個程度,會轉為fixed
- 需指定
top
或right
或bottom
或left
,才會生效 - 瀏覽器支援度較低
-
position: static
<div class="box box1">box1</div> <div class="box box2">box2</div> <div class="box box3">box3</div>
.box { height: 100px; width: 200px; } .box1 { background: red; } .box2 { background: blue; } .box3 { background: green; }
-
position: relative
.box { height: 100px; width: 200px; } .box1 { background: red; } .box2 { background: blue; position: relative; top: 10px; left: 30px; } .box3 { background: green; }
-
position: fixed
.box { height: 100px; width: 200px; } .box1 { background: red; } .box2 { background: blue; position: fixed; top: 10px; left: 30px; } .box3 { background: green; }
-
position: absolute
<div class="wrapper"> <div class="box box1">box1</div> <div class="box box2">box2</div> <div class="box box3">box3</div> </div>
.wrapper { margin: 50px; border: 5px solid yellow; width: 400px; } .box { height: 100px; width: 200px; } .box1 { background: red; } .box2 { background: blue; position: abosulte; top: 10px; left: 30px; } .box3 { background: green; }
浮動式排版 - float
有 float: left
、float: right
兩種可供選擇
它會將該元素整個往左、往右移並脫離網頁原先流向
更強大的排版工具 - Flexbox
- 分為兩種
Flex Container
父容器Flex Item
子項目
- 方向
main axis
主軸cross axis
交叉軸(垂直主軸)
- 父容器
display: flex
flex-direction
設定主軸的方向row
左->右row-reverse
右 -> 左column
上 -> 下column-reverse
下 -> 上
justify-content
主軸的對齊方式flex-start
主軸的起點 (預設)flex-end
主軸的終點center
主軸中間space-between
剩餘的空間平均分配,起點和終點沒有space-around
剩餘的空間平均分配
align-items
交叉軸的對齊方式flex-start
交叉軸的起點flex-end
交叉軸的終點center
交叉軸中間stretch
延伸baseline
與文字基線對齊
flex-wrap
當子層的數量太多,可以決定要不要換行nowrap
不換行(預設)wrap
換行wrap-reverse
換行時反轉
-
子項目
flex
是flex-grow
、flex-shrink
和flex-basis
的縮寫flex-grow
伸展的比例 (空間還有多的時候,我分到剩下空間的比例)- 值是數字且無單位,不可以為負值
- 預設是 0,代表不會放大
flex-shrink
壓縮的比例 (空間不夠時,我可以壓縮我自己的比例)- 值是數字且無單位,不可以為負值
- 預設是 1,代表要壓縮的話,我可以算 1 等分
flex-basis
項目的基準值- 值可以是
%
、px
、em
、rem
- 如果主軸是
row
或row-reverse
,flex-basis
等同於設置width
- 如果主軸是
column
或column-reverse
,flex-basis
等同於設置height
- 值可以是
order
重新定義排列順序- 從小排到大
-
詳細
flex-grow
與flex-shrink
的計算公式- 參考 详解 flex-grow 与 flex-shrink
-
flex-grow
父 子 1 子 2 子 3 寬度 500px 100px 150px 100px flex-grow 1 2 3 - 所以剩餘空間為
500px - 100px - 150px - 100px = 150px
- 權重總和是
1 + 2 + 3 = 6
- 子 1 還可以多分 =
150px * 1/6 = 25px
- 子 2 還可以多分 =
150px * 2/6 = 50px
- 子 3 還可以多分 =
150px * 3/6 = 75px
父 子 1 子 2 子 3 寬度 500px 100px 150px 100px flex-grow 1 2 3 還可以多拿 25px 50px 75px 最後顯示的寬度 125px 200px 175px - 所以剩餘空間為
-
flex-shrink
父 子 1 子 2 子 3 寬度 500px 150px 200px 300px flex-shrink 1 2 3 - 所以不夠空間 =
500px - 150px - 200px - 300px = -150px
- 權重總和
1 * 150px + 2 * 200px + 3 * 300px = 1450px
- 子 1 可以壓縮 =
150px * ((1 * 150px) / 1450px) = 15.5px
- 子 2 可以壓縮 =
150px * ((2 * 200px) / 1450px) = 41.4px
- 子 3 可以壓縮 =
150px * ((3 * 300px) / 1450px) = 93.1px
父 子 1 子 2 子 3 寬度 500px 150px 200px 300px flex-shrink 1 2 3 可以壓縮 15.5px 41.4px 93.1px 最後顯示的寬度 134.5px 158.6px 206.9px - 所以不夠空間 =
overflow 溢位
當內容超過元素的大小時,會產生 overflow
- overflow
overflow: visible
- 會呈現在元素框外
- 預設值
oveflow: hidden
- 內容會被修剪,超出的地方就看不到了
overflow: scroll
- 內容會被修剪,但是瀏覽器會顯示滾動條,以便查看其餘內容
overflow: auto
- 如果內容被修剪,則會出現滾動條
圖層關係
z-index
圖層順序- 數字越大越上面
讓網頁排版在各瀏覽器快速一致化的重置歸零
在 W3C
制訂 HTML
與 CSS
規格時,並沒有強制規定各家瀏覽器應該怎樣實作每一個 HTML tag 的 CSS 預設樣式,導致各家瀏覽器顯示差異
- 重置 CSS
- CSS Reset
- 做法是把所有瀏覽器最不一致的地方強制歸 0
- 優點是統整、重置了各個瀏覽器的樣式設定
- 缺點是必須全部重新做設定,比較沒有彈性,而且在使用開發者工具時會看到一大坨的繼承鏈
- Normalize CSS
- 保留有用的瀏覽器默認設置,而不是將其刪除
- 為廣泛的 HTML 元素提供一般化的樣式
- 修正瀏覽器的 Bug 與不一致
- 透過微妙的改善提高可用性
- 有詳細的文檔來解釋代碼
- CSS Reset
/* reset.css */
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
font,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol,
ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption,
th,
td {
text-align: left;
font-weight: normal;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
}
blockquote,
q {
quotes: "" "";
}
變形
transform
變形translate
平移rotate
旋轉角度scale
放大縮小
對 transform 有興趣的也可以參考我之前在公司前端分享會的主題 - Transform 變形
div:hover {
transform: translate(30px, 40px) rotate(90deg) scale(1.2);
}
動畫效果
CSS3 中有兩個用來做動畫的屬性,一個是 Transition
,另一個是 Animation
transition
過渡動畫- 在給定的持續時間內平滑地更改屬性值(從一個值到另一個值)
transition: [property 名稱] [duration 時間] [timing-function 特效] [delay 延遲]
- 屬性名稱為
all
,代表所有屬性都套用
- 屬性名稱為
<div class="box"></div>
.box {
width: 100px;
height: 100px;
background: blue;
transition: width 0.3s ease-in;
}
.box:hover {
width: 200px;
height: 200px;
background: red;
}
陰影效果
vertical-align
- 用來指定行內元素(inline)或表格單元格(table-cell)元素的垂直對齊方式
- MDN - vertical-align
置中對齊的方法
其他可以參考 CSS 垂直置中技巧,我只會 23 個,你會幾個
-
文字水平置中 -
text-align
<div class="content">Lorem ipsam.</div>
.content { text-align: center; width: 400px; background: #ccc; }
-
單行文字垂直置中 -
line-height
<div class="parent"> <div class="child"> Lorem ipsam. </div> </div>
.parent { border: 1px solid black; width: 400px; height: 100px; } .child { line-height: 100px; background: #ccc; }
-
block 塊級水平置中 -
margin auto
<div class="parent"> <div class="child"></div> </div>
.parent { width: 400px; border: 1px solid black; } .child { width: 100px; height: 100px; background-color: blue; margin: 0 auto; }
-
絕對定位水平垂直置中 -
position + translate
<div class="parent"> <div class="child"></div> </div>
.parent { width: 400px; height: 300px; border: 1px solid black; position: relative; } .child { width: 100px; height: 100px; background-color: blue; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
-
flexbox
<div class="parent"> <div class="child"></div> </div>
.parent { width: 400px; height: 300px; border: 1px solid black; display: flex; justify-content: center; align-items: center; } .child { width: 100px; height: 100px; background-color: blue; }