CSS-2
===
## 元素顯示與隱藏
### display
`dispaly: none;`
> - 隱藏且==不佔位==
`display: block;`
> - 轉為塊元素
> - 顯示
### visibility
`visibility: hidden;`
> - 隱藏, ==佔位==
`visibility: visible;`
> - 顯示
### overflow
> - 當一個盒子內容物超出時會溢出
<img src="https://i.imgur.com/L1YR3qy.png" style="width:100px"/>
> - `overflow: visible;`: 默認, 啥也不幹
> - `overflow: auto;`: ==超出時==顯示滾動條, 不讓內容溢出
> - `overflow: scroll;` : 總是顯示滾動條 (實際測試: Chrome77還是要溢出才有滾動條)
> - `overflow: hidden;` : 溢出部分直接隱藏, 也沒有滾動條
### 實作: 滑鼠經過後顯示NameTag
> - 這招經常使用在導航Bar, 經過時顯示導航細項
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
line-height: 100px;
background: gray;
color: white;
text-align: center;
margin: 300px auto;
position: relative;
}
div img {
width: 200px;
position: absolute;
left: 100px;
top: 0;
display: none;
}
div:hover img {
display: block;
}
</style>
</head>
<body>
<div>
NameTag
<img src="NameTag.png"/>
</div>
</body>
```
## CSS用戶界面樣式
### 滑鼠
> 移動到目標時的滑鼠樣式
> - `cursor: default;` <img src="https://i.imgur.com/skuz2pj.png" style="width:20px"/>
> - `cursor: pointer;` <img src="https://i.imgur.com/nsb0dhn.png" style="width:20px"/>
> - `cursor: move;` <img src="https://i.imgur.com/Pf72Aqm.png" style="width:20px"/>
> - `cursor: text;` <img src="https://i.imgur.com/oivlAV9.png" style="width:18px"/>
> - `cursor: hand;` 也是<img src="https://i.imgur.com/oivlAV9.png" style="width:18px"/> ,但FireFox不支持
> - `text` IE6以上都支持,故盡量使用這個
> - `cursor: not-allowed;`
### 輪廓 outline
<img src="https://i.imgur.com/tAlmFxi.png" style="width:100px"/> -> <img src="https://i.imgur.com/IJMvvU5.png" style="width:100px"/>
> - 在border外圍的線( 不是Border )
> - 設置 `{outline: outline-color | outline-style | outline-width}`
> - input點擊輸入時預設是有的
> - 刪除 `<input type="text" style="outline: 0;" />` 或 `style: none;`
### 防止拖曳文本域 resize
> - 文本域 `<textarea></textarea>`
<img src="https://i.imgur.com/YwP5BZ4.png" style="width:200px"/>
> - 由於文本域預設可以拖曳, 有時會有點困擾
> - 取消文本域拖曳 `<textarea style="resize: none;"></textarea>`
### Vertical-align: 垂直對齊
> - 複習對齊
```html
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
border: 1px solid gray;
margin: 0 auto; /* 盒子水平居中 */
text-align: center; /* 文字水平居中 */
line-height: 100px; /* 文字垂直居中
* line-height=height 運用的是文字預設中線對其的效果*/
}
</style>
</head>
<body>
<div>刷一排漢堡</div>
</body>
}
```
> - 垂直對齊種類: top(藍) | middle(黃) | baseline(紅) | bottom(灰)

>
> - Vertical-align 只對inline 或 inline-block 起效果
> - 文字和圖片默認基線(baseline)對齊
> <img src="https://i.imgur.com/K5I16VB.png" style="width:200px"/> -> <img src="https://i.imgur.com/iqd3fkB.png" style="width:200px"/>
>
> <img src="https://i.imgur.com/euZbSGA.png" style="width:200px"/> -> <img src="https://i.imgur.com/8hK3ekf.png" style="width:200px"/>
> 防Bug行
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
img { /* inline-block */
/* vertical-align: baseline; 默認基線對齊 */
vertical-align: middle;
}
textarea {
vertical-align: middle;
}
</style>
</head>
<body>
<img src="raccoon.jpeg"/>Raccoon
<hr />
文字域: <textarea></textarea>
</body>
```
### 去除圖片下面空白縫隙
> - 由於行內塊元素的底線會和父級盒子的baseline對齊,
> - 舊版本的瀏覽器有時候下面會有一層底線
> <img src="https://i.imgur.com/AAmbPWY.png" style="width:100px;" />
> 防Bug
```htmlembedded=
<head>
<meta charset="utf-8">
<style>
div {
width: 225px;
height: 225px;
background: blue;
}
img {
width: 225px;
height: 225px;
}
</style>
</head>
<body>
<div>
<img src="raccoon.jpeg"/>
</div>
</body>
```
> - 解決辦法:
> - `img {display: block;}`
> - `img {vertical-align: top | middle;}` (常用)
### 盒子垂直居中
<img src="https://i.imgur.com/KftmbO7.png" style="width: 100px;"/> -> <img src="https://i.imgur.com/0tQXxEF.png" style="width: 100px;"/>
- 第一種
```css
.father {
position: relative;
}
.son {
position: absoulute;
top: 50%;
transform: translateY(-50%);
}
```
- 第二種 margin-top
- 第三種 vertical-align
- 前提: 父盒子必需轉為`display:table-cell`
- `table-cell`: 表格單元格, 類似於\<td>
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
.one {
height: 200px;
width: 200px;
border: 1px solid skyblue;
display: table-cell; /* 類似於<td> */
vertical-align: middle;
}
.two {
height: 100px;
width: 100px;
border: 1px solid blue;
}
</style>
</head>
<body>
<div class="one">
<div class="two"></div>
</div>
</body>
```
### 盒子水平居中
- 第一種 `margin: 0 auto;`
- 第二種 `margin-left`
- 第三種
```css
.father {
position: relative;
}
.son {
position: absoulute;
left: 50%;
transform: translateX(-50%);
}
```
- 第四種
- 子元素轉成`display: inline-block`
- 父元素`text-align: center`
- `text-align` : 文本水平居中的設定
```css
.father {
text-align: center;
}
.son {
display: inline-block;
}
```
### 垂置居中 fixed + margin
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
div {
background: red;
opacity: 0.5;
position: fixed;
width: 100px;
height: 100px;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
</style>
</head>
<body>
<div></div>
</body>
```
## 文字溢出
<img src="https://i.imgur.com/Hqvi6iR.png" style="width:100px;" />
### word-break
> 用於處理英文, 因為中文本來就拆不了
> - `word-break: normal;`: 就沒變
> - `word-break: break-all;` : 允許英文字拆開
> <img src="https://i.imgur.com/UUCQqZL.png" style="width:100px;" />
> - `word-break: keep-all;` : 只允許連字符或空格處換行, 其實也就是沒變
> <img src="https://i.imgur.com/bLZHtSQ.png" style="width:100px;" />
### white-space
> - `white-space: normal;`
> - `white-space: nowrap;`: 強制在同一行顯示, 除非遇到 <br/>
> <img src="https://i.imgur.com/vAyOGGz.png" style="width:150px;" />
>
### text-overflow
> - 使用前提:
> - 必須強制顯示一行 `white-space: nowrap;`
> <img src="https://i.imgur.com/vAyOGGz.png" style="width:150px;" />
>
> - 必須搭配`overflow` 使用
> <img src="https://i.imgur.com/9sjTHhM.png" style="width:100px;" />
> - `text-overflow: clip;`: 直接裁減,其實就是上圖,沒變
> - `text-overflow: ellipsis;` : 裁減的部分用(...)代替
> <img src="https://i.imgur.com/OgnRLRc.png" style="width:100px;" />
### 顯示多行的隱藏(webkit的css擴展屬性)
> 上面是顯示單行的隱藏方法, 以下則是顯示單行的隱藏方法( 限定 webkit )
<img src="https://i.imgur.com/xfEJXTp.png" style="width: 200px;"/> -> <img src="https://i.imgur.com/c64eH51.png" style="width: 200px;"/>
> - 使用前提: `display: box`
> 1. `-webkit-box-orient: vertical;`: 設定盒子的排列方式
> 2. `-webkit-line-clamp: <num>`: 顯示行數
> 3. `overflow: hidden`: 把超出盒子的隱藏
> 4. `text-overflow: ellipsis`: 隱藏的部分用...的效果
### 自己自製隱藏
<img src="https://i.imgur.com/384EDvm.png" style="width:300px;" /> -> <img src="https://i.imgur.com/NEzg7cn.png" style="width:200px;" /> -> <img src="https://i.imgur.com/Jhs6tJ5.png" style="width:100px;" />
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
p {
/* 先將 p 設需要的寬高 */
height: 30px;
line-height: 2em;
border: 1px solid skyblue; /* 輔助用, 在線外面都是要隱藏的 */
position: relative;
overflow: hidden;
}
p::after {
content: "...";
position: absolute;
right: 0;
top: 0;
padding: 0 45px 0 0;
}
</style>
</head>
<body>
<p>Evolving from single-celled yellow organisms at the dawn of time, Minions live to serve, but find themselves working for a continual series of unsuccessful masters, from T. Rex to Napoleon. Without a master to grovel for, the Minions fall into a deep depression. But one minion, Kevin, has a plan; accompanied by his pals Stuart and Bob, Kevin sets forth to find a new evil boss for his brethren to follow. Their search leads them to Scarlet Overkill, the world's first-ever super-villainess.Evolving from single-celled</p>
</body>
```
## CSS Sprite
### 使用背景
> - 網頁每張圖片都需要跟服務器請求一次
> - 當網頁圖片過多時,服務器的壓力就會過大
### Sprite原理
> - 把多張==背景圖片==集中到一張大圖,此時只需要請求一次
### 使用方法
> - 運用`background-position`調整到想要使用圖的座標
### 小技巧
> - PhotoShop 查看XY與寬高
> <img src="https://i.imgur.com/BhJy4xE.png" style="width:100px;" /> -> <img src="https://i.imgur.com/GzV41oD.png" style="width:200px;" /> -> <img src="https://i.imgur.com/np68lhu.png" style="width:100px;" />
### 資源
> https://www.spriters-resource.com/
### 實作: FaceBookLogo

> - 這裡有一張圖, 如果我想要使用橘色FaceBookLogo
> - 首先先測量裝圖的盒子大小(Logo大小): 72*72px
> - 接著測量Logo所在位置的左上角XY值: (80, 234)
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div { /* 先創建一個裝圖的盒子 */
width: 72px;
height: 72px;
/* 把圖丟進去 */
background: url(sprite.png) no-repeat;
/* 移到位置上
* 圖在(80,234),
* 故應該把圖向左移80,向上移234
* 由於CSS的Y軸向下是正的, 故Y向上移應該是負數*/
background-position: -80px -234px; /* 此時得到一個FBLogo盒子 */
margin: 100px auto; /* 這盒子就可以隨便亂動了 */
}
</style>
</head>
<body>
<div></div>
</body>
```
### 實作: RACCOON

```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 20px;
height: 20px;
background: url(AtoZ.jpg) no-repeat;
float: left;
}
nav {
margin: 200px;
}
.R {
background-position: -52px -218px;
}
.A {
background-position: -29px -186px;
}
.C {
background-position: -76px -186px;
}
.O {
background-position: -364px -186px;
}
.N {
background-position: -342px -186px;
}
</style>
</head>
<body>
<nav>
<div class="R"></div>
<div class="A"></div>
<div class="C"></div>
<div class="C"></div>
<div class="O"></div>
<div class="O"></div>
<div class="N"></div>
</nav>
</body>
```
## 字體圖標 (iconfont)
> - 圖片的缺點:
> - 體積大
> - 請求多
> - 縮放失真
> - 字體圖標: 雖然表面上是圖, 實際上是字型
> - 可以做跟圖片一樣的事
> - 可以做字型在做的事,如改顏色、陰影..
> - 體積小
> ### 另外使用方法,
> - 直接引入對方的圖庫 `<link style=>`
> - 給要使用的標籤設他圖庫給的類名 `<i class='xxx'>`
> - https://www.oxxostudio.tw/articles/201406/css-icon-font.html
> - https://fontawesome.com/
### 使用方法
> - 設計效果圖(svg)
> - UI人員使用illustrator或sketch設計
> - 輸出成svg檔
> - 上傳轉換
> - 將svg檔轉成網頁能使用的字體文件
> - [IcoMoon](https://icomoon.io/),[阿里媽媽](https://www.iconfont.cn/),[fontello](http://fontello.com/),[FontAwesome](https://fontawesome.com/),[GlyphiconHalflings](https://glyphicons.com/),[Icons8](https://icons8.com/)...等
> - 下載到本地(以IcoMoon)為例
> - 到官網後點選右上角的IcoMoon APP
> <img src="https://i.imgur.com/ouxauL9.png" style="width:100px"/>
> - 上傳自己的或選取內建的
> - 選完後按GenerateFont來生成
> <img src="https://i.imgur.com/2MGRoC5.png" style="width:500px"/>
> - 確認沒問題後Download
> <img src="https://i.imgur.com/oxfTZFR.png" style="width:300px"/>
> - 旁邊的設定鍵可以設定一些東西,例如圖標支援IE6
> - 將字體引用至頁面
> - 下載後解壓,有一個fonts資料夾,將他複製到Project資料夾中
> <img src="https://i.imgur.com/8qbraqB.png" style="width:200px"/>
### 轉檔工具
> - [FontSquirrel](https://www.fontsquirrel.com/tools/webfont-generator)
> ```
> text/
> ├── fonts
> │ ├── icomoon.eot
> │ ├── icomoon.svg
> │ ├── icomoon.ttf
> │ └── icomoon.woff
> ├── images
> └── web
> └── index.html
> └── style.css
> ```
> - 此時就可以使用了,接下來需聲明字體
```css
@font-face { /* 聲明字體, 內容除了font-family以外都不要改 */
font-family: 'icomoon'; /* font-family 定義名稱可以隨便取 */
src: url('fonts/icomoon.eot?7kkyc2');
src: url('fonts/icomoon.eot?7kkyc2#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?7kkyc2') format('truetype'),
url('fonts/icomoon.woff?7kkyc2') format('woff'),
url('fonts/icomoon.svg?7kkyc2#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
```
> - 讓盒子使用字體
```css
span {
font-family: "icomoon" /* 必須跟聲明的變量名一樣 */
}
```
> 此時span以可以使用該字體,接著只要在html輸入該字體即可
> - 回到剛剛下載網頁,如果關掉了就打開剛剛解壓的資料夾有個demo.html
> - <img src="https://i.imgur.com/AyDisHe.png" style="width:200px"/>
> - 每個圖標都有一個框框跟一串字符串
> - 複製框框
> - 複製那個框框到標籤中
```htmlmixed=
<body>
<span></span>
</body>
```
> - 手打字符串(前面要加一個"\\")
```htmlmixed=
<head>
<style>
div::before {
content: "\ea92"
}
</style>
</head>
<body>
<div></div>
</body>
```
> - <img src="https://i.imgur.com/BRVtEkq.png" style="width:50px"/>
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?7kkyc2');
src: url('fonts/icomoon.eot?7kkyc2#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?7kkyc2') format('truetype'),
url('fonts/icomoon.woff?7kkyc2') format('woff'),
url('fonts/icomoon.svg?7kkyc2#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
span::before {
content: "\ea91";
font-family: "icomoon";
}
div {
font-family: "icomoon";
font-size: 30px; /* 此時就可以使用font來玩了 */
color: darkblue;
}
</style>
</head>
<body>
<span></span>
<div></div>
</body>
```
> - 追加ICONFont
> - 打開IcoMoon > <img src="https://i.imgur.com/ouxauL9.png" style="width:100px"/> > <img src="https://i.imgur.com/MhNY77J.png" style="width:100px"/>
> - 選擇selection.json
> <img src="https://i.imgur.com/yD6NtQ5.png" style="width:200px"/>
> - 此時會看到剛剛載下來的那幾個,
> <img src="https://i.imgur.com/z142mmR.png" style="width:200px"/>
> - 接著把想要的也都選一選重新下載後把project的fonts換掉就好了
> - 故下載下來的檔案在更新之前都要留著,否則之後要添加就要整個code改一改了
## 滑動門

> - 常常會遇到一些難做的框框,例如上圖,
> - 通常這類都會使用背景圖來完成,惟字數都不一樣多是如何做到的呢?
> - CSS滑動門技術就是來解決這類問題
### 核心想法
> - 運用padding來撐開寬度,如此寬度就能依內容而定
> - 運用背景圖片位置來完成框框
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
a,
a span {
background: url(ao.png) no-repeat; /* a跟span都使用下面那張圖當背景 */
height: 33px; /* 輪廓整個高度為33px */
display: inline-block;
}
a {
padding-left: 15px; /* 不能把寬度寫死,所以使用padding來撐開
* 輪廓的寬差不多為15px*/
}
a span {
background-position: right; /* span需要的是右半邊的輪廓 */
padding-right: 15px;
}
</style>
</head>
<body>
<a href="#">
<span></span>
</a>
</body>
```
> - ao.png: 
> - <img src="https://i.imgur.com/iBqMg9d.png" style="width:150px"/>
> - 結果: <img src="https://i.imgur.com/IF7WiRY.png" style="width:80px"/>
> - 此時就完成了左右兩邊的輪廓,
> - 在span輸入字所撐開的寬之背景都是span背景剩下全黑的部分
> - 寬度也視內容而定,沒有內容就30px寬
> <img src="https://i.imgur.com/KpxZkLd.png" style="width:100px"/>
### 實作: 微信NAV
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}
body {
background: url(wx.jpg) repeat-x;
}
/* nav */
div {
width: 965px;
margin: 0 auto;
}
ul {
height: 75px;
float: right;
}
li {
float: left;
margin-top: 20px;
line-height: 33px;
}
a {
padding-left: 15px;
color: #fff;
text-decoration: none;
}
span {
padding-right: 15px;
}
.first,
.first span,
a:hover,
a:hover span {
display: inline-block;
height: 33px;
}
.first {
padding-left: 15px;
background: url(lTcb_ve.png) no-repeat;
}
.first span {
padding-right: 15px;
background: url(lTcb_ve.png) no-repeat;
background-position: right;
}
a:hover {
background: url(ao.png) no-repeat;
}
a:hover span{ /* 滑鼠經過a之後span也要換背景,因為a只有左邊15px那一塊*/
background: url(ao.png) no-repeat;
background-position: right;
}
</style>
</head>
<body>
<div class="clearfix">
<ul>
<li>
<a href="#" class="first">
<span>首頁</span>
</a>
</li>
<li>
<a href="#">
<span>幫助與反饋</span>
</a>
</li>
<li>
<a href="#">
<span>公眾平台</span>
</a>
</li>
<li>
<a href="#">
<span>開放平台</span>
</a>
</li>
<li>
<a href="#">
<span>微信支付</span>
</a>
</li>
<li>
<a href="#">
<span>微信網頁版</span>
</a>
</li>
<li>
<a href="#">
<span>表情開放平台</span>
</a>
</li>
<li>
<a href="#">
<span>微信廣告</span>
</a>
</li>
</ul>
</div>
</body>
```
## before & after
> - 偽元素: 因為他不是真正HTML的元素,而是CSS製作貌似頁面元素的效果
> - 默認`display: inline;`且必須要有==content==
### 實作: 滑鼠經過品項後添加編框
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 225px;
height: 225px;
margin: 300px auto;
position: relative;
}
div:hover::before { /* 滑鼠經過後在div前面添加偽元素 */
content: "";
width: 100%;
height: 100%;
display: block;
border: 10px solid rgba(0,0,0,0.2);
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<div>
<img src="raccoon.jpeg"/>
</div>
</body>
```
## 過渡(Transition, CSS3)
### 前情提要
<img src="https://i.imgur.com/fxGaz4C.png" style="height: 100px"/> -> <img src="https://i.imgur.com/MLBn6wN.png" style="height: 100px"/>
> - 當我使用hover讓滑鼠經過圖一(`width: 100px`)時變成圖二(`width: 200px`)
> ```css
> div:hover {
> width:200px;
> }
> ```
> - 此時他會瞬間轉換成200px
> - 過渡就是讓轉換有動畫效果: 一幀幀案順序速度播放
### 語法
`transition: property [ duration || timing-function || delay ];`
> - `transition-preperty`: 要過渡的CSS屬性名稱
> - `transition-preperty: all;`:全屬性都要變化過渡
> - `transition-duration`: 過渡花費的時間
> - 必須寫單位, s/ms
> - 預設: 0s
> - `transition-timing-function`: 時間曲線
> - 
> - 預設: ease
> - `transition-delay`: 延遲
> - 必須寫單位, s/ms
> - 預設: 0s
> - 如果有多組變化, 用==逗號==隔開
> - 不限於hover
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
border: 1px solid skyblue;
/*transition: width 0.5s ease 0s;*/
transition: width 0.5s,
height 0.5s 1s,
background 0.5s 1s;
}
div:hover {
width: 200px;
height: 200px;
background: darkblue;
}
</style>
</head>
<body>
<div></div>
</body>
```
## Transform(2D變形,CSS3)
> - 實現位移,旋轉,縮放,矩陣
### Translate(移動)
> - `transform: translate(x,y);`
> - `transform: translateX(x);`
> - `transform: translateY(y);`
> - XY可負值
> - 如果值是%,是以==自己==寬度去計算,與margin不同
> ```css
> div {
> width: 100px;
> height: 100px;
> transform: translateX(50%); /* 向右移動50px(100px*50%) */
> }
> ```
> - 佔位是佔移動前的位置
> <img src="https://i.imgur.com/MobT9He.png" style="width: 100px;"/> -> <img src="https://i.imgur.com/7C07lz7.png" style="width: 100px;"/>
> 前者為移動前, 後者為移動後, 移動後ds並沒有移動
### 移動: 置中
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
border: 1px solid skyblue;
position: absolute;
left: 50%;
top: 50%;
/* 以前的置中
margin-right: -50px;
margin-top: -50px;
缺點: 要自己算,如果盒子大小改了,這裡也要跟著改*/
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div></div>
</body>
```
### Scale(縮放)
> - `transform: scale(x,y);`
> - 只設一個值: X=val, y=val
> - `transform: scaleX(x);`
> - `transform: scaleY(y);`
> - scale預設值為1
> - 縮小: `scale(0.01~0.99)`
> - 放大: `scale(1.01)`以上
```htmlmixed=
<!-- 常見的縮放應用: 滑鼠移到圖片會緩慢放大, 離開後縮小 -->
<head>
<meta charset="utf-8">
<style>
div {
width: 225px;
height: 225px;
border: 1px solid skyblue;
margin: 300px auto;
overflow: hidden; /* 超出隱藏 */
}
img { /* 注意不是盒子在縮放, 是img! */
transition: transform 0.5s;
}
div:hover img{
transform: scale(1.25);
}
</style>
</head>
<body>
<div>
<img src="raccoon.jpeg"/>
</div>
</body>
```
> - 負數為反轉
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
div {
height: 200px;
width: 200px;
margin: 200px auto 0;
background: yellow;
transform: scale(1);
transition: 1s all ease;
}
div:hover {
transform: scale(-1, 1);
}
</style>
</head>
<body>
<div>123</div>
</body>
```
### Rotate(旋轉)
`transform: rotate(deg);`
> - 單位是deg(度)
> - 正值是順時針轉, 負值是逆時針轉
### Transform Origin 設定變形點
`transform-origin: x y;`
> - center | left | right | top | bottom
> - px
> - 預設是 `transform-origin: center center`
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
img {
margin: 300px 300px;
transition: transform 0.5s;
transform-origin: right bottom; /* 變形點改成右下 */
}
img:hover {
transform: rotate(180deg); /* 以右下為基點轉180 */
}
</style>
</head>
<body>
<img src="raccoon.jpeg"/>
</body>
```
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 180px;
height: 73px;
border: 1px solid skyblue;
margin: 300px auto;
position: relative;
}
img {
width: 100%;
height: 100%;
transition: all 0.3s;
position: absolute;
transform-origin: right bottom;
}
div:hover img:nth-child(1) {
transform: rotate(60deg);
}
div:hover img:nth-child(2) {
transform: rotate(120deg);
}
div:hover img:nth-child(3) {
transform: rotate(180deg);
}
div:hover img:nth-child(4) {
transform: rotate(240deg);
}
div:hover img:nth-child(5) {
transform: rotate(300deg);
}
div:hover img:nth-child(6) {
transform: rotate(360deg);
}
</style>
</head>
<body>
<div>
<img src="original.jpg"/>
<img src="original-1.jpg"/>
<img src="original-2.jpg"/>
<img src="original-3.jpg"/>
<img src="original-4.jpg"/>
<img src="original-5.jpg"/>
</div>
</body>
```
### Skew(傾斜)
> - `transform: skew(xdeg,ydeg);`
> - `transform: skewX(xdeg);`
> - `transform: skewY(ydeg);`
### 多個 transform 變換
`transform: xx1() xx2() ...`
> - 多個 transform 一起執行時, 執行順序是從後面執行到前面(xx2->xx1)
> - 其實code是從前往後的, 是矩陣乘法的關係
> 任何一個圖形操作, 其實都是矩陣操作,
> 如果我同時執行 5 個圖形操作, 其實是做[矩陣乘法](https://zh.wikipedia.org/wiki/%E7%9F%A9%E9%99%A3%E4%B9%98%E6%B3%95)
> 而矩陣乘法最終結果看起來就是反過來的
> - 先執行誰當然就會影響最終圖形的成果
> - 正方形先拉長後旋轉
> <img src='https://i.imgur.com/wPJTzMG.png' style='width: 200px'/>
> - 正方形先旋轉後拉長
> <img src='https://i.imgur.com/OHJcOaU.png' style='width: 200px'/>
```css
div {
height: 100px;
width: 100px;
border: 1px solid black;
margin: 100px auto;
}
div:hover {
/* 先旋轉再拉長
transform: scale(2,1) rotate(45deg);*/
/* 先拉長再旋轉 */
transform: rotate(45deg) scale(2,1);
}
```
## 3D Transform (CSS3)
### 3D
> - 一般的3D方向
> 
> - CSS3的3D方向
> 
### Rotate(旋轉)
> - `transform: rotateX(xdeg);`: 繞X軸轉
> - `transform: rotateY(ydeg);`: 繞Y軸轉
> - `transform: rotateZ(zdeg);`: 繞Z軸轉
> - `transform: rotateX(xdeg) rotateZ(zdeg) rotateY(ydeg);`
> - 理解 XYZ 旋轉效果小技巧, 想像自己在+XYZ的末端看著軸, 順時鐘轉是正的
### Perspective(透視)
<img src="https://i.imgur.com/k0kfLBK.png" style="width: 300px"/> -> <img src="https://i.imgur.com/frm4FHS.png" style="width: 300px"/>
<img src="https://i.imgur.com/Pnahet2.png" style="height: 300px"/>-><img src="https://i.imgur.com/qMNpN9D.png" style="height: 300px"/>
> - 讓2D呈現3D效果
> - 原理: 近大遠小
> - 如果不寫的話, 透視預設就是無窮大
> 而透視給的越小, 3D 感覺越明顯,
> 反之則越不明顯, 所以不加看起來當然就沒有3D效果
> - 下面透視圖的兩個原點就是透視點([滅點](https://zh.wikipedia.org/wiki/%E6%B6%88%E5%A4%B1%E7%82%B9)), 兩點越近越立體
> <img src='https://i.imgur.com/XeJ38zH.jpg' style='width: 200px'/>
> - `perspective: px`: 設置視點距離
> `transform: perspective(px)`: 另一種寫法
> 常用 300 700 1200
> - perspective要設置在父元素,轉換其子元素的3D效果
### TranslateZ
`transform: translateZ(z)`
> - translateX跟translateY是平面的上下左右移動
> - translateZ即前後移動,正值向前,負值向後
> - z 不能寫%數, 只能寫值

> - perspective就是模擬眼睛到螢幕的距離(d)
> - translateZ就是模擬盒子的高度(z)
> - 亦即perspective = translateZ時,表示物體整個塞在你的眼睛前面,故呈現盒子的表面內容佔滿版
### Translate3D
`transform: translate3d(x,y,z)`
> - 就是把translate寫在一起的東西
> - x,y跟上面一樣, 可寫%或值
> - z只能寫值
### 實作: 開門
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
.Door {
width: 225px;
height: 225px;
margin: 300px auto;
border: 1px solid skyblue;
position: relative;
perspective: 500px;
}
/* 門 */
.leftDoor,
.rightDoor {
width: 112.5px;
height: 225px;
background: orange;
position: absolute;
transition: all .5s;
}
.leftDoor {
transform-origin: left;
}
.rightDoor {
right: 0;
background: red;
transform-origin: right;
}
/* 門把 */
.leftDoor::before,
.rightDoor::before {
content: "";
position: absolute;
top: 50%;
width: 10px;
height: 10px;
border: 1px solid black;
border-radius: 50%;
transform: translateY(50%);
}
.leftDoor::before {
right: 10px;
}
.rightDoor::before {
left: 10px;
}
/* 動 */
.Door:hover .leftDoor {
transform: rotateY(-135deg);
}
.Door:hover .rightDoor {
transform: rotateY(135deg);
}
</style>
</head>
<body>
<div class="Door">
<div class="leftDoor"></div>
<div class="rightDoor"></div>
</div>
</body>
```
### Backface-Visibility(背面顯示)
> - `backface-visibility: hidden;`
### 實作: 翻轉圖片
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
border: 1px solid skyblue;
margin: 300px auto;
position: relative;
perspective: 500px;
}
.front,
.behind {
width: 100%;
height: 100%;
margin: 0;
position: absolute;
transition: all .8s;
}
.front {
background: orange;
z-index: 1;
backface-visibility: hidden;
}
.behind {
background: red;
}
div:hover .front,
div:hover .behind {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div>
<div class="front"></div>
<div class="behind"></div>
</div>
</body>
```
## Transform-Style
`transform-style: flew | preserve-3d;`
> - 默認為 `flew`
> - 指定子元素看起來是二維還是三維
> - 當只有子元素設置旋轉時, 看起來是三維
> <img src="https://i.imgur.com/yAVxIVb.png" style="width: 100px;"/>
> - 惟當父元素也設置旋轉時, 子元素會跟著父元素跑, 子元素會變成二維視覺
> <img src="https://i.imgur.com/pCDEpQh.png" style="width: 100px;"/>
> - `preserve-3d`
> - 讓子元素可以脫離父級
> - 如有需要脫離, 該父級都必須寫
> - vs. `perspective`
> - 只是一種視覺效果
> - 一般只會加在最外層一次
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
body {
perspective: 500px;
}
.father {
width: 300px;
height: 300px;
border: 3px solid red;
margin: 300px auto;
transform: rotateY(0deg);
transform-style: preserve-3d; /* 設置前, 子元素會跟著父元素轉 */
}
.son {
border: 3px solid blue;
height: 100%;
width: 100%;
transform: rotateY(60deg);
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
```
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
.f {
height: 100px;
width: 100px;
border: 1px solid black;
margin: 200px auto;
transition: 1s all ease;
transform: perspective(700px) rotateX(45deg) rotateZ(45deg);
/* 這個只解除 .s 的 3d 限制 */
transform-style: preserve-3d;
}
.s {
height: 100%;
width: 100%;
background: skyblue;
/* 這個解除了 .s2 的 3d 限制 */
transform-style: preserve-3d;
}
.s:hover {
transform: translateZ(30px);
}
.s2 {
height: 70%;
width: 100%;
background: green;
transform: translateZ(0);
}
.s2:hover {
transform: translateZ(30px);
}
</style>
</head>
<body>
<div class='f'>
<div class='s'>
<div class='s2'></div>
</div>
</div>
</body>
```
### 實作: 正方體
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
.main {
height: 200px;
width: 200px;
margin: 300px auto;
background: gray;
position: relative;
transition: 3s all ease;
transform: perspective(700px) rotateX(30deg) rotateY(30deg);
transform-style: preserve-3d;
}
.main:active {
transform: perspective(700px) rotateX(360deg) rotateY(360deg);
}
.main div {
position: absolute;
top: 0;
right: 0;
border: 1px solid black;
height: 100%;
width: 100%;
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.botton {
transform: rotateX(-90deg) translateZ(100px);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.front {
transform: translateZ(100px);
}
.back {
transform: translateZ(-100px);
}
</style>
</head>
<body>
<div class='main'>
<div class='top'>上</div>
<div class='botton'>下</div>
<div class='left'>左</div>
<div class='right'>右</div>
<div class='front'>前</div>
<div class='back'>後</div>
</div>
</body>
```
### 實作: 翻轉副克牌
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
.main {
height: 200px;
width: 150px;
background: blue;
margin: 300px auto 0;
transform: perspective(300px) rotateY(0);
transition: 1s all ease;
position: relative;
transform-style: preserve-3d; /* 解放子元素的 translateZ */
}
.main:hover {
transform: perspective(300px) rotateY(180deg);
}
.main div {
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.front {
background: red;
transform: translateZ(10px);
}
.back {
background: green;
transform: translateZ(-10px) scaleX(-1);
}
</style>
</head>
<body>
<div class='main'>
<div class='front'>紅心A</div>
<div class='back'>紅心A</div>
</div>
</body>
```
### 實作: 超酷炫旋轉

> - 想法: 滑鼠放上淺藍色盒子時, 全部旋轉
> - 邏輯:
> - 由於是立體的, 中間盒子與外圍盒子要有距離(translateZ), (prespective)
> - 每個盒子都水平繞著中間盒子的感覺, Y軸旋轉
> - 要讓子盒子有3D感(transform-style: preserce-3d)
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
body {
perspective: 1000px;
}
nav {
width: 100px;
height: 100px;
background: skyblue;
margin: 300px auto;
position: relative;
transition: all 5s;
transform-style: preserve-3d;
}
nav:hover {
transform: rotateY(360deg);
}
div {
width: 100%;
height: 100%;
background: darkblue;
position: absolute;
top: 0;
left: 0;
}
div:nth-child(1) {
transform: rotateY(0deg) translateZ(400px);
}
div:nth-child(2) {
transform: rotateY(60deg) translateZ(400px);
}
div:nth-child(3) {
transform: rotateY(120deg) translateZ(400px);
}
div:nth-child(4) {
transform: rotateY(180deg) translateZ(400px);
}
div:nth-child(5) {
transform: rotateY(240deg) translateZ(400px);
}
div:nth-child(6) {
transform: rotateY(300deg) translateZ(400px);
}
</style>
</head>
<body>
<nav>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</nav>
</body>
```
### 實作: 翻書
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
.book {
width: 200px;
height: 100px;
position: relative;
margin: 200px auto 0;
/* 讓書本倒下來 */
transform: perspective(300px) rotateX(30deg);
transform-style: preserve-3d;
}
.book .page {
position: absolute;
top: 0;
width: 98px; /* 200/2-2(邊框) */
height: 98px; /* 100-2(邊框) */
border: 1px solid black;
}
/* 左邊頁 */
.book .page1 {
left: 0;
}
/* 右邊頁 */
.book .page4 {
right: 0;
}
/* 翻書頁 */
.book .page23 {
left: 50%;
position: relative;
transform-style: preserve-3d;
transition: 1s all ease;
transform-origin: left; /* 旋轉的軸線 */
}
/* 翻書 */
.book .page23:active {
transform: rotateY(-180deg);
}
.book .page2,
.book .page3 {
height: 100%;
width: 100%;
position: absolute;
}
.book .page2 {
transform: translateZ(1px);
background: red;
}
.book .page3 {
transform: translateZ(-1px) scaleX(-1);
background: green;
}
</style>
</head>
<body>
<div class='book'>
<div class='page page1'>123</div>
<div class='page page23'>
<div class='page2'>456</div>
<div class='page3'>789</div>
</div>
<div class='page page4'>10</div>
</div>
</body>
```
### 其他
> - transform-3d 很難做非常複雜的東西
> - Q. 如何製作更複雜的幾何?
> - 必須依靠 JS 的 webGL, 這東西可以做出非常非常複雜的 3D 模型, 只是我不會
## Animation(動畫)
### @keyframes 定義動畫
> `@keyframes animationname { keyframes-selector { css-styles;}}`
> - `animationname`: 必須, 動畫名稱
> - `keyframes-selector`: 必須, 動畫時長百分比
> - 0~100%
> ```css
> @keyframes test {
> 0%{top: 10px} /* 時間一開始時在哪裡 */
> 10%{top: 15px} /* 時間走到10%時在哪裡 */
> 100%{top: 300px} /* 時間走到底時在哪裡 */
> }
> ```
> - from {} to {}
> ```css
> @keyframes test2 {
> from { /* 相當於0% */
> transform: translateX(10px);
> }
> to { /* 相當於100% */
> transform: translateX(300px);
> }
> }
> ```
> - `css-styles`: 必須, 動畫效果
### 執行動畫
`animation: name, duration, timimg-function[, delay,iteration-count, direction];`
> - `animation-name:`
> - `keyframesname;`: @keyframe定義的名字
> - `none;`: 無動畫效果, 用來取消的
> - `animation-duration: time(s/ms)`: 持續時間, 默認0
> - `animation-timimg-function:`: 時間曲線
> - `ease`: 低速起, 加速, 低速尾 (默認)
> - `ease-in`: 低速起
> - `ease-out`: 低速尾
> - `ease-in-out`: 低速起尾
> - `linear`: 勻速
> - `cubic-bezier(n,n,n,n)`: 自定義yframes
> - `animation-fill-mode`: 停在什麼位置上
> - `backwards`: 回到初始
> - `both`: 是次數而定, 第一次在起點, 第二次在終點
> - `forwards` : 保持在終點狀態
> - `none`
>
> - `animation-delay: time(s/ms);`: 延遲時間, 默認0
> - `animation-iteration-count`: 播放次數
> - `n`: 次數
> - `infinite`: 無限
> - `animation-direction`: 方向
> - `normal`: 正常播放(默認)
> - `alternate`: 輪流反向
> - `animation-fill-mode`
> - `animation-play-state`: 滑鼠經過時的動畫狀態
> - `paused`: 暫停
> - `running`: 持續
> - `animation-play-state` : 動畫的狀態
> - `paused`
> - `running`
```htmlmixed=
<head>
<meta charset='utf-8'>
<style>
@keyframes test {
0%{height: 100px; width: 100px; background: blue; color: red;}
25%{height: 200px; width: 100px; background: blue; color: red;}
50%{height: 200px; width: 200px; background: blue; color: red;}
75%{height: 200px; width: 200px; background: black; color: red;}
100%{height: 200px; width: 200px; background: black; color: white;}
}
div {
height: 100px;
width: 100px;
background: skyblue;
/*transition: 1s all ease;*/
transition: 1s width ease, 3s background ease;
animation-name: test;
animation-duration: 2s;
animation-timing-function: ease;
animation-fill-mode: forwards;
/*animation-delay: 2s;*/
animation-iteration-count: infinite;
animation-direction: alternate;
}
div:hover {
animation-name: null;
/*animation-play-state: paused;*/
}
</style>
</head>
<body>
<div>123</div>
</body>
```
### 實作: 移動的浣熊
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
border: 1px solid skyblue;
position: relative;
/*animation: test 2s ease-in 0s infinite alternate;*/
animation: test 5s infinite;
}
img {
position: absolute;
}
/*
@keyframes test {
form {
transform: translateX(30px);
}
to {
transform: translateX(100px);
}
}*/
@keyframes test {
0% {
transform: translate3d(0,0,0);
}
49% {
transform: translate3d(800px, 0, 0);
}
50% {
/* 相同屬性不同值,用空格隔開就好 */
transform: translate3d(800px, 0, 0) rotateY(180deg);
}
99% {
transform: translate3d(0, 0, 0) rotateY(180deg);
}
100% {
transform: rotateY(-180deg);
}
}
</style>
</head>
<body>
<div>
<img src="raccoon.jpeg"/>
</div>
</body>
```
### 實作: KKBOX
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
div {
width: 1800px;
height: 365px;
border: 1px solid skyblue;
overflow: hidden;
}
ul {
width: 9000px; /* 圖給兩次, 所以總寬要兩倍 900*5*2 */
animation: moving 10s linear;
animation-iteration-count: infinite;
}
li {
float: left;
}
div:hover ul{ /* 滑鼠經過盒子時, 動畫暫停
* kkbox沒有設這個屬性 我測試用 */
animation-play-state: paused;
}
@keyframes moving {
0% { /* 100%-0% 要剛好是一圈的寬度,這樣才能無縫接上 */
transform: translate3d(-725px, 0, 0);
}
20% {
transform: translate3d(-1625px, 0, 0);
}
22% {
transform: translate3d(-1625px, 0, 0);
}
40% {
transform: translate3d(-2525px, 0, 0);
}
42% {
transform: translate3d(-2525px, 0, 0);
}
60% {
transform: translate3d(-3425px, 0, 0);
}
62% {
transform: translate3d(-3425px, 0, 0);
}
80% {
transform: translate3d(-4325px, 0, 0);
}
82% {
transform: translate3d(-4325px, 0, 0);
}
98% {
transform: translate3d(-5225px, 0, 0);
}
100% {
transform: translate3d(-5225px, 0, 0);
}
}
</style>
</head>
<body>
<div>
<ul>
<li>
<img src="kkbox.jpg"/>
</li>
<li>
<img src="kkbox-1.jpg"/>
</li>
<li>
<img src="kkbox-2.jpg"/>
</li>
<li>
<img src="kkbox-3.jpg"/>
</li>
<li>
<img src="kkbox-4.jpg"/>
</li>
<!-- 跑最後一張圖後,跑下一圈前,中間會產生空白
故需要一些圖來補後面的空白,所以圖給兩次 -->
<li>
<img src="kkbox.jpg"/>
</li>
<li>
<img src="kkbox-1.jpg"/>
</li>
<li>
<img src="kkbox-2.jpg"/>
</li>
<li>
<img src="kkbox-3.jpg"/>
</li>
<li>
<img src="kkbox-4.jpg"/>
</li>
</ul>
</div>
</body>
```
## Flex
### 舊版佈局
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
nav {
width: 80%;
height: 300px;
border: 1px solid skyblue;
margin: 300px auto;
}
div {
height: 100%;
width: 33.3%;
float: left;
}
div:nth-child(1) {
background: blue;
}
div:nth-child(2) {
background: green;
}
div:nth-child(3) {
background: red;
}
</style>
</head>
<body>
<nav>
<div></div>
<div></div>
<div></div>
</nav>
</body>
```
> - 缺點:
> - 要計算,否則很容易超過寬度而掉下來,很麻煩
> <img src="https://i.imgur.com/YdO8Wl7.png" style="width: 200px;"/> -> <img src="https://i.imgur.com/8oHBadS.png" style="width: 200px;"/>
> - 要給的屬性多(至少要給寬高, 要讓block元素在一行還要float)
### flex
> - 將盒子分等份,等比縮放(響應式)
> - 不一定要指定flex屬性,也可以混搭
> - `min-width: px`: 使用響應式網站時,避免嚴重縮放造成變形, 可以設置盒子最小寬
> - `max-width: px`: 最大寬
> - `flex` 是一個簡寫屬性: 包含 `flex-grow` `flex-shrink` `flex-basis`
> - 雙值的首值必須是 `flex-grow`
> - `flex` 裡的 `float` `clear` `vertical-align` 不起作用
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
nav {
width: 80%;
height: 300px;
border: 1px solid skyblue;
margin: 300px auto;
display: flex;
min-width: 700px;
}
div {
/* 舊版排版
float: left;
margin: 0 2px;
width: 33.3%;
height: 100%;*/
/* flex啥都不用給, 給等分就行了 */
/* 所有div都拿到一等分
flex: 1;
margin: 0 2px;*/
}
div:nth-child(1) {
background: blue;
/*flex: 1;*/
width: 300px; /*混搭也沒問題 */
}
div:nth-child(2) {
background: green;
flex: 2;
margin: 0 2px; /* 不會掉下來 */
}
div:nth-child(3) {
background: red;
flex: 3; /* 總共六等分, 紅色拿一半*/
}
</style>
</head>
<body>
<nav>
<div></div>
<div></div>
<div></div>
</nav>
</body>
```
### flex-grow & flex-shrink
> - `flex-grow` 是把剩餘空間加權分配給各個子元素
> - 例如剩餘空間 120, 子元素有兩個, 分別設 `flex-grow: 1;` `flex-grow: 2;`
> - 那麼剩餘空間分配就是 120 / 3 * 1 跟 120 / 3 * 2
> <img src='https://i.imgur.com/3zRAjet.png' style='width: 100px;'/>
```htmlmixed=
<head>
<meta charset="utf-8">
<title></title>
<style>
.fa {
height: 300px;
width: 420px;
display: flex;
}
.son1 {
background: blue;
width: 100px;
flex-grow: 1; /* 拉伸 120 / 3 * 1 */
}
.son2 {
width: 100px;
background: yellow;
flex-grow: 2; /* 拉伸 120 / 3 * 2 */
}
</style>
</head>
<body>
<div class='fa'>
<div class='son1'></div>
<div class='son2'></div>
</div>
</body>
```
> - `flex-shrink` 則是把多餘空間按比例縮減
> - 例如超出120px, 兩個盒子分別設 `flex-shrink: 1;` `flex-shrink: 2;`
> 則多餘空間就按比例縮減 120 / 3 * 1 跟 120 / 3 * 2
> <img src='https://i.imgur.com/SbU3th4.png' style='width: 100px;'/>
```htmlmixed=
<head>
<meta charset="utf-8">
<title></title>
<style>
.fa {
height: 300px;
width: 300px;
display: flex;
}
.son1 {
background: blue;
width: 210px;
flex-shrink: 1; /* 縮減 120 / 3 * 1 = 40 */
}
.son2 {
width: 210px;
background: yellow;
flex-shrink: 2; /* 縮減 120 / 3 * 2 = 40 */
}
</style>
</head>
<body>
<div class='fa'>
<div class='son1'></div>
<div class='son2'></div>
</div>
</body>
```
> - 如果你有一個東西不想被縮,那就可以設置 `flex-shrink: 0` ,這樣就只會縮其他人
```html
<body>
<style type="text/css">
.fa {
max-width: 300px;
display: flex;
}
.son1 {
width: 400px;
height: 300px;
background: blue;
}
.son2 {
background: red;
flex-shrink: 0;
}
</style>
<div class="fa">
<div class="son1"></div>
<div class="son2">a b c d</div>
</div>
</body>
```
### flex-basis
> - `flex-basis` 跟 `width` 與 `flex-direction: column` 的 `height` 相衝突,
> 以 `flex-basis` 為主
```htmlmixed=
<head>
<meta charset="utf-8">
<title></title>
<style>
.fa {
height: 300px;
width: 300px;
display: flex;
}
.son1 {
background: blue;
width: 100px;
flex-basis: 200px;
}
.son2 {
background: yellow;
flex-grow: 1;
}
</style>
</head>
<body>
<div class='fa'>
<div class='son1'></div>
<div class='son2'></div>
</div>
</body>
```
### flex-direction
> - 設定方向
> - `flex-direction: row`: 行對齊(預設)
> 
> - `flex-direction: row-reverse;`: 水平, 順序相反
> 
> - `flex-direction: column`: 列對齊
> 
> - `flex-direction: column-reverse;`: 列對齊, 順序相反
> 
> #### 另外一種說法(Amos):
> - 資料流向(主軸): 就是資料怎麼排的, 預設由上至下, 由左至右
> - 交叉軸(次軸): 跟資料流向垂直
> - 如果資料流向是由上至下, 那交叉軸就是由左至右
> - 反之亦同
> - flex-direction: 設定資料流向
> - `flex-direction: row`: 由左至右(預設)
> - `flex-direction: row-reverse;`: 由右至左
> - `flex-direction: column`: 由上而下
> - `flex-direction: column-reverse;`: 由下而上
### 實作
<img src="https://i.imgur.com/Zi7BMrh.png" style="width:500px"/>
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
body{
min-width: 320px;
max-width: 540px;
margin: 0 auto;
}
header {
height: 100px;
width: 100%;
background: gray;
}
nav {
padding: 5px;
}
.raw {
height: 90px;
width: 100%;
/*margin: 5px; 用margin會整個向右移動5px
因為100%+5px(左), 所以用nav的padding來包*/
display: flex;
border-radius: 5px;
margin-bottom: 5px;
}
.raw:nth-child(1) {
background: #FF8384;
}
.raw:nth-child(2) {
background: #3A9FFF;
}
.raw:nth-child(3) {
background: #42B820;
}
.raw:nth-child(4) {
background: #FFA319;
}
.raw-in {
flex: 1;
border-left: 1px solid #fff;
}
.raw-in:first-child {
border: 0;
}
.column {
display: flex;
flex-direction: column;
}
.column a{
flex: 1;
text-align: center;
color: #fff;
line-height: 45px;
text-decoration : none;
font-size: 16px;
}
.column a:first-child {
border-bottom: 1px solid #fff;
}
.icon {
display: column;
}
.icon span {
flex: 1;
line-height: 45px;
text-align: center;
color: #fff;
text-decoration: none;
display: block;
}
.icon div {
flex: 1;
text-align: center;
height: 45px;
}
</style>
</head>
<body>
<header></header>
<nav>
<div class="raw">
<div class="raw-in icon">
<span>酒店</span>
<div>icon</div>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
</div>
<div class="raw">
<div class="raw-in icon">
<span>機票</span>
<div>icon</div>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
</div>
<div class="raw">
<div class="raw-in icon">
<span>旅遊</span>
<div>icon</div>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
</div>
<div class="raw">
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
<div class="raw-in column">
<a href="#">海外酒店</a>
<a href="#">特價酒店</a>
</div>
</div>
</nav>
</body>
```
### Justify-Content
`justify-content: flex-start | flex-end | center | space-between | space-around;`
> - 調整X軸的對齊方向
> - 沒有讓父元素被子元素佔滿時, 會有剩餘空間
> - 以下子元素`width: 30%;height: 100%;`
> - `justify-content: flex-start;`: 子元素的起始與父元素的起始對齊, 順序不變 (預設)
> 
>
> - `justify-contnet: flex-end;`: 子元素的結束與父元素的結束對齊, 順序不變
> 
>
> - `justify-content: center;`
> 
>
> - `justify-content: space-between;`:
> 
> 
> - 首個子元素的起始與父元素起始對齊,
> - 末個子元素的結束與父元素結束對齊
> - 剩餘子元素間分配剩餘空間
> - `space- between`: 剩餘空間分散在中間
>
> - `justify-content: space-around;`
> - 剩餘空間分散在兩邊
> - 相當於每個盒子添加相同margin
> 
### align-items
`align-items: flex-start | flex-end | center | stretch`
> - 調整Y軸對齊方向
> - 以下子元素 `width: 100%;`
> - `align-items: stretch`: 不給高度的前提下, 拉伸子元素的高度與父元素相同 (預設)
> 
>
> - `align-items: flex-start;`
> 
>
> - `align-items: flex-end;`
> 
>
> - `align-items: center;`
> 
```htmlmixed=
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 600px;
border: 1px solid red;
margin: 300px auto;
display: flex;
/* align-items: center;
* align-items: flex-start;
* align-items: flex-end;
*/
align-items: stretch; /* 預設 */
}
.son1,
.son2,
.son3 {
width: 100px;
}
.son1 {
background: blue;
}
.son2 {
background: green;
}
.son3 {
background: red;
}
</style>
</head>
<body>
<div class='father'>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
</div>
</div>
</body>
```
> #### Amos
> - align系列是設定次軸(交叉軸)的對齊
> - 如果主軸(資料流向)是由左至右,
> - 那麼次軸就是由上而下,
> - 上面是起點, 下面是終點
> - `align-items: flex-start;`: 對齊起點(上)
> - `align-items: flex-end;`: 對齊終點(下)
### flex-wrap
`flex-wrap: nowrap | wrap | wrap-reverse`
> - 控制超出時,是否換行
> - 以下子元素`height: 100%; width: 40%`
> - `flex-wrap: nonwrap`: 不換行,強制壓縮成一行 (默認)
> 
>
> - `flex-wrap: wrap`: 換行
> 
>
> - `flex-wrap: wrap-reverse`: 換行後翻轉
> 
### 解決問題: 使用float無法讓每列等高
#### float
> - 根據內容給高後, 內容不同就沒有等高

```htmlmixed=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
.clearfix:before,
.clearfix:after {
content: '';
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix { /* IE6,7 */
*zoom: 1;
}
.father {
width: 600px;
border: 1px solid red;
margin: 300px auto;
}
.son1,
.son2,
.son3 {
width: 200px;
float: left;
}
.son1 {
background: blue;
}
.son2 {
background: green;
}
.son3 {
background: red;
}
</style>
</head>
<body>
<div class='father clearfix'>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
</div>
</body>
</html>
```
> #### flex

```htmlmixed=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 600px;
border: 1px solid red;
margin: 300px auto;
display: flex;
flex-wrap: wrap;
}
.son1,
.son2,
.son3 {
width: 200px;
}
.son1 {
background: blue;
}
.son2 {
background: green;
}
.son3 {
background: red;
}
</style>
</head>
<body>
<div class='father'>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
不增不減。是故空中無色。無受想行識。
無眼耳鼻舌身意。無色身香味觸法。
無眼界。乃至無意識界。
無無明。亦無無明盡。乃至無老死。亦無老死盡。
</div>
</div>
</body>
</html>
```
### flex-flow
`flex-flow: <'flex-direction'> || <'flex-wrap'>`
> - flex-flow 是複合屬性
> - 預設: `flex-flow: row nowrap`
### align-content
`align-content: flex-start | flex-end | center | space-between | space-around | stretch`
> - 使用前提:
> - 父元素要設置flex `display: flex`
> - 排列方式要設置成row `flex-direction: row`
> - 換行 `flex-wrap: wrap`
> ```css
> E {
> display: flex;
> flex-flow: row nowrap;
> }
> ```
> - 以下子元素 `width: 40%;`
> - `align-content: flex-start`
> 
> - `align-content: flex-end`
> 
> - `align-content: center`
> 
> - `align-content: space-between`
> - 剩餘空間分散在中間
> 
> - `align-content: space-around`
> - 剩餘空間分散在兩邊
> 
> - `align-content: stretch`(預設)
> 
> - flex 的多行排列 vs. `align-items`單行排列
> - `align-items` 是設定單行交叉軸的對齊
> - `align-content` 是設定整體交叉軸的對齊
> - 兩個都預設 (兩個都是拉伸到最大)
> 
> - 如果我只有設 `align-items: center;`
> 
> - 如果我只有設 `align-content: center;`
> 
> - 如果我兩個都設 `center;`
> 
### align-self
> - 這東西其實就是拿來覆蓋父級的 align-items
> - 個別設置交叉軸的對齊

```htmlmixed=
<head>
<meta charset="utf-8">
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 600px;
height: 600px;
border: 1px solid red;
margin: 300px auto;
display: flex;
align-items: center; /* 預設全部都對其中間 */
}
.son1,
.son2,
.son3 {
width: 200px;
}
.son1 {
background: blue;
}
.son2 {
background: green;
align-self: flex-start; /* 第二個盒子對其flex-start*/
}
.son3 {
background: red;
}
</style>
</head>
<body>
<div class='father'>
<div class='son1'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
</div>
<div class='son2'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
</div>
<div class='son3'>
觀自在菩薩。行深波若波羅蜜多時。照見五蘊皆空。
度一切苦厄。舍利子。色不異空。空不異色。
色即是空。空即是色。受想行識。亦復如是。
舍利子。是諸法空相。不生不滅。不垢不淨。
</div>
</div>
</body>
```
### order
`order: <int>`
> - 使用CSS來調換盒子排序
> - int越小排會前面, 可以有負數, 預設皆為0
> - 使用場景:
> - 電腦畫面呈現想要123排序
> - 手機畫面呈現想要213排序
> - 平板畫面想要321排序
> - 此時不可能改 HTML 的內容, 因為三個排序都不一樣, 改誰另外兩個都倒霉
> - 此時就可以直接利用 order 來改排序
<img src="https://i.imgur.com/mTDvUM2.png" style="width: 300px;" /> -> <img src="https://i.imgur.com/qhTGlgf.png" style="width: 300px;" />
```css
div:nth-child(3) {
background: orange;
order: -1; /* 其他兩個都是0, 最後一個設為-1, 故橘色跑到第一個 */
}
```
## BFC(Block Formatting Context)
> - BFC是一個隔離的獨立容器
### 創建BFC的前提
> - 有寬有高有邊距有邊框的屬性
> 
> - display屬性中,`block | list-item | table` 會產生BFC
> - `list-item` 就是 \<ul> \<ol> \<dl> 所默認的屬性
> - `table` 就是 \<table> 所默認的屬性
> - display的其他屬性, 如`inline` 會產生IFC
### 觸發BFC
> 以下其中之一都會觸發
> - `html` 根元素
> - `float: [^none]`: Float不要是None
> - `position: absolute | fixed;`
> - `display: inline-block | table-cell | table-caption | flex | inline-flex ;`
> - `overflow: [^visibility];` overflow不為visibility
> - 如果只是要觸發BFC,那 `overflow: hidden;` 較為常用,因為比較沒有副作用
### BFC特性
> 1. 盒子從頂端排列下來
> 2. 盒子垂直距離由 Margin 決定, 同個BFC間垂直 margin 會互吃
> 3. 盒子 margin-left 會碰觸到容器的 border-left
> 4. BFC區域不與浮動盒子產生交集,而是緊貼邊緣
> 5. BFC高度時會包括浮動或定位盒子的高度
### BFC應用
> - 清除浮動
> - 子元素浮動時, 如果父元素沒有設高,由於沒東西撐開父元素, 故父元素`height:0;`
> - 利用BFC第五個特性可以把沒有高度的容器撐開
>  -> 
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
.father {
border: 1px solid gray;
width: 100px;
/*overflow: hidden;*/
/*position: absolute;*/
/*display: inline-block;*/
float: left;
}
.son1, .son2 {
width: 30px;
height: 30px;
float: left;
}
.son1 {
background: skyblue;
}
.son2 {
background: darkblue;
}
</style>
</head>
<body>
<div class="father">
<div class="son1"></div>
<div class="son2"></div>
</div>
</body>
```
> - 外邊距合併問題
> - 相同BFC的垂直外邊距會合併
> - 那不同BFC就解決合併問題了
> <img src="https://i.imgur.com/stbGUzQ.png" style="width: 200px;" /> -> <img src="https://i.imgur.com/LC8yTdD.png" style="width: 200px;" />
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
.father {
border: 1px solid gray;
width: 100px;
}
.son1, .son2 {
width: 30px;
height: 30px;
}
.son1 {
background: skyblue;
margin-bottom: 5px;
overflow: hidden;
}
.son2 {
background: darkblue;
margin-top: 10px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="father">
<div class="over"> <!-- overflow隔開, 如此.son1與.son2
就是不同BFC而沒有合併問題 -->
<div class="son1"></div>
</div>
<div class="son2"></div>
</div>
</body>
```
> - 製作右側適應盒
> - 行動端常用, 因為每台手機都不同大小, 控制浮動盒子就能控制BFC
> - 下面這個盒子淺藍色給固定寬高, 深藍色沒給任何寬高, 讓文字撐開
> <img src="https://i.imgur.com/ImF0qLj.png" style="width: 200px;" />
> - 當淺藍色浮動時, 深藍色會往上跑, 並環繞淺藍色
> <img src="https://i.imgur.com/NKLUYks.png" style="width: 200px;" />
> - 而深藍色創造BFC後, 因為BFC不予浮動交集並緊貼的特性, 就換產生右側適應盒
> <img src="https://i.imgur.com/RB305t1.png" style="width: 200px;" />
> - 淺藍色的寬擴大或縮小, 都會影響深藍色的大小
> <img src="https://i.imgur.com/97pwk0u.png" style="width: 200px;" />
## 瀏覽器前綴
> - 處理老版本瀏覽器兼容性問題
> - 現在寫 css 可以不用加前綴, 在編譯的時候讓他自己加就行了
- `-webkit-`: Chrome, Safari, Andriod Browser
- `-moz-`: firefox
- `-o-`: opera
- `-ms-`: IE
- `khtml`: Konqueror
## 背景漸層 (Linear Gradient)
`<linear-gradient>: [ <angle> | to <side | corner> ]? <color-stop>#`
- `<angle>`: `num [deg | grad | rad | turn]`
- `<side | corner>`: `[ left | right ] || [ top | bottom ]`
- `to left` = 270 deg
- `to right` = 90 deg
- `to top` = 0 deg
- `to bottom` = 180 deg (預設)
- `<color stop>`: `color [ length | percentage ]`
```htmlmixed=
<head>
<meta charset="utf-8"/>
<style>
div {
width: 20%;
height: 100px;
margin: 300px auto;
background: linear-gradient(to bottom left, blue, skyblue 10%, red 30%, yellow 40%);
}
</style>
</head>
<body>
<div></div>
</body>
```