筆記、[FE101] 前端基礎 盒模型與定位


Posted by s103071049 on 2021-05-21

盒模型

一、Box model 盒模型

在 html 裡面的每個元素,都可以看做是一個盒子。我們可以用 css 調整盒子的屬性。它會有幾個東西組成,寬度/高度、內邊距(padding)、框線(border)、外邊距(margin)。

留意點 : 它的寬高和你想的不一樣。寬、高是指內容的寬跟高,padding、border 是往外面長。

border : 5px solid black => 寬 = 200 + 5 + 5 = 210 同理,高 = 110

#box1 {

  width: 200px;
  height:100px;

  text-align:center;
  line-height: 100px;
  color:white;
  background:orange;
  border:5px solid black;
}

同理,padding => (寬, 高) = (220, 120)

#box1 {

  width: 200px;
  height:100px;

  text-align:center;
  line-height: 100px;
  color:white;
  background:orange;
  border:5px solid black;
  padding:5px;
}

每次計算寬、高超麻煩,為了解決這個問題,可以使用 box-sizing,來決定用甚麼模式顯示。

  • content-box 的寬、高,是 content 的寬、高
  • border-box => 會將 padding、border 納入 ,也就是電腦會將 padding、border 都考慮進來,自動調整內容的寬高。

二、斯斯有三種:display 的三種形式:block、inline 與 inline-block

重要度 : 五顆星
display 最常用的三種型式 : block、inline 與 inline-block

(一)、block => 調甚麼都可以

block特點

  1. 預設元素 : div, h1, p
  2. 每個元素佔一行,也就是自己佔滿整行,不會將下方東西遞補上去

以下為預先準備好的檔案,我們可以在 dev-tool 右下 user agent stylesheet 檢視它的預設值。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
</body>
</html>
.box {
    background: orange;
    width: 100px;
    height: 100px;
    margin: 10px;
}

(二)、inline => 調寬高無用、調上下邊距也無用

回憶 box model
inline特點

  1. 預設元素 : span, a
  2. 調 margin => 左右邊距改變,但上下邊距不變。可以想像,一整段文字用 span 括起來想做一些效果,例如 : 加點背景顏色,或做些文字特效。故,動上下整段會有點奇怪
  3. 調 padding => 左右 padding 會變(因為跟其它元素距離有變);調上下padding時,元素位置沒有動但背景有影響。特別留意,對 inline 元素用 padding 上下是有作用的,只是不會影響到它的位置。所以調上下邊距也無用,是指它不會影響元素位置,但它仍會把元素的高度給撐開。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <span class="box">box1</span>
  <span class="box">box2</span>
  <span class="box">box3</span>
</body>

重點整理
margin、padding 對 inline 元素上下沒用,左右才有用。有用無用是指它會否影響到其它元素。 note the vertical padding and border are still applied.

padding 是有作用的,只是不會影響其它元素。

(三)、inline-block => 對外同 inline 可併排、對內同 block 可調整各屬性

  1. 預設元素 : button, input, select
  2. 比較 : block 與 inline-block,差別在 inline-block 可以併排,一行內可放多個元素。如果是 block 一行內只能放一個元素。
  3. inline-block 空格會造成元素間的間隙
.box {
    background: orange;
    width: 100px;
    height: 100px;
    margin: 10px;
    display: inline-block; 
}

inline-block 併排時的小陷阱

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
</body>
</html>
.box {
    background: orange;
    width: 100px;
    height: 100px;
    margin: 10px;
    border:5px solid black;
    display: inline-block; 

}

我將 margin 刪掉,還是會有空格 ? 打開 devtool => margin=0

因為你在 html 元素 div 有空格,解決辦法 :

<body>
  <div class="box">
  box1</div><div class="box">
  box2</div><div class="box">
  box3
  </div>
</body>

不是 bug,因為有空格 render 出來。有很多解決方法,也可以透過加註解。

<body>
  <div class="box">
  box1
  </div><!--
--><div class="box">
  box2
  </div><!--
--><div class="box">
  box3
  </div>
</body>

定位 (position)

前言 : 排版時要將元素放到該放的位置,這時就需要不同的定位方法進行輔助。

最好理解的兩種:static 與 relative

(一)、static => 網頁預設的排版方式

按照順序畫(排)下去。因為 body 本身有 margin,所以它會從 margin 完的點開始畫。所以我們才先把 body 的 margin 給塗掉。

body {
    margin:0;
}

.box {
    background: orange;
    width: 100px;
    height: 100px;
    margin: 10px;

}

(二)、relative => 相對定位

依據原本的定位點,上下左右調整,但它不會影響到其它元素。

.box:nth-child(2) {
    position:relative;
    top:-20px;
    left:30px;
}

沒那麼難理解的 absolute 與 fixed

(三)、absolute => 絕對定位

絕對定位是針對某個參考點進行定位,所以絕對定位需要有某個參考點

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">
    <div class='box-inner'>
        x
    </div>
  </div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>
</html>
body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;

}

現在,想將 box inner 的元素,相較於 box 移動到右上角,但用 relative 定位定不到這個位置。

發現它絕對定位點定位到相對於 body (top:10px;right:10px) 的位置。

.box-inner {
    position: absolute;
    top:10px;
    right:10px;
}

所以如果想針對這個盒子做定位,需要將它的 position 設為 relative。

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;

}
.box-inner {
    position: absolute;
    top:10px;
    right:10px;
}

絕對定位是針對某個參考點進行定位,某個參考點是指往上找,找到第一個不是 static 的元素。依照範例,往上找,找到第一個不是 static 的元素是第二個 box,這個 box 是相對定位,我們可以用它做定位。所以,這也是為甚麼如果我們沒有設定,它會用 body 做定位。

如果原本的下面還有東西,例如:

<body>
  <div class="box">box1</div>
  <div class="box">
    <div class='box-inner'>
        x
    </div>
    <div>
        你吵死了~
    </div>
  </div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>

使用絕對定位,原本元素會從正常排版流程被抽掉,下一個元素會被遞補上來。所以 " x " 會跑到盒子的右上角," 你吵死了 " 會被遞補上來。

如果現在將 position: absolute 拿掉,元素就會按照正常的排版流程排下來。

body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;
}
.box-inner {

    top:10px;
    right:10px;
}

如果今天針對 x 做一些變化:
如果是相對定位," 你吵死了~ " 位置不會改變。

body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;
}
.box-inner {

    top:10px;
    right:10px;
    position:relative;
}

如果用 absolute 就會拖離正常的排版流程。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box" style="position: absolute; right:10px; top:10px">
    <div class="box-inner">
        x
    </div>
    <div>
        123
    </div>
  </div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>
</html>
body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;
}
.box-inner {

    top:10px;
    right:10px;
    position:absolute;

}

比較 : 絕對定位是針對某個參考點進行定位、相對定位是針對排版點進行定位

(四)、fixed => 固定定位

相較於瀏覽器這個窗口做定位,也就是畫面上看到的,依據瀏覽器的位置做定位。準確地說,固定定位是相較於viewport做定位。可以先將 viewport 想成瀏覽器,你看的到的地方。

可以將 width:5000px 調整,不管怎麼滾還是在同一個位置。

body {
    margin:0;
}

.box {
    background: orange;
    width:5000px;
    height: 100px;
    margin: 10px;
    display: block;

}

.box:first-child{
    position:fixed;
    width:100px;
    background: red;
    right:0px;
    bottom:100px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>
</html>

決定圖層順序:z-index

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>
</html>
body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;
}
.box:nth-child(2) {
  background: red;

}

現在,將 top:-30px 則 box2 蓋到 box1 身上;若將 top:30px 則 box2 被 box3 覆蓋。因為 box3 在 box2 的前面,所以會將 box2 給蓋掉。

.box:nth-child(2) {
  background: red;
  top:30px;
}

若想將 box2 顯示在 box3 前面:調 z-index。只要比 box3 預設值大就行,理論上應該調任何正數都是沒有問題的。z-index 數字越大會在越前面,會將後面東西蓋掉。

.box:nth-child(2) {
  background: red;
  top:30px;
  z-index:1;
}

比較潮的 sticky

sticky 是 position 裡面較新的屬性,所以並不是每個瀏覽器都支援,但基本上較現代的瀏覽器 chrome, firefox 裡面都有支援這個 position。

sticky 和它的名字一樣,是一個會黏住的元素。

範例:當這個元素,還沒達到 top:0px 時,它和正常元素一樣,和用預設值排版的狀態相同。差別在當你滾動,達到 top:0px 時,它就被黏到那個地方。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="urf-8"> 
    <title>i am title</title>
    <link rel="stylesheet" href="./style.css"/>
  </head>
<body>
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
  <div class="box">box4</div>
  <div class="box">box5</div>
  <div class="box">box6</div>
</body>
</html>
body {
    margin:0;
}

.box {
    background: orange;
    width:300px;
    height: 100px;
    margin: 10px;
    display: block;
    position:relative;
}
.box:nth-child(2) {
  background: red;
  top:50px;
  position: sticky;
  z-index: 1;
}

有點像是,平常沒有到設定位置狀態為 static ,一旦到了設定的位置狀態就變為 fix

sticky 實際應用:手機通訊錄,滑到 A 開頭顯示 A、滑到 B 開頭顯示 B ; 或者是網站的導覽列往下滑時會黏在上面。


#css







Related Posts

[ 學習筆記系列 ] 網頁本質 (一) - HTML 篇

[ 學習筆記系列 ] 網頁本質 (一) - HTML 篇

CSS BEM命名

CSS BEM命名

蔡比八寫後端(6) - TypeORM entity & column

蔡比八寫後端(6) - TypeORM entity & column


Comments