---
# System prepended metadata

title: CSS 學習筆記

---

> 如果有記憶吐司就好了...

# CSS 學習筆記


---

## float與clear:both
float可以設定的值:
* left：靠左浮動
* right：靠右浮動
* none：預設值，也就是不浮動
* inherit：繼承自父層的屬性

clear可以設定的值:
* left：消除左邊的浮動
* right：消除右邊的浮動
* both：消除左右兩邊的浮動
* none：預設值，不消除任何一邊的浮動
* inherit：繼承浮動，IE未支持此屬性值

```htmlembedded=
<div class="wrap">
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
</div>
```
```css=
.wrap {
  width: 600px;
  background: #d07;
  margin: auto;
}
.col {
  border: 1px solid #000;
  width: 200px;
  height: 100px;
  background: #eee;
}
```
呈現如下:

![](https://i.imgur.com/CRDc6S7.jpg)

若要將三個灰色區塊變成橫向並排,通常會使用到float的屬性,需注意的是若父層(wrap)寬度為600px,那麼子層(col)的區塊的寬度需自行運算,margin+padding+border+col總寬度若超過wrap,則超出的區塊會自動斷行。

另一個須注意的地方就是,原本的父層(wrap)的寬度有設定,高度是由子層(col)撐開的,但由於float的特性是浮動,當子層(col)設定float之後,父層的高度就會跑掉,如下圖:

![](https://i.imgur.com/ATxcmlf.jpg)

此時的wrap因為沒有高度以及寬度跟子層的寬度一樣,所以會看不見,當我再將wrap設定高度50px以及寬度再加上10px之後,就可以看到超出來的wrap了,如下圖:

![](https://i.imgur.com/ZkfHXsS.jpg)

現在的狀態是,wrap寬610px高50px是存在的,子層的總寬度是600px高100px是蓋在wrap上方,所以能看到wrap的部分只能看到多出來的寬10px高50px的區塊。
若要避免因為子層下float導致跑版,可以新增一個區塊在子層的最後面,用clear:both去將前面col的浮動特性清除,進而撐開高度。

```htmlembedded=
<div class="wrap">
  <div class="col"></div>
  <div class="col"></div>
  <div class="col"></div>
  <div class="clearFix"></div>
</div>
```
```css=
.wrap {
  width: 600px;
  background: #d07;
}
.col {
  border: 1px solid #000;
  margin: 10px;
  width: 178px;
  height: 100px;
  background: #eee;
  float: left;
}

.clearFix {
  clear: both;
}

```
呈現如下:
![](https://i.imgur.com/MOR8pMq.jpg)


---

## inline與block及他們的孩子inline-block

### inline - 行內元素
特性:
* 傳說中的日本人,很整齊的排排站
* 不能設定寬跟高
* 長度是靠內容撐開的

### block - 區塊元素
特性:
* 傳說中的佔位哥,自成一行
* 可以設定寬跟高

### inline-block
特性:
* 可以排排站
* 可以設定寬跟高

inline-block常用在導覽列,以下示範一個範例:

```htmlembedded=
<nav class="menu">
  <a href="#">新聞</a>
  <a href="#">新聞</a>
  <a href="#">新聞</a>
  <a href="#">新聞</a>
  <a href="#">新聞</a>
  <a href="#">新聞</a>
</nav>
```
```css=
.menu {
  background: #fa0;
  text-align: center;
}

.menu a {
  display: inline-block;
  text-decoration: none;
  padding: 10px 30px;
  background: #aaa;
  
}
.menu a:hover{
  background: #000;
}
```
呈現如下:
![](https://i.imgur.com/QVVSaVJ.jpg)

此時由於a與a之間有約4-5px(視字型而定)的空白該如何去除呢?
我們可以將menu的font-size設為0,再將文字大小設定在menu內的a標籤內即可解決這個問題。

```css=
.menu {
  background: #fa0;
  text-align: center;
  font-size: 0;
}

.menu a {
  display: inline-block;
  text-decoration: none;
  padding: 10px 30px;
  background: #aaa;
  font-size: 16px;
}
.menu a:hover{
  background: #000;
}
```
呈現如下:
![](https://i.imgur.com/TvSa23y.jpg)


---

## box-sizing
以往在排版時,都須計算像是padding+margin+border+寬度,需算好才不會跑版,現在有了box-sizing就可以省掉計算的時間。
### box-sizing: content-box
此為預設的狀態,寬度是以內容寬度為主,所以若外層設定寬為960px,要分成三欄,那總寬度(內容寬度+padding+margin+border)不能超過960px,否則會跑版。

### box-sizing: border-box
寬度是以border的寬度為主,若若外層設定寬為960px,要分成三欄,但由於margin是在border外面,所以須注意內容寬度+margin寬度不超過960px即可。


---

## 滿版式Banner設計
要設計滿版的Banner先決條件是需要一張很大的圖,寬度最好1920px以上喔。

關鍵語法:
1. height: calc(100vh - 67px)
* 100vh=100%
* calc是計算
* 扣掉67px是header的高度

3. background-size: cover
* 調整背景圖像的大小以覆蓋整個容器，即使它必須拉伸圖像或從邊緣剪掉一點。

```htmlembedded=
<div class="header">
  <div class="container">
    <a href="#" class="logo">
      旅遊吧
    </a>
  </div>
</div>

<div class="banner d-flex align-items-center justify-content-center">
  <h1 class="text-white">開始實現你的夢想旅程</h1>
</div>
```
```css=
a{
  text-decoration: none;
}

.header{
  background: #F0F0F0;
  padding: 20px 0;
}

.logo{
  font-size: 24px;
  font-weight: bold;
  line-height: 24px;
  color: #28DAA5;
}

.banner{
  height: calc(100vh - 67px);
  background-image: url(https://images.unsplash.com/photo-1573126617899-41f1dffb196c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80
);
  background-size: cover; 
  background-repeat: no-repeat;
  background-position: center;
}
```
呈現如下:
![](https://i.imgur.com/QBEw62Q.jpg)

若沒有計算好,網頁會有y軸,若將
height: calc(100vh - 67px)改為height: calc(100vh - 10px)

呈現如下:
![](https://i.imgur.com/ts5oTjR.gif)


---

## 排版神器flex


### flex 外容器屬性：

#### display
display 是我們熟知的 CSS 屬性，對於 Flexbox 來說，多了有兩種方式可以設定，預設為「flex」，其布局方式與 block 幾乎類似，都會強迫換行，但設定display:flex的子元素卻具備了更多彈性的設定，此外另外一種方式則是「inline-flex」，和 inline-block 也是幾乎雷同，意義上都是一個display:flex的元素外面包覆display:inline的屬性，在後方的元素不會換行。

#### flex-flow (flex-direction 與 flex-wrap 的縮寫)
簡單說就是合併了兩種屬性，用一個屬性就可以設定主軸的方向以及要不要換行。
* <‘flex-direction’> || <‘flex-wrap’>
#### flex-direction
設定主軸的方向。
* row 主軸由左至右 次軸由上至下
* row-reverse 與row相反
* column 主軸由上至下 次軸由左至右
* column-reverse 與column相反

#### flex-wrap
這個屬性負責的是讓內容的元素換行，因為當我們把父元素的 display 設定為 flex 或 inline-flex 的時候，子元素就是以單行的方式，彈性撐滿父元素，所以就要利用 flex-wrap 來換行，共有三個設定值。
* nowrap 預設值，單行。
* wrap 元素自動換成多行。
* wrap-reverse 元素自動換成逆序的多行。

#### justify-content
justify-content 決定了內容元素與整個 Flexbox 的「水平對齊」位置，回想一下最上面講的 Flexbox 盒子模型，具有 main start 與 main end 左右兩個端點，justify-content 就是按照這個方式做設定，而其中的設定值總共有下列五個。
* flex-start 靠主軸的起點
* center 置中
* flex-end 靠主軸的終點
* space-around 每行平均分配間距
* space-between 每行平均分配間距，左右元素將會與主軸的起點與終點貼齊
* space-evenly

#### align-items
align-items 剛好和 justify-content 相反，align-items 決定了內容元素與整個 Flexbox 的「垂直對齊」位置，再回想一下最上面講的 Flexbox 盒子模型，具有 cross start 與 cross end 左右兩個端點，align-items 與 align-self 就是按照這個方式做設定，設定值總共有下列五個。
* flex-start 靠次軸的起點
* flex-end 靠次軸的終點
* center 置中
* baseline 以所有內容元素的基線作為對齊標準
* stretch 預設值，內容元素全部撐開

#### align-content
遇到多行的元素，就要使用 align-content 這個屬性，這個屬性總共有六個設定值。
* flex-start 靠次軸的起點
* flex-end 靠次軸的終點
* center 置中
* space-between 將第一行與最後一行分別對齊最上方與最下方
* space-around 每行平均分配間距
* stretch 預設值，內容元素全部撐開

### flex 內元件屬性：

#### flex
由三個屬性組合而成，依照先後順序分別是「flex-grow」、「flex-shrink」和「flex-basis」，如果 flex 只填了一個數值 ( 無單位 )，那麼預設就是以 flex-grow 的方式呈現，三個屬性可以分開設定，也可以合在一起用一個 flex 統一設定，下面的例子展現出同一個 Flexbox，在不同的寬度，子元素會有不同大小的呈現。
* none
* [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ]

#### flex-grow (伸展)
數字，無單位，當子元素的 flex-basis 長度「小」於它自己在父元素分配到的長度，按照數字做相對應的「伸展」比例分配，預設值為 0，不會進行彈性變化，不可為負值，設為 1 則會進行彈性變化。
* number 剩下的空間依照比例做伸展

#### flex-shrink (收縮比)
數字，無單位，當子元素的 flex-basis 長度「大」於它自己在父元素分配到的長度，按照數字做相對應的「壓縮」比例分配，預設值為 1，設為 0 的話不會進行彈性變化，不可為負值。
* number 預設為1
總比值-各子項目的寬度*收縮值,並加總所有子項目計算結果
超出值
扣除值
(子項目寬*收縮比/總比值)*超出值 = 扣除值

#### flex-basis
子元素的基本大小，作為父元素的大小比較基準，預設值為 0，也因為預設值為 0，所以沒有設定此屬性的時候，會以直接採用 flex-grow 屬性，flex-basis 也可以設為 auto，如果設為 auto，就表示子元素以自己的基本大小為單位。
* XXXpx 控制物件的主軸長度

#### order
可以直接指定一個數字，預設為0,設定為1就往右,設定為-1就往左,由小到大的排列順序。
* nember 

#### align-self
align-self 的設定與 align-items 相同，但目的不同，align-self 的作用在於覆寫已經套用 align-items 的屬性，如果照我們以前所寫，因為 align-items 是針對子元素，所以必須要用 align-self 來進行覆寫。
* auto
* flex-start
* flex-end
* center
* baseline
* stretch


---

## Position 定位

### static
啟用方式 position:static;
「static 靜態定位」此定位是將其他定位特性取消，回到最原始的狀態，一般來說除非有特殊狀況，不然不會用到，多數的網頁物件預設也都屬於此種定位。

### relative
啟用方式 position:relative;
「relative 相對定位」的效果是將設定的物件，將其參考空間參考自身原始的資料流位置，且此種定位值並不會將物件獨立一層，搭配其它 CSS 屬性，如 top 、 right 、 bottom 、 left 可做到「顯示位置的偏移」。
若使用偏移後蓋住了另一個品項,若希望品項不要被蓋住,此時可以用z-index去設定由誰覆蓋住誰。

### absolute
啟用方式 position:absolute;
「absolute 絕對定位」的效果是將設定的物件，將其參考空間設定為「階層離自身最近且具備定位設定的父層空間」，倘若沒有任何一個父層空間俱備定位設定，最終該物件將採用視窗空間座位參考空間，而父層空間只要俱備了以下四種定位類型，就可被絕對定位物件做為參考空間，此外當物件設定了 absolute 之後，將會自己獨立一層，不會與其它物件有任何關連，所以可以利用 absolute 來做到物件堆疊的視覺效果。
* relative
* absolute
* fixed
* sticky

### fixed
啟用方式 position:fixed;
「fixed 固定定位」的效果是將設定的物件，將其參考空間設定為「視窗」，也就是說當我對一個物件設定了 position: fixed; 之後，該物件的參考空間就直接對視窗的範圍了，需要特別注意的是 fixed 定位與 absolute ，一樣都會自己獨立一層，在實務應用上，常見的「蓋版廣告」或者是「光箱效果/light box」，又或者是 Bootstrap 中的「modal組件」，以及常見的網頁導覽列要固定在視窗上方的效果，再不然就是經常出現在視窗右下角的那一個「回到頁面頂端」的區塊，都是普遍會使用到 fixed 定位的

**fixed與absolute的差異**
fixed 除了將參考空間設定為視窗與自己獨立一層外，也由於定位的空間是定在視窗內，所以不管你如何捲動你的視窗卷軸，這個物件就是怎樣都不會換位置，但 absolute 若定位在視窗的話則會被捲走，這也是兩者之間非常明顯的差異點。

### sticky
啟用方式 position:sticky;
「sticky 黏貼定位」是所有定位中最年輕也最新的一個定位了，這個值非常的棒，它同時結合了 relative 與 fixed 兩大特性，這個定位的特色是

* 預設定位在父層空間
* 當視窗捲動到該物件位置時，會依據對該物件所設定的 top 值來讓該物件呈現 fixed 在視窗的效果
* 當物件呈現 fixed 效果時，其所能 fixed 的空間是該物件的父層空間
* 當視窗往下捲到超過 sticky 物件的父層空間時， sticky 物件則不會再呈現 fixed 的效果，而是會被捲離視窗範圍。

## transition 動畫
啟用方式: transition: 屬性 轉換時間 延遲執行時間 速度;
若要設定兩個屬性或以上,可使用逗號隔開。
```htmlembedded=
<a href="#" class="btn">送出</a>
```
```css=
.btn {
  background-color: #000;
  color: #fff;
  display: inline-block;
  padding: 10px 20px;
  text-decoration: none;
  transition:all 0.5s;  //屬性 轉換時間
}

.btn:hover {
  background-color: #fa0;
}
```
呈現如下:
![](https://i.imgur.com/xQDBQXJ.gif)


---

## animation 動畫

啟用方式: animation: 動畫名稱 播放時間 延遲執行時間 速度 次數 方向 填充模式 播放狀態;

```htmlembedded=
<div class="wrap">
  <div class="box"></div>
  <div class="box1"></div>
</div>
```
```css=
.wrap{
  display: flex;
  padding: 30px 30px;
}

.box {
  background-color: #f00;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  margin-right: 10px;
}

/* animation 下box1 */
.box1 {
  background-color: #f00;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  animation: circle 2s infinite alternate;
/* circle = 動畫名抽
 * 2s = 播放2秒 
 * infinite = 無限播放次數 
 * alternate = 來回播放 */
}

@keyframes circle {
  0%{border-radius: 50%}
  100%{border-radius: 0%}
}
```
呈現如下:
![](https://i.imgur.com/8jkngi6.gif)


---
## CSS reset小技巧
1. 防止圖片破版,可以在css reset處加上下面的程式碼

`max-width: 100%` 寬度最大為圖片本身的寬度,若比圖片寬度小則會自適應調整比例,而寬度若比圖片大則會定格在本身圖片最大的寬度
```css=
img {
    max-width: 100%; 
    height: auto;
}
```
2.讓你可以不用去計算padding、margin、border

`box-sizing: border-box` 將box尺寸的計算直接從border去算,假設設定寬100px,那麼包含border、padding總寬就是100px(margin不含喔)
```css=
*,*::before,*::after{
    box-sizing: border-box
}
```

---


## 如何指定區塊直接到最下方

會自動補滿距離父層的上方的margin

```css=
margin-top: auto;
```

---


## 輕鬆讓內層有自適應技巧
若外層已有一個寬度,內層可用%的方式輕鬆達到自適應
```htmlembedded=
<div class="outside">
    <div class="inside"></div>
</div>
```
```css=
.outside{   
    max-width: 1000px;
}
.inside{
    width: 70%;
}
```

---



## RWD 媒體查詢

```css=
/* 手機版常見尺寸 */
@media(max-width:375px) {
    ...    
}
@media(max-width:414px) {
    ...    
}
---
/* 平板常見尺寸 */
@media(max-width:768px) {
    ...    
}
---
/* pc版常見尺寸 */
@media(max-width:1140px) {
    ...    
}
@media(max-width:1200px) {
    ...    
}
```

## 藉由darken、lighten調出想要的顏色

```css=
/* 比括弧設定的顏色再深40% */
box{
    background: darken(顏色,40%)
}

/* 比括弧設定的顏色再淡40% */
box{
    background: lighten(顏色,40%)
}
```

---


## 圖片取代文字的技巧
### 為什麼要使用圖片取代文字的方式來寫LOGO?
因為 google 機器人無法搜尋到圖片，只會認文字內容，所以為了讓搜尋引擎能夠找到網站重要內容，建議用圖片取代文字的方法。
* logo 背景圖位置寫在 a 連結，才能點擊的到。
* a 連結為行內元素，記得寫 display:block 變區塊元素logo圖才會正確顯示
* 重點css 屬性:
```css=
text-indent:101%; /*首行縮排*/
overflow:hidden; /*自動隱藏超出的文字或圖片*/
white-space:nowrap; /*希望元素在第一排上面，沒有斷行*/
```
範例1:
```htmlembedded=
<body>
  <h1 class="logo">
    <a href="#">公司logo</a>
  </h1>
</body>
```
```css=
.logo a{
    display:block;
    background: url(../.png) no-repeat;
    width: 170px;
    height: 36px;
    text-indent: 101%;
    overflow: hidden;
    white-space: nowrap;
}
```
範例2: 使用float
```htmlembedded=
<div class="wrap">
  <div class="header clearfix">
    <h1 class="logo"><a href="#">六角學院</a></h1>
      <ul class="nav clearfix">
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Shop</a></li>
      </ul>
  </div>
</div>
```
```css=
.wrap{
  width: 960px;
  margin: 0 auto;
}
.clearfix:after{
  content:'';
  display:table;
  clear:both;
}
.header{
  background: #a1bad0;
  padding:10px;
}
.logo a{
  display:block;
  background: url(../.png) no-repeat;
  width: 170px;
  height: 36px;
  float:left;
  text-indent:101%;
  overflow:hidden;
  white-space:nowrap;
}
.nav{
  float:right;
}
.nav li{
  float:left;
}
.nav a{
  display:block;
  padding:10px 15px 10px 10px;
  text-decoration:none;
  color:#fff;
  font-size:18px;
  font-weight:600;
}

```

---

## 位元素水平調整及垂直置中

垂直置中 父層flex+align-items:center
水平置中 justify-content: center
水平可用margin、padding調整


