[討論] U120, 左方區塊的溢出問題, overflow的工作原理

Lastor
Code 隨筆放置場
4 min readAug 14, 2019

課文中精華討論, 蠻有趣的。
我這邊也試著分別用Chrome & Firefox開測試用的CodePen
顯示結果確實是Chrome會爆版, Firefox也會, 只是Firefox的爆炸方式跟Chrome不一樣。
我另外做一個比較清楚的爆炸示意圖↓

父層包裹的 .row 設定了實高200px, 但子層的文字 .col 區塊一樣噴了出去。
overflow沒有如預期工作。

舊版本的Chrome我不是很清楚, 那時候還沒開始學做Web……XD||
但現版本的Chrome渲染方式, 之前有稍微研究了一下。
我想最主要的原因是在於Chrome的當前版本, overflow 只能作用在「有實高」的box。

這個case的結構大概長這樣, 全部層級都沒有被定義明確的實體高。

<body>  // min-height: 100vh; 不屬於明確的實體高度
<div class="container">
<div class="row"> // max-height: 600px; 不屬於明確的實體高度
<div class="col"> #Text </div> // overflow下的位置
</div>
</div>
</body>

當 display 屬於 block 時, 如果沒有清楚給定 height, 高的部分就會預設為 auto。
auto 的工作方式是, 依照內容高。
例如, 裡面塞了張 height 100px 的圖片, 父層就會把 height 參照到子層上, 變成 100px。

為何會說參照? 因為他實際上並沒有真實產生高度。
可以做一個簡單的實驗, 證實這件事。

// HTML
<div class="container"> // 不設高
<div class="fake-img-box"></div> // height: 100px;
<div class="other"></div> // height: 100%; 讓他繼承 .container
</div>
// CSS
.container {
border: 1px solid; // 給一個黑框, 辨識用
}
.fake-img-box {
height: 100px;
}
.other {
height: 100%;
border: 1px solid red; // 給一個紅框, 辨識用
}

結果如下圖, 黑框為父層 .container 他參照了子層 .fake-img-box 的 height 100px。
另一個子層 .other 給定 height 100% 讓他完全繼承父高。
透過 .other 可以發現, 實質上父層的 .container 高仍然是空的, 所以 .other 繼承不到。

拉回原本的case, 因為overflow在現在的Chrome中, 僅能作用在擁有實體高的box裡。
推測, 必須透過實體高, 明確規範出當前box的範圍, overflow才能工作。

而這個點餐app, 左側這一塊 .col-md-4 的高, 是參照到內容, 他本身的box是沒有高的。

所以邏輯上, 就有兩個方法解決這個問題:
1. 直接給上實體高 (這個case, 我們給在父層會比較好些)

.row {
height: 600px; // 直接換成實體高
}
.col-md-4 {
overflow-y: auto;
height: 100%; // 讓子層去繼承他
}

但這樣顯然是不理想的, 因為高被固定住了, 不符合RWD原則。

2. 給子層下限制, 規範出 max-height

.row {
max-height: 600px;
}
.col-md-4 {
overflow-y: auto;
max-height: 580px; // 給上限制, 規範它
}

前面提出了假設, overflow無法工作於沒有實體高的box上。
min/max 的設定, 實質上也無法給出實體高, 那為何可以工作呢?

這應該是因為, 給實體高的方式, 等價於「規範了一個明確範圍」
而「參照內容高 + max設限」同樣也是「規範了一個明確範圍」
於是, overflow可以如預期工作。

--

--

Lastor
Code 隨筆放置場

Web Frontend / 3D Modeling / Game and Animation. 設計本科生,前遊戲業 3D Artist,專擅日本動畫與遊戲相關領域。現在轉職為前端工程師,以專業遊戲美術的角度涉足 Web 前端開發。