# 四、\[前端] CSS

CSS 主要是來管外觀的部份

範例

```css
p {
    margin: 10px;
    font-size: 16px;
    color: #ccc;
}

選擇器 {
    屬性: 值;
}
```

## CSS 選擇器(selector)

再舉例

```css
/*所有 p 標籤的背景都會變藍色*/
p {
    baceground-color: blue;
}

/* id 為 target 元素的文字大小變成 32px */
#target {
    font-size: 32px;
}

/* class 為 container 元素的外距會自動調整，產生置中效果 */
.container {
    margin: 0 auto; // 置中
}
```

如果直接選不夠的話，需要設立條件縮小範圍

```css
/* 從 header 底下找 li，不管幾層都可以，子孫有就行 */
#header li {
    backgournd-color: #ccc;
}

/* 只有 nav 的下一層的 ul，只有底下一層的孩子 */
#nav > ul {
    padding: 4px 12px;
}

/* li.active 代表既是 li 又有 .active 的元素
 ~ 用來連接目標與後面同一層的元素，只要是在 li.active 之後的 li，都會套用設定 */
li.active ~ li {
    font-weight: bold;
}

/* 只有目標後面的正後面的元素才會套用設定，就是 li.active 正後面的 liv 才會套用設定 */
li.active + li {
    color: green;
}
```

常見的 CSS selector

* 基本
  * `p` 基本標籤 tag
  * `#target` id&#x20;
  * `.container` class name
* 篩選條件
  * `div.container` 所有帶有 .container 的 div
  * `#header li` #header 底下所有的 li 子孫
  * `#header > ul` #header 下一層的 ul 兒子
  * `.active ~ li` .active 後的同一層的所有 li
  * `.active + li` .active 後的第一個 li

## 常見的 CSS 屬性

知道了選擇器，可以找到目標後，接下來學習怎麼改外觀。首先要了解 box model

box model 由外而內包含

* margin，外距，自己與其他元素的距離
* border，邊框，自己的邊框
* padding，內距，留白，content 到 border 的距離
* width / height，內容自己的長與寬

```css
.block {
    /* 外距和內距，有上下左右屬性 */
    margin-right: 10px;
    margin-bottom: 10px;
    padding: 20px;

    /* 邊框 */
    border-width: 2px; /* 寬度 */
    border-style: solid; /* 長相 */
    border-color: black; /* 顏色 */
    border: 2px solid black; /* 簡寫   */
}
```

接下來談 position，位置。它不是直接調整座標 (x,y) 位置，而是用來設定元素位置的根據點的屬性。例如

* static。自然的文章流動，由上而下由左至右，是預設值。它不能調整位置
* relative。可以調整位置的 static。一樣有自然文章流動，但可以調整位置
* absolute。設定特別。會有起始點，根據最早有設定 position 的祖先當作基準點
* fixed。起始點就是網頁整個可見的範圍

接下來談 float，就是文繞圖的概念。

* float
  * 值有 left, right
* clear
  * 值有 left, right, both

float 常被用在排版上面。float: left 的主要內容可以設定 width: 80%，float: right 的側邊欄可以設定 width: 20%，這樣排版就會正常。

只是使用完 float 後，要清除 float，不然網頁下方的 footer 會往上跑。這屬性叫 clear。`clear: both`

範例

```markup
<!-- html -->

<div id="content">
    <div id="article">
        Lorem
    </div>
    <div id="sidebar">
        Lorem
    </div>

    <div class="clearfix"></div>
</div>

<div id="footer">
    footer is here
    <p>
        Lorem
    </p>
</div>
```

```css
#content {
    position: relative; /* 文字自然流動，但能調整大小與位置 */
    float: left; /* 文字靠左流動 */
    width: 80%; /* 內容寬度佔父親寬度的 80% */
}

#sidebar {
    position: relative;
    float: right;
    width: 20%
}

.clearfix {
    clear: both;
}
```

小結

* box model
* position
* float / clear
* [基礎 CSS 教學！不再擔心記不住，一次掌握 CSS 常用屬性 / 網頁基礎 15 天 - Blog](https://www.everyonecanwebsite.com/blog/post/common-css-attributes)

### 常見的 CSS 設定補充

* 比較大的架構
  * display
    * block, inline, none, flex
    * [Flexbox basic - YouTube](https://www.youtube.com/watch?v=epHSeA7OCZU\&t=324s)
      * System
      * CSS properties
      * Playground
      * Practice
      * Can I use?&#x20;
  * position
    * static, relative, absolute, fixed
    * 搭配 top / right / bottom/ top 調整位置
  * float & clear
    * float: left, right
    * clear: left, right, both
* 比較小的細節
  * box-model
    * 很多屬性的總稱
    * margin, border, padding, width / height
    * block 元素才有 box model；inline 元素就沒有
  * background
    * background-color, background-image, background
  * text
    * text-align
    * line-height
  * font
    * font-size, font-weight, color 文字顏色, font-family
  * Others
    * overflow 當內容超出容器，怎麼顯示
    * list-style-type li 點的樣式
    * text-decoration 底線 underline、刪除線 line-through
    * ...

[Flexbox basic - YouTube](https://www.youtube.com/watch?v=epHSeA7OCZU\&t=324s)

* System
  * 在自己設定 display: flex 後，自己變成 flex container，子元素變成 flex item
  * flex lines 基準線會被 flex item Follow
  * Main axis and Cross axis 水平軸線與垂直軸線
  * Main start / Main end, Cross start / Cross end
  * 這個系統可以調整的東西：方向、對齊方式、寬度設定
* CSS properties
  * Flex container
    * Flex container About axis
      * flex-direction
        * 定義 main axis 的走向
        * 預設值 `flex-direction: row` 由左置右
        * 設定值 `row, row-reverse, column, column-reverse`
      * justify-content
        * flex items 如何對齊 main axis
        * 預設值 `justify-content: flex-start`
        * 設定值 `flex-start, flex-end, center, space-between, space-around`
      * align-items
        * flex items 如何對齊 cross axis
        * 預設值 `align-items: flex-start`
        * 設定值 `` `flex-start, flex-end, center, stretch(延展開來), baseline(看 flex item 裡文字的底線) ``
    * Flex container About wrap 包覆的方式
      * flex-wrap
        * flex item 超過 container 的話，該怎麼做
        * 預設值 `flex-wrap: nowrap` 雖然不會超出去，但 item 也不會換行，就在同一行硬塞
        * 設定值 `nowrap, wrap, wrap-reverse`
      * align-content
        * 在 wrap 之後，會多很多行 flex lines
        * flex lines 如何對齊在 cross axis&#x20;
        * 有多行，就會有多條 flex lines
        * 預設值 `align-content: flex-start`
        * 設定值 `flex-start, flex-end...` 好多  ==
  * Flex items
    * Flex
      * 容易跟 display: flex 搞混
      * 預設值 `flex: 0 1 auto`
      * flex: `flex-grow flex-shrink flex-basis;`
      * flex-grow
        * flex container 還有多的空間時，要不要自動成長，閒置空間要怎麼分
      * flex-shrink
        * 當 flex-items overflow 時，item 要不要縮
        * 預設值 `flex-shrink: 1`，會縮
      * Flex-basis
        * 類似寬度的設定
        * 預設值 `flex-basis: auto`，可用 px 設定寬度
    * Order
      * 在 RWD 操作方便，可以控制呈現順序
      * 假設畫面上有 .sidebar.A .content .sidebar.B 區塊
      * 在手機上想先呈現 .content，再呈現 .sidebar.A .sidebar.B
      * ```css
        .main {
            display: flex;    /* 把自己變成 flex container */
            flex-wrap: wrap;  /* flex item 寬度超過 container 的話，就硬塞 */
        }

        .content {
            order: 1;
        }

        .sidebar.A {
            order: 2;
        }

        .sidebar.B {
            order: 3;
        }

        @media screen and (min-width: 600px) {

            .sidebar {
                flex: 0 0 200px;
            }

            .content {
                flex: 1;
                order: 2;
            }

            .sidebar.A {
                order: 1;
            }

            .sidebar.B {
                order: 3;
            }
        }
        ```
    * Margin
      * 在 flex 裡更 powerful，上下的 margin 可以 auto，可以實現垂直置中
    * align-self
      * 單獨一個 flex item 對齊 cross axis
      * 如果有機車設計師要單獨一個 item 位置不一樣，就用這個
      * ```css
        .product:nth-child(3) {
            align-self: flex-end;
        }
        ```
* Playground
  * [Visual Guide to CSS3 Flexbox: Flexbox Playground |](https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/)
  * [Flexy Boxes — CSS flexbox playground and code generation tool](http://the-echoplex.net/flexyboxes/?fixed-height=on\&display=flex\&flex-direction=row\&flex-wrap=nowrap\&justify-content=flex-start\&align-items=flex-start\&align-content=stretch\&order%5B%5D=0\&flex-grow%5B%5D=0\&flex-shrink%5B%5D=1\&flex-basis%5B%5D=auto\&align-self%5B%5D=auto\&order%5B%5D=0\&flex-grow%5B%5D=0\&flex-shrink%5B%5D=1\&flex-basis%5B%5D=auto\&align-self%5B%5D=auto\&order%5B%5D=0\&flex-grow%5B%5D=0\&flex-shrink%5B%5D=1\&flex-basis%5B%5D=auto\&align-self%5B%5D=auto)
  * [CodePen - Flexbox playground](https://codepen.io/enxaneta/full/adLPwv)
  * [Flexbox Playground](http://flexboxplayground.catchmyfame.com/)
* Practice
  * Grid
    * 像 bootstrape 把 column 12 等分
    * ```css
      * {
          box-sizing: border-box; /* 不知道什麼用途 */
      }

      .container {
          width: 800px;
          margin 0 auto;
      }

      .product-list{
          display: flex;    /* 只用這個排版就好了，好棒棒 XD */
          /* flex-wrap: wrap;  想換行的話 */
          width: 800px;
      }

      .product {
          /* flex: 0 1 auto; */
          margin-bottom: 30px;
          padding: 0 15px;
      }

      .product img {
          width: 100px;
          height: auto;
      }
      ```
    * 發現好用的示意圖工具，placehold.it
      * <http://placehold.it/400x300>
  * Sticky footer
    * 剛做網站，內容很少，footer 沒被擠下去，就跑上來了
    * ```css
      #main {
          display: flex;
          fles-direction: column;    /* 排版由上至下，#header, #content, #footer */
          height: 100vh;
      }

      #header {
          background-color: #ccc;
          line-height: 2;
      }

      #content {
          flex: 1; /* 跟 #content 要自動 flex grow，把多的空間拿來使用 */
      }

      #footer {
          padding: 30px;
          background-color: #333;
          text-align: center;
          color: white;
      }
      ```
  * More
    * webflow
    * <https://flexbox.webflow.com/#examples>
* Can I use?
  * 2012 年後規範穩定
  * <https://caniuse.com/#search=flexbox>

## \[練習] 版面置中

試作的 Codepen

* <https://codepen.io/pen/?editors=1100>

html

```markup
<div class="container">
  <h1>Lorem ipsum dolor sit amet.</h1>
  <p>
    Lorem ipsum dolor sit, amet consectetur adipisicing elit. Impedit repudiandae beatae, optio enim non distinctio perspiciatis a modi fugiat saepe!
  </p>
  <img src="http://placehold.it/400x300" alt="px示意圖">
</div>
```

css

```css
.container1 {
  width: 60%;
  margin: 0 auto; /*版面置中*/
  padding: 20px;

  background-color: pink;
  text-align: center; /*把文字置中*/
  color: white;
}
```

## \[練習] 3 欄式架構

試作的 Codepen

* <https://codepen.io/ayugioh2003/pen/PRJrBJ>
* emmet 展開功能
* [Can VS Code Do Emmet? | CSS-Tricks](https://css-tricks.com/can-vs-code-emmet/)
* [Cheat Sheet](https://docs.emmet.io/cheat-sheet/)
* [(29) Using Emmet in Visual Studio Code - YouTube](https://www.youtube.com/watch?v=DvN5B8rQpIw)
* [Emmet Documentation](https://docs.emmet.io/)

html

```markup
<h1>3 欄式架構</h1>
<div class="container2">
  <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
    <div class="work">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis dignissimos exercitationem accusantium aliquid officiis debitis quos velit dolorem error sint!
  </div>
  <div class="clearfix"></div>
</div>
<p>記得要 clearfix 避免版面壞掉</p>
```

css

```css
.container2 {
  position: relative; /*讓 float 有依據*/
  width: 660px;
  margin: 0 auto; /*置中*/
}

.work {
  float: left; /*讓內容浮動*/
  background-color: pink;
  margin: 5px;
  padding: 5px;
  width: 200px;
  height: 220px; /*如果內容不一樣高，可能會塌陷*/
}

.clearfix {
  clear: both;
}
```

## 控制寬度的魔法：box-sizing

試作的 Codepen

* <https://codepen.io/pen/?editors=1100>

width 只會計算 content 的寬度，padding, content 要另外加總；於是就有了 box-sizing 魔法

box-sizing 有兩個值

* content box (default)
* border box

html

```markup
<h1>用box-sizing控制寬度</h1>
<div class="container3">
  <div class="work1">
    <div>
      width 很單純 <br>
      只設定內容的 width 而已
      其他另算

    </div>
  </div>
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>  
    <div class="work1">
    <div>
      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Soluta quas totam modi numquam quam nihil cupiditate molestiae voluptates iusto ipsam.
    </div>
  </div>
  <div class="clearfix"></div>
  <p>要記得 clearfix</p>
</div>
```

css

```css
.clearfix {
  clear: both;
}

.container3 {
  width: 600px;
  margin: 0 auto;
  position: relative;
}

.work1 {
  box-sizing: border-box;
  padding: 0 5px;
  width: 33.3%;
  height: 220px;
  float: left;
}

.work1 > div {
  background-color: pink;
}
```
