# [FE101] 前端基礎:CSS
> [TOC]
CSS= Cascading Style Sheets 階層式樣式表
## CSS 基礎 1: Selector
### CSS selector
有三種使用 CSS 的方法:
1. 「很少用」直接寫在 html 裡面
```htmlembedded=
<body>
<div style='background=red'></div> <!--很難維護,所以很少使用-->
</body>
```
2. 「很少用」直接寫在 html 的 `<style>` 標籤包住的裡面
```htmlembedded=
<head>
<style>
div {
background: red;
}
</style>
</head>
```
3. 「最常用」將 CSS 獨立成一個檔案,再在 HTML 檔案內使用 `<link rel='stylesheet' href='xxx.css'>` 連結,這樣 CSS 和 HTML 兩個檔案互不干擾。
當 html 內容變多後,可以把 css 的檔案另存成 .css 的副檔名。
```htmlmixed=
<!--in a html file-->
<head>
<link rel='stylesheet' href='./style.css'></link>
</head>
<body>
<div></div>
</body>
<!--in a css file-->
div {
background: red;
}
```
### CSS selector:我全都要
CSS Selector Universal Selectors: 可以使用 **`*`** 到所有的元素。
```css=
* {
color: red;
}
```
### CSS selector:標籤 selector
標籤 selctor 會選到所有的標籤。
缺點:在實際開發的時候,不常用到標籤 selector,因為通常選到一兩個要的元素來更改樣式。
```css=
div {
background: green
}
```
### CSS selector:id 與 class(最常用!)
| HTML | CSS | 譬喻 |規則說明|
| -------- | -------- | -------- | -------- |
| id='div1' | #div1 {} | 身份證 | 整個檔案只能有一個 id |
| class='bg-yellow'| .bg-yello {} | | 一個元素可以有很多個 class |
| class='bg-yellow text-white'| .bg-yello {} | | 各個元素可以擁有複數個 class 也可以共享 class|
### CSS selector:同時符合
同時符合的條件,selector 才會有效。
* HTML 標籤與 class 同時符合 ``<div class='bg-yellow>` 才會背景變黃色
```css=
div.bg-yellow {
background: yellow;
}
```
* 同時具有 class='bg-yellow bg-real-yellow' 背景才會變黃色
```css=
.bg-yellow.bg-real-yellow {
background: yellow
}
```
### CSS selector:底下的元素
什麼是底下的元素?
如下程式,那要怎麼選 lv3 的CSS selector呢?
```htmlembedded=
<!--HTML-->
<div class='lv1'>lv1
<div>lv2
<div class='bg-red'>lv3
</div>
<div class='bg-red'>
hello
</div>
</div>
</div>
```
* select: `class=lv1` 的**下一層** `div`
```css=
/* CSS */
.lv1 > div {
background: red;
}
```
* select: `.lv1 .'bg-red'` 意即:`.lv1` 底下(所有被包住的裡面層)**所有**的`bg-red`
```css=
.lv1 .bg-red {
background: red;
}
```
Summary:
CSS=Cascading Style Sheets 裡,Cascade(階層式)的一層一層的概念,一個包一個的結構。
### CSS selector:~與+
**「同一層」「旁邊」的元素**: + 與 ~
```htmlembedded=
<!--HTML-->
<div class='bg-red'>div1</div>
<div>div2</div>
<div class='bg-red'>div3</div>
<div class='bg-red'>div4</div>
<div>123</div>
<span>456</span>
<span>789</span>
```
`+`:旁邊的**一個**元素
* 要選 `class='bg-red'` 旁邊也是 `class='bg-red'` 的標籤,所以是 `div4` 顯示 `background: red`。
* 要選 `div` 旁邊的 `span` 的 **`span`**,變成 `background: blue;`
```css=
.bg-red + .bg-red {
background: red;
}
div + span {
background: blue;
}
```
`~`:旁邊的**所有**元素
* 要選 `div` 旁邊所有 `span` 的元素,所以是 `456`、`789` 皆變成`background: blue`
```css=
div ~ span {
background: blue;
}
```
應用:希望在 `span` 貼齊邊邊,然後 `span1 span2 span3 span4` 想要在每個 `span` 的中間加間隔。
```htmlmixed=
<span class='bg-red'>span 1</span>
<span class='bg-red'>span 2</span>
<span class='bg-red'>span 3</span>
<span class='bg-red'>span 4</span>
```
```css=
.bg-red ~ .bg-red {
margin-left: 20px
}
```
### CSS selector:Pseudo classes,以 hover 為例
* hover: 滑鼠移過去標籤的動作,要顯示什麼樣的樣式。
```css=
span:hover {
background: red;
}
```
* debug 工具: Chrome developer > element > span 口 `:hover`,滑鼠不用移到上面,也可以顯示 `hover`
* 更多 pseudo class 參考:[pseudo class MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes)
* 應用:點過的連結,顯示什麼顏色,和未點過的連結做區分。
### CSS selector:nth-child
* 分類:CSS selector > pseudo class: nth-child
* 舉例:
* `:last-child`
* `:nth-child(3)`
* `:nth-child(odd)`:
* `:nth-childe(3n)`: n=0, 3, 6, 9
* `:nth-childe(3n+1)`: n=1, 4, 7
舉例:**`nth-child(n)` 先看順序才看標籤**
<code>.wrapper .bg-red:nth-child(2)</code>是怎麼看的?
* 想法 1:`.wrapper` 底下的第二個 `.bg-red` 的標籤
* 想法 2:`.wrapper` 底下的第二個是不是 `.bg-red` 的標籤
<iframe height="265" style="width: 100%;" scrolling="no" title="css-nthchild-sample" src="https://codepen.io/estella00911/embed/BaWQKbL?height=265&theme-id=dark&default-tab=html,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href='https://codepen.io/estella00911/pen/BaWQKbL'>css-nthchild-sample</a> by PinChun
(<a href='https://codepen.io/estella00911'>@estella00911</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>
### CSS selector:before and after
* 分類:CSS selector > pseudo class > pseudo element: before & after
* 為了跟 pseudo class 區分,pseudo element 需要兩個冒號`::`
* 應用 1:在 CSS 統一修改,比在 html 個別修改方便
<iframe height="265" style="width: 100%;" scrolling="no" title="CSS part1- before&after" src="https://codepen.io/estella00911/embed/xxqROON?height=265&theme-id=light&default-tab=html,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href='https://codepen.io/estella00911/pen/xxqROON'>CSS part1- before&after</a> by PinChun
(<a href='https://codepen.io/estella00911'>@estella00911</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>
<br>
<br>
* 應用 2:簡潔的 code :容易在 CSS 上修改、更新樣式
1. 只要在 CSS 上面修改內容、樣式很方便!
1. 使用自定義名稱:通常都取為「data-id」
1. **比較:搭配`span`**
每次都要新增 span,很麻煩!
<iframe height="265" style="width: 100%;" scrolling="no" title="dyvOXdG" src="https://codepen.io/estella00911/embed/dyvOXdG?height=265&theme-id=light&default-tab=html,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href='https://codepen.io/estella00911/pen/dyvOXdG'>dyvOXdG</a> by PinChun
(<a href='https://codepen.io/estella00911'>@estella00911</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>
### CSS selector 的權重
**權重**:`id` > `class` > `標籤` (越詳細的贏)
**小幫手:** Chrome developer > elements > styles 可以看樣式的權重
> **「很少用的」例外**:HTML inline style 與 `!important`
> * HTML inline style >> CSS selector 權重
> * `[盡量少用 因為會把其他蓋掉]` 放在 `color:red !important` 的`!important`
**權重公式**:
| id | (psuedo)class, attribute | tag(標籤) |
| -------- | -------- | -------- |
| 0 | 0 | 0 |
**權重計算**:
| CSS selector | 權重計算 |
| -------- | -------- |
|.wrapper .list .item| 0,3,0|
|div.wrapper > div.list|0,2,2|
|#pick|1,0,0|
| !important | 1,0,0,0 |
**<u>Summary</u>**:
* 很少使用 `!important` 及 HTML inline styles
* **權重**:`id` > `class` > `標籤` (越詳細的贏)
###### 以下 part 僅作重點筆記
## CSS 基礎 2: 各種裝飾
### 背景:background
可以把背景設計成顏色及圖片
* color:
舉例: `background: red`
* rgb(244,8,0)
* rgba(244,34,12,0.5): 0.5 為透明度
* #ff00ff
* red(顏色名稱)
* picture:
```css=
background: url(./bg.jpg) no-repeat center center
/* url 不重複 x置中央 y置中央*/
height: 300px;
width: 200px;
```
* x, y 軸對齊
* bottom, right, left, center, top
* background-size
* 單位:`50%`, `px`, `contain`, `cover`
* `contain`:看是長、寬哪一部份貼合,不會更改長寬比例
* `cover`: 常用。
* 小幫手: Google developer > elements > styles 可以查顏色色號(如:#ff00ff)
### 把自己框起來:border, border-radius
往 box 外面延伸,然後框起來。
* `border`
加了 `border` 會影響到原本 box 位置,所以 box會移動。
* `border style`:
* `solid`:
* `dotted` 等等。
* `border-radius`:
* `10px`, `100px`, `50%` etc.
* 圓形
如果縮 50% 的話,就會變半徑,形狀會從方形變圓形。
* 三角形
利用 `border-top`, `border-bottom`, `border-left`, `border-right`, `height`, `width` 畫三角形。
* `outline`:
加了之後,往元素外面延伸,不會動到任何 box 位置
### 離我遠一點:邊距 margin, padding
* `margin`: 外邊距。
* `margin: 20px`: 上下左右 20px
* `margin: 20px 10px`: 上下 20px,左右 10px
* `margin: 8px`: 在開瀏覽器看 CSS box 成果時,會與最邊邊有空白,那是瀏覽器自行加上的,如果要與邊邊無空隙,可以在CSS檔案上寫 `margin: 0px`
* `padding`: 內邊距。
### 文字相關:color, font-family, font-weight, white-space
* `color: white`: 文字顏色
* `font-size: 30px`: 文字大小
* `font-weight: 100`: 100~900 細體、粗體、一般等等
* `font-family: serif`: 字體
* `letter-spacing: 1px`: 字母與字母間的間距
* `line-height: 1.5 em`:就是字大小的1.5倍行高。
* `line height:100px` 與 `text-align: center`: 與色塊(height:200px),這樣就會有垂直置中的效果。缺點就是如果有兩行文字的話,第二行就會隔很開。
* 垂直置中(另法):不設 box 的高,直接使用 `padding: 30px 0px`,上下 30px 左右 0px 一樣會被放在中間。
* `text-align: center`: 置中對齊。
### 文字相關 part 2: word-break, white-space
調整文字很長的時候,做切割。
* `word-break`:
* `break-all`: 單字直接被切兩行。
* `break-word`: 會把單字放在同一行的切成不同行。
* `white-space`:
* `nowrap`: 強制在同一行
### 滿了,那就漫出來:overflow, text-overflow
內容超出方框寬度要怎麼處理?
* `overflow:`
與 `text-overflow`的差異:`overflow` 的應用較廣
* `scroll`: 不管有沒有超過,都會顯示可滾動的滾輪區域
* `hidden`: 截斷,然後藏起來
* `auto`: 如果有超過寬度,才會顯示滾輪,可滾動的區域
* `text-overflow:`
與 `overflow`的差異:`text-overflow` 只能用在文字
* `ellipsis`: 把多的字,使用`...`蓋掉,
* **使用條件**需要加入:
1. `overflow: hidden`,才能把多的蓋掉
2. `white-space: nowrap`: 強制在同一行
### 加了我質感瞬間升級:transition
漸變,搭配 `hover`,不過 `transition` 不是放在`hover`
* `transition: all 1s ease-in`
* ease-in: 動畫可以從 google developer 調整
### Die Verwandlung transform 的妙用
變形轉換
* `:hover {transform:... }`
* `scale(2)`: 從中心點變大兩倍。
* `rotate(180deg)`: 可以轉 180 度。
* `translate(50px, -20px)`: 從原本位置偏移,不會影響到其他方塊。
* `「常用」`置中在畫面正中央
* `position: absolute`
* `top: 50%` 上方整個畫面的 50%
* `left: 50%` 方框左上角為正中間
* `transform: translate(-50%, -50%)` 依照元素寬度高度一半向左上移動,就達成垂直水平置中。
## CSS 基礎 3: Box Model
### 什麼是 Box Model
* box model 意義:從 content 的設定的尺寸大小,再向外擴展 padding, border。
* 可是就是想要整個 box 都符合設定的尺寸,不想要向外擴展的話,可以使用 `box-sizing: border-box`,設定的寬高 200px 100px,整個元素的 content、border、padding 就是 200px 100px。
*
### Display 有三種:block, inline, inline-block
* `display:`
* `block`: div、h1、p 的預設。
* `inline`: span a 的預設,
* 調寬高、上下邊距都沒有用,只能調整左右邊。不過調整垂直`padding` 會影響元素的大小,不會影響位置,但通常沒什麼用。
* `inline-block`:
* 如 `button`、`input`、`select`。
* 對外像 inline 可並排,可以調寬高、margin。
* 對外像 block 可調各種屬性。
* 比較:
* `inline-block` vs `block` : 一行內可不可以擺多個元素。
## CSS 基礎 4: position
### 最好理解的兩個:static, relative
* `static`:
* default
* 按照順序往下排。
* `relative`:
* 改變相對位置,不會影響其他元素的位置
* 改變偏移的舉例:`top`、`left`、`right`、`bottom`: 20px
### 沒那麼難理解:absolute, fixed
* `position:`
* `fixed`: 不管怎麼捲動頁面,都會在瀏覽器上定位,更精確是 wiewport 做定位。
* `absolute`: 需要一參考點。
* 針對某一個參考點 —— 不是 static 的 position。
### 誰在前面?z-index
**決定圖層順序**
`z-index=10` 數字越大,圖層越前面。
### 比較 fashion 的 sticky
`top: 0px` & `postion: sticky` 當滾輪滾到該元素為 `top: 0px` 時,從 static 變成 fix 。
## 簡單切版實戰
* CSS Naming: BEM(block element modifier
* 命名規則:`__` 兩個底線
* `align-items: vertical-align`:
* 用在 `inline` 元素、`table`。
* `<div>`: 視覺上的區塊
* `flexbox`: frog 小遊戲。
* 學習順序:`flexbox` -> `grid` -> `float`
* `reset.css`:
* 在 Chrome、IE、safari 會呈現不同的頁面
* 針對所有標籤下 css。
* `normalize.css`:
* follow 瀏覽器樣式。
* [學習 CSS 版面配置](https://zh-tw.learnlayout.com)
###### tags: `MTR05` `Lidemy學習筆記`