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(灰) ![](https://i.imgur.com/1bXdvTW.png) > > - 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 ![](https://i.imgur.com/x5NMq0y.png) > - 這裡有一張圖, 如果我想要使用橘色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 ![](https://i.imgur.com/WNRXie9.jpg) ```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改一改了 ## 滑動門 ![](https://i.imgur.com/O3tLs3d.png) > - 常常會遇到一些難做的框框,例如上圖, > - 通常這類都會使用背景圖來完成,惟字數都不一樣多是如何做到的呢? > - 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: ![](https://i.imgur.com/INakgjB.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`: 時間曲線 > - ![](https://i.imgur.com/7zTsBTx.png) > - 預設: 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方向 > ![](https://i.imgur.com/KHicG75.png) > - CSS3的3D方向 > ![](https://i.imgur.com/nZseXaF.png) ### 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 不能寫%數, 只能寫值 ![](https://i.imgur.com/ycZGi9D.png) > - 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> ``` ### 實作: 超酷炫旋轉 ![](https://i.imgur.com/cnDDNqF.png) > - 想法: 滑鼠放上淺藍色盒子時, 全部旋轉 > - 邏輯: > - 由於是立體的, 中間盒子與外圍盒子要有距離(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`: 行對齊(預設) > ![](https://i.imgur.com/HDT9Hi0.png) > - `flex-direction: row-reverse;`: 水平, 順序相反 > ![](https://i.imgur.com/Naew7jd.png) > - `flex-direction: column`: 列對齊 > ![](https://i.imgur.com/csTfEoG.png) > - `flex-direction: column-reverse;`: 列對齊, 順序相反 > ![](https://i.imgur.com/Afsgl4u.png) > #### 另外一種說法(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;`: 子元素的起始與父元素的起始對齊, 順序不變 (預設) > ![](https://i.imgur.com/upTUwv4.png) > > - `justify-contnet: flex-end;`: 子元素的結束與父元素的結束對齊, 順序不變 > ![](https://i.imgur.com/HKlT9su.png) > > - `justify-content: center;` > ![](https://i.imgur.com/L9k0lAV.png) > > - `justify-content: space-between;`: > ![](https://i.imgur.com/pRlQHYk.png) > ![](https://i.imgur.com/yge1uUF.png) > - 首個子元素的起始與父元素起始對齊, > - 末個子元素的結束與父元素結束對齊 > - 剩餘子元素間分配剩餘空間 > - `space- between`: 剩餘空間分散在中間 > > - `justify-content: space-around;` > - 剩餘空間分散在兩邊 > - 相當於每個盒子添加相同margin > ![](https://i.imgur.com/gXgmnEu.png) ### align-items `align-items: flex-start | flex-end | center | stretch` > - 調整Y軸對齊方向 > - 以下子元素 `width: 100%;` > - `align-items: stretch`: 不給高度的前提下, 拉伸子元素的高度與父元素相同 (預設) > ![](https://i.imgur.com/ILA1xHs.png) > > - `align-items: flex-start;` > ![](https://i.imgur.com/c8WzIHh.png) > > - `align-items: flex-end;` > ![](https://i.imgur.com/rIQAg3p.png) > > - `align-items: center;` > ![](https://i.imgur.com/6O7SCGF.png) ```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`: 不換行,強制壓縮成一行 (默認) > ![](https://i.imgur.com/mNSBpij.png) > > - `flex-wrap: wrap`: 換行 > ![](https://i.imgur.com/r7MBHAQ.png) > > - `flex-wrap: wrap-reverse`: 換行後翻轉 > ![](https://i.imgur.com/V9otXLo.png) ### 解決問題: 使用float無法讓每列等高 #### float > - 根據內容給高後, 內容不同就沒有等高 ![](https://i.imgur.com/tJQeRgV.png) ```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 ![](https://i.imgur.com/tlDiX13.png) ```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` > ![](https://i.imgur.com/cRONSmE.png) > - `align-content: flex-end` > ![](https://i.imgur.com/cFydeeK.png) > - `align-content: center` > ![](https://i.imgur.com/zc4jvah.png) > - `align-content: space-between` > - 剩餘空間分散在中間 > ![](https://i.imgur.com/1kXsygk.png) > - `align-content: space-around` > - 剩餘空間分散在兩邊 > ![](https://i.imgur.com/3HkRbBj.png) > - `align-content: stretch`(預設) > ![](https://i.imgur.com/Nyk8ptg.png) > - flex 的多行排列 vs. `align-items`單行排列 > - `align-items` 是設定單行交叉軸的對齊 > - `align-content` 是設定整體交叉軸的對齊 > - 兩個都預設 (兩個都是拉伸到最大) > ![](https://i.imgur.com/CHAVcCP.png) > - 如果我只有設 `align-items: center;` > ![](https://i.imgur.com/QTtGbZr.png) > - 如果我只有設 `align-content: center;` > ![](https://i.imgur.com/7MJggET.png) > - 如果我兩個都設 `center;` > ![](https://i.imgur.com/ANur8Ki.png) ### align-self > - 這東西其實就是拿來覆蓋父級的 align-items > - 個別設置交叉軸的對齊 ![](https://i.imgur.com/DR3or04.png) ```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的前提 > - 有寬有高有邊距有邊框的屬性 > ![](https://i.imgur.com/obj1EWD.png) > - 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第五個特性可以把沒有高度的容器撐開 > ![](https://i.imgur.com/ssWOwFZ.png) -> ![](https://i.imgur.com/ePsfOv2.png) ```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> ```