---
# System prepended metadata

title: CSS 基礎
tags: [CSS]

---

# CSS 基礎


###### tags: `CSS`

## CSS的三種寫法：

1. 直接加<style = ''>

```htmlmixed=
<html>
	<head>
		<meta charset= "utf-8"/>
		<title>I am title</title>
    </head>
    <body>
    	  <div stytle="background: red;">
    		hello
    	</div>
    </body>
</html>
```
> 背景變紅色，但不常用，因為難維護。

2. 在 `<head>` 裡面加上 style 標籤
```htmlmixed=
<html>
	<head>
		<meta charset= "utf-8"/>
		<title>I am title</title>
		<style>
			div {
				background: blue;
			}
		</style>
    </head>
    <body>
    	<div> 
    		hello
    	</div>
    </body>
</html>
```
> 背景變藍色

3. 最好的方法為新增到另外一個檔案去。
```
a. 新增 style.css 檔案
b. 貼上 div {background: green;}
c. 加一列 <link rel= "stylesheet" href="./style.css">
//因為存在同一個資料夾底下，可以用 ./
//用法很像 .a 一樣
```

```htmlmixed=
<html>
	<head>
		<meta charset= "utf-8"/>
		<title>I am titled</title>
		<link rel="stylesheet" herf="./style.css">
       </head>
       <body>
    	   <div> 
    		hello
    	   </div>
       </body>
</html>
```

> 背景變綠色

前面兩種用法較不常用，因為不好維護。
第三種用法最常用是因為兩個檔案獨立不干擾！


## CSS selector: Universal Selectors

在 style.css 資料夾內

```htmlmixed=
* {
	color: blue; 
}
```

用星號可以選到所有的東西！


## 標籤 selectors

在 style.css 檔案內
```htmlmixed=
div{
	background: black;
}

body{
	background: green;
}
```
## id 與 class Selector
這兩個最常用的。

1. #YYY
2. .XXX
在一個 `<div>`內，可以設多個 class
```htmlmixed=
<div class="bg-yellow text-white">
	hello world!
</div>
```
```htmlmixed=
.bg-yellow{
	background: yellow;	
}

.text-white{
	background: red;	
}
```
＊兩者之間差別： **id 只能有一個，但是 class 可以有很多個！**

## 同時符合條件
```htmlmixed=
div.bg-yellow{	

}

又是 div 又是 bg-yellow
```

## 底下的元素

檔案： index.html
```htmlmixed=
<html>
	<head>
		<meta charset= "utf-8"/>
		<title>I am title</title>
		<link rel="stylesheet" herf="./style.css">
    </head>
    <body>
    	<div class="Lv1">Lv1
    		<div>Lv2
    			<div>L3</div>
    		</div>
    	</div>
    </body>
</html>
```

* .Lv1
選到全部的 div
```htmlmixed=
<div class="Lv1">Lv1
    <div>Lv2
    	<div>L3</div>
    </div>
</div>
```
* .Lv1 > div
選到 Lv1 下一層的 div => 選到 Lv2
```htmlmixed=
<div>Lv2
    <div>L3</div>
</div>
```
* .Lv1 > div > div
選到 Lv3
```htmlmixed=
<div>L3</div>
```
* .Lv1 div
==中間空格 ＝ 選 Lv1 底下所有的 div==
```htmlmixed=
<body>
    <div class="Lv1">Lv1
    	<div>Lv2
    		<div class="bg-red">L3</div>
    	</div>
    	<div class="bg-red">
    		hello
    	</div>
    </div>
</body>
```

* .Lv1 .bg-red
<mark>注意中間有空格</mark>，和選下面所有的 .bg-red
選到的是 level one 底下所有的 class="bg-red"
```htmlmixed=
<div class="bg-red">L3</div>
<div class="bg-red">hello</div>
```
* .Lv1 > .bg-red
Lv1 底下那一層的 .bg-red
選到的是 hello
```htmlmixed=
  <div class="bg-red">hello</div>
```

## 旁邊的元素：＋ （旁邊） 與 ～（右邊所有的）

>如何定義為"旁邊"？
雖然程式碼看起來是由上到下，但是真正呈現的時候，
為由左到右～另外『+,~』需要在『同一層』才會有效果

大綱:
```htmlmixed=
<body>
    <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>
</body>
```

例一
```htmlmixed=
.bg-red + .bg-red{
	background: red;
}
```
選 class="bg-red" 旁邊的東西 => div4背景為紅色。

例二
```htmlmixed=
div + span {
	background: blue;
}
```
選 div 旁邊的 span => 456背景為藍色
然後因為 `<span>789</span>` 不是在 `<div>`旁邊所以不會被選到

例三
```htmlmixed=
div ~ span {
	background: blue;
}
```
選到 456 and 789

例四
```htmlmixed=
bg-red ~ .bg-red{
	background: red;
}
```
選到 div3 and div4

例五
```htmlmixed=
bg-red + .bg-red{
	background: red;
}
```

選 class="bg-red" 旁邊的東西 (.bg-red) => div4 背景為紅色。

> 影片 5:06 處，講解 ～ 時常遇到的狀況：
當要設定邊距時，每個元素中間是有距離的

```htmlmixed=
.bg-red ~ .bg-red {
    background-color: red;
    margin-left: 20px;
}
```
## Pseudo-classes：某個狀態底下的樣子

* hover
Pseudo-classe想成假的class
:hover 滑鼠移上後變成的模樣

```css 
.mouse:hover{
    background: red; 
}
```

如何得知 debug hover有沒有設定好？
go to devtool
=> styles
=> force element state
=> 打勾 :hover 會維持著 hover 的狀態

- nth-child
```htmlmixed=
<body>
    <div class="wrapper">
	    <div>row1</div>
	    <div>row2</div>
	    <div>row3</div>
	    <div>row4</div>
	    <div>row5</div>
    </div>   
</body>
```
* `.wrapper div {background: red;}`
全選背景變紅色

* `.wrapper div:first-child{}`
選到 row1

* `.wrapper div:last-child{}`
選到 row5

* `.wrapper div:nth-child(3){}`
選到 row3

* `.wrapper div:nth-child(even){}`
選到偶數; odd則是奇數

`nth-child()`用法需要注意：
他是先看排序為第幾個，才會再回頭看你所想要選的元素，例子如下

```htmlmixed=
<body>
    <div class="wrapper">
	    <div class="bg-red">row1</div>
	    <div>row2</div>
	    <div class="bg-red">row3</div>
	    <div>row4</div>
	    <div>row5</div>
    </div>   
</body>
```
```htmlmixed=
wrapper div:nth-child(2) {
	background: red;
}
```

沒選到東西，因為 nth-child(2) => 從第二個 div 回頭看，並沒有 bg-red 可選。
nth-child是從後面往前看,並且要選擇正確的標籤才會顯示


* .wrapper div:nth-child(3n){}
選到三的倍數

* .wrapper div:nth-child(2n+1){}
選到 row2 row4

(n從0開始, 這樣子的用法真的很特別！！)

## pseudo-elements 偽元素

與 pseudo-classes 差別是，它可選到一些那個元素裡面的某部分。
就是說我開F12後我可以選到標籤,但是我在html裡面是沒有的
等於說我做在css裡面了.

```htmlmixed=
<body>
	<div class="price">
		1000
	</div>
</body>
```
<mark>注意</mark>: 他是要兩個冒號
```css
.price::before {
	content: "$";
	color: yellow;
}
```
通常用於標價格時！
```css
.price::after {
	content: "$";
	color: yellow;
}
```
變成 $ 標在後面

content 裡面可以放一個 attr()

* attr() 設定屬性新名稱，它會自己去抓這個屬性的內容，然後放到 content 內。
* 自己設定的屬性，在前面加 data，與原生的屬性做個區別。
```
<body>
	<div class="price" data-id="moneybaby">
		1000
	</div>
</body>
```
```
.price::after{
	content: attr(data-id)
}
```
顯示出 1000 moneybaby

> 影片 5:30 講解 attr() + ::after 特出用法的好處
其實沒有很難拉,就是content後可以放attr,attr裡面在放入自己設定的屬性.
PS : content 裡面一定要設東西，才會有元素出現！

## CSS Selector 的權重計算方式

```htmlmixed=
<body>
	<div class="wrapper">
		<div class="list">
			<div id="pickme" class="item">
				pick me
			</div>
		</div>
	</div>
</body>
```
```css
.wrapper {
	color: red;
}
```
會繼承原則
```css
.item {
	color: blue;
}
```
變成藍色，把之前紅色蓋掉了

當兩個是一樣的東西，會以後面的為優先！
```css
.item {
	color: blue;
}
.item {
	color: green;
}
```
變成綠色
```css
#pickme {
	color: pink;
}
```
變粉色

> 大原則：
id > class > 標籤
越詳細的贏！

> 影片 4:24 講怎麼計算？



| id | class/pseduo class/attribute | tag |
| -------- | -------- | -------- |
| 0     | 0     | 0     |

* 按照順序比下來
```
// id=0, class=3 , tag=3
div.wrapper > div.list > div.item {
	color: yellow;
}

// id=1, class=0, tag=0
#pickme {
	color: pink;
}

=> 所以粉色蓋過黃色
````

**但如果優先順序一樣的話，以後面的為準。**
But，人生就是有個 BUT，上面的說法都抵不過 inline- style => 權重變成 1, 0 , 0, 0
```
<body>
	<div class="wrapper">
		<div class="list">
			<div id="pickme" class="item" style="color: orange;">
				pick me
			</div>
		</div>
	</div>
</body>
```
* 奧義： ！important
=> 權重：1, 0, 1, 0, 0
```
div.wrapper > div.list > div.item {
	color: yellow ！important;
=> 顏色就是黃色，無人能敵！
```

> 小結：
!important > inline-style > id > class > tag
如果權重一樣，則程式碼在下面的優先。

## 基本裝飾 background

> 在之前做week7 HW2時,為了要把上面的背景和下面分開.
當時container下面就直接接內容.因此特別在用一個class包住form,最後透過絕對定位往上提. 這部分也一開始沒想到,一看到別人這麼做就知道了.

`background: red;`
`background: rgb(244, 4,10);`
`background: rgba(244,40,100,0.2) => a:是透明色，0~1，淺到深。`

`background: url("./bg.jpg")`
這邊要特別注意,在同一層資料夾裡面要加上'./'

`background: url(網址) no-repeat 圖片只會顯示一張，不重複。`
`background: url(網址) no-repeat X Y Ｘ可以寫成 center/ top/ buttom Ｙ可寫成 center/ right/ left`
自己試過是不行拉
最好還是寫成 background-position:center,這樣比較保險.

```
#box1 {
	height: 300px;
	weight: 2000px;
	background: url("/.bg.jpg") no-repeat center center; 
         //no repeat 照片不會重複，只會有一張
	//圖片放置位置：center: X 與 Ｙ 軸置中
	// 若要 Ｘ Ｙ 顯示上下 / 左右 ： buttom/top   right/left
	background-size: 100px //圖片大小：px , 50%
}
```
`background-size用法：`

* 100px 100px 壓縮圖片
* 50% 50% 壓縮圖片
* content 不改變圖片比例，壓縮圖片到可以放入框框中。
* cover 將圖片填滿背景，隨著視窗大小縮放。

## 邊框 border and outline

**border 邊匡**

border 重點他是往元素裡面長,所以會改變原本的位置:+1:

border-style: dashed(虛線)／dotted(點點線)
```
＃box1 {
	border: 2px solid green;
	// border: 粗度 類型 顏色

	border-radius: 5px //弧度
 
}
```
border-radius: 50px or 50% 都是變圓形。

**outline 外匡線**
往元素外面長，加或不加，都不會影響原本元素的寬高。

>小結：
outline: 不影響元素，不會移動
border: 會影響元素，和移動位置

如何用 CSS 畫三角形？
1. 點 [codepen](https://codepen.io/norriswu/pen/BeZMMY) 看得更清楚！
2. [三角形產生器](http://apps.eky.hk/css-triangle-generator/zh-hant)

其實很多圖形都是用 border 畫的，實際開發不會用到 outline。

## 邊距 ：margin 外距 與 padding 內距

padding 內距: 
1. 距離是從內容裡面長出來的
2. 會影響寬高

margin 外距：
1. 距離是從內容往外面長的
2. 離其他的東西有多遠，不會影響寬高。

> 網頁上點“檢查”去看，移到 body 上面，有間距（瀏覽器預設）幫忙預留的空間。
解決方法？如下：
```
html, body{
	 margin: 0px;
	 //這樣會把瀏覽器預設的寬高設定不見
}
```
如果不想要整個盒子的寬度受 padding 和 border 影響，想要設定 width 和 height 時就是整個盒子包含 border 的大小，就多放這行程式碼box-sizing: border-box;。

## CSS 文字相關屬性
- color: 文字的顏色

- fornt-family: 字體

- font-size: 字體大小

- font-weight: 字體粗細 
  - normal
  - bold
  - 700/500/300

- line-height: 行高
- em (對應到字體的大小，X倍的行高)=> `之前沒有掌握到的觀念`

- letter-spacing: 字距
px(單位)

- text-align: 水平對齊
  - left
  - center
  - right

### 如何讓文字垂直置中在盒子正中間？

1. 一行字的話，可以將 line-height 設成和原本的height 一樣
2. 多行字的話，用 padding 撐開,但是整個內容高度會變成多少要自己算.

- word-break：（斷行用法,又區分成兩種功能）
  - break-all 會造成一個單字從中間截斷
  - break-word 依照單字來截斷(這好像是vscode預設的)

- white-space
   - nowrap : 字永遠在同一行(強制不換行)=>`這是第一次知道,也很想要用用看`
   - pre: 保留完整樣式，前有空格也會留著
   - pre-line: 保留換行(這也是vscode預設的)

---
## overflow 與 text-overflow
與超出寬度要怎麼處理有關

* overflow

  - hidden 超出後，把東西藏起來
  - scroll 滾動（就算沒超出區域，也可滾動）
  - auto 超出的話，有滾軸可以用

* text-overflow: 只針對文字才能用

   - ellipsis: ... 效果
   
> 想要有 abc...效果，必須先設定
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

## transition 漸變效果
可以看範例，點[這裡](https://codepen.io/norriswu/pen/WBERKW)！

>注意事項，初學者容易將 transition 放在 #box1:hover 裡面，這樣會造成滑鼠移入時有漸變效過，但移出時沒有！

:100:一開始我也不懂這是什麼概念,簡單來講漸變效果應該是要滑鼠移進去和移出來都要有相同效果,但是如果你放錯地方,只有移進去會有效果而已


## transform 變形轉換

### 讓網頁元素做出旋轉、縮放、移動等效果

* transform:
  - scale(數字) 放大 
  - rotate(180deg) 旋轉 
  - translate(Ｘ,Y) 位移(10右,-10上) 按照原本位置做偏移
  
> 如何利用 transform 垂直又水平置中？
position:absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

:+1:
其實就是一開始設定為position:absolute;
是因為要和網頁的body做定位,所以會在網頁的中間
但是這個中間又是以左上角的那個點為中心,所以還要把自己在往左上角拉.
重點就是ｙ軸剛好和一般認知是相反的
![](https://i.imgur.com/uTysv94.png)


# CSS 基礎 Part3：盒模型（box model）

## box model 盒模型

在 HTML 內，每個元素可以看成是一個小盒子，然後你可以用 CSS 來調整他們。基本組合由內而外有：內容(寬高)＋內距＋邊匡＋外距。

padding and border 是從內容往外面長得！

> 如何固定寬度？
box-sizing: border-box 好處是不用自己算寬高

box-sizing 種類：
- content-box 預設
- border-box 自己調整內容的寬高

這張圖很重要！
![盒模型](https://i.imgur.com/Enf14LD.png)

### Display的形式
1. block: （為預設值）
   代表有： div、h1、 p
   
調什麼都可以
特性為佔滿一整行

---

2. inline
   代表有：span、 a
   
調寬高沒用，調上下邊距也沒用，因為寬高會根據內容顯示。

調margin只會有左右的邊距會改變，上下不變（通常在一整段文字會被 span 括起來）

調padding，左右會變，上下不會影響元素的位置，但還是會撐開元素的高度（只有在有背景或是有border的情況下）

這個知識我本來就了解的,但是我不知道margin只會影響左右,而padding都會影響的這件事.

---
3. inline-block
等於 inline 和 block 的優點結合起來
代表有：button、 input、 select...

對外像 inline 可並排
對內像 block 可以調整各種屬性

[小陷阱:Inline-Block元素多出來的間隙](https://blog.darkthread.net/blog/inline-block-redundant-space/)

4. none 不顯示

## CSS 基礎 Part4：定位（position）

position：
基本：上下左右

<mark>下距增加會往上跑
左距增加會往右跑</mark>

> 這短短兩句話,讓我記得當年11月小弟我還在剛學css的時候搞了一個小時
還天真的以為自己會這些東西是不是能夠轉職了...

* static:
網頁預設定位方式。
按照瀏覽器的預設自動排列，無法調整偏移（不受上下左右值的影響）。

* relative 相對定位。
相對於原本參考點做定位，可以調整上下左右讓其偏移，但不會影響到其他元素所在的位置，只會改變自己的。

* absolute 絕對定位
針對某個參考點（往上找第一個不是stastic的元素）進行定位。如果前面無設定，會以 body 為主要參考點！

> 注意 5:25 分處 講遞補上來的概念！
因為絕對定位後，會脫離正常的排版流程走，有點像是被抽出去，所以下面一個元素會遞補上來被抽走的位置。
這個觀念,其實想想自己平常排版的時候有遇到,就是下面的東西會被叫上來..但是今天有人講我才知道..

* fixed: 固定定位
簡單版 - 相對於瀏覽器的窗口做定位
困難版 - 相對於viewport做定位
捲動時，視窗固定會出現在同個位置。

## z-index 決定圖層順序
決定哪個元素的順序。
**順序越大就在越前面～**

<style>
    .box:nth-child(2) {
        background: red;
        top: 40px;
        z-index: 10;
    }
</style>


## position: sticky 較新的屬性
當他離 top: 20px 的時候，就會固定在那
像是導覽列會固定在上方，不會隨著文章移動，而看不見。

參考可看[這裡！](https://codepen.io/zuppachu/pen/ReNZdN)

<style>
    .box:nth-child(2) {
        background: red;
        top: 40px;
        position: sticky;  //當盒子滾到離top 40px 的時候，就會黏住不動
        z-index: 10;
    }
</style>


---


## CSS技巧整理

### element整體往上移動
#### 方法1:

設定 top & left 來改變位置

```css
div{
    position:relative
    top:-40px;
}
```
#### *產生問題*：
會保留他原本應該存在的空間，導致下面留空


### 方法2:+1:
這個方法可以讓element裡面的元素也跟著移動,==需最外面的div才可使用==

```css
div{
    margin-top:-40px;
}
```

## **置中方法**
### 文字類型

==width:100%==
```css
div{
	width:100%;
	text-align:center;
}
```
### 區塊類型

實務應用
1. css要下在要改變的那一個class(text1),不是下在height
2. margin-left的做法要下在section2,不是下在height

```html
 <div class="section2">
	<div class="height">
	 <input type="text" value="請輸入身高" class="text1">
      </div>
    	<div class="weight">
          <input type="text" value="請輸入體重" class="text2">
   	</div>
</div>
```
```css
text1{
	left:50%;
	transform:translateX(-50%);
}
```
```css
.section2{
    margin-top:-220px;
}
```

### container置中方式
```css
div{
	margin: 0 auto;
	height:auto;
	display:block;
}
```

### div 置中的方法,這一個需要在想一想 我先提供初步試驗的結果
```htmlmixed=
    <div class="outter">
        <div class="inner">
            <div class="title">
                化繁為簡
            </div>
        </div>
    </div>
```
```css
        .outter{
            margin:  0 auto;
            width: 1200px; 
            border: 1px solid;
        } 
        .inner{
            margin:  0 auto;
            width: 800px; 
            border: 1px solid;
        }
        .title{
            padding: 10px 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }

```

注意要對置中的那個東西下css條件,並且千萬不要設定高度


### 圖型裡面的置中方法
1. text-align:center
2. line-height:xxx(設定和圓圈直徑一樣)

> codepen
> https://codepen.io/norriswu/pen/XGdKMj

### clearfix
這件事情其實很常見,簡單來說就是在子元素下面新增float屬性
例如我要做一個三欄式的版型,而造成父元素高度不見了
依據我學習的最好的方法,是在父元素加入cleafix屬性

屬性設定
```css
.clearfix:after {
    content: '';
    display: block;
    clear: both;
}
```

舉例如下:
在父元素加上的原因是因為after,而after放在最後透過屬性,可以清除浮動
```htmlmixed=
<div class="container clearfix">
  <div class="col-3"></div>
  <div class="col-3"></div>
  <div class="col-3"></div>
</div>
```

![F12後的結果會看的更清楚](https://i.imgur.com/70D5Vew.png)

> [延伸閱讀](https://blog.chibc.net/learning/uibeginner-daily/890)


## SASS安裝

怕自己忘記, 所以直接把連結附在這邊, 不是很難拉, 忘記再回來看就好
還是稍微記錄下好了

- 直接新增scss檔
- vscode有安裝好live scss, 他會自動幫你compile. 
- 底下是watch sass就可以了

[Link](https://www.youtube.com/watch?v=lGUNWBP2p8U)

反正忘記了看下就好了, 不是什麼特別重要的.