การทำให้ Element สูงเท่ากับ Viewport (100vh) ใช้สร้าง Full-screen Sections, Hero Areas, หรือ Sticky Sidebar ตัวอย่างนี้แสดง 2 วิธี: height: 100vh บน html/body และ Flexbox Layout
Syntax
selector {
height: 100vh; /* 100% Viewport Height */
/* หรือ */
min-height: 100vh; /* สูงสุด 100vh แต่ขยายได้ถ้าเนื้อหามากกว่า */
}
Viewport Units
| Unit | ความหมาย | เทียบเท่า |
|---|---|---|
vh | Viewport Height | 1vh = 1% ของความสูง Viewport |
vw | Viewport Width | 1vw = 1% ของความกว้าง Viewport |
vmin | Min(vw, vh) | ด้านที่สั้นกว่า |
vmax | Max(vw, vh) | ด้านที่ยาวกว่า |
dvh | Dynamic Viewport Height (New) | ไม่นับ Browser UI (Address Bar) |
svh | Small Viewport Height | ตอน UI เปิดเต็มที่ |
lvh | Large Viewport Height | ตอน UI ซ่อนหมด |
ตัวอย่างที่ 1: Basic 100vh
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
html, body {
margin: 0px;
height: 100vh;
}
div {
height: 100%;
text-align: center;
background: mistyrose;
}
</style>
</head>
<body>
<div>100% height!!</div>
</body>
</html>
จุดสำคัญ
html, body { height: 100vh; margin: 0; }- ต้องตั้งค่าทั้ง html และ body- Child ใช้
height: 100%จะสืบทอดจาก Parent (body) - หากเนื้อหามากกว่าจอ จะเกิด Overflow (ใช้
min-height: 100vhแทน)
ตัวอย่างที่ 2: Flexbox Multiple Full-height Columns
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
html, body {
display: flex;
flex-direction: row;
justify-content: space-around;
margin: 0px;
height: 100vh;
box-shadow: inset 0 0 40px lightblue;
}
div {
width: 40%;
height: 100vh;
text-align: center;
box-shadow: inset 0 0 20px lightcoral;
}
</style>
</head>
<body>
<div>Watch This!</div>
<div>Let Me Show You How The Boss Does It!!</div>
<div>Open Up The Sky!!</div>
<div>GO! GO! GO!!</div>
</body>
</html>
วิเคราะห์
- Body เป็น Flex Container:
display: flex; height: 100vh - Children (div) กว้าง 40% แต่ละอัน สูง 100vh
justify-content: space-around- จัดกระจายพื้นที่ว่าง- เหมาะสำหรับ Split-screen Layout, Dashboard Panels
ปัญหาที่พบบ่อยกับ 100vh และวิธีแก้
1. Mobile Browser Address Bar (Chrome Mobile, Safari iOS)
100vh รวม Address Bar ด้วย → เนื้อหาล่างทับ Address Bar
/* ใช้ Dynamic Viewport Units (Modern) */
height: 100dvh; /* Dynamic - ปรับตาม UI */
/* Fallback สำหรับ Browser เก่า */
height: 100vh;
@supports (height: 100dvh) {
height: 100dvh;
}
/* หรือ JavaScript Fallback */
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
window.addEventListener('resize', () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
});
/* ใช้: height: calc(100 * var(--vh)) */
2. Scrollbar เนื้อหายาวเกิน
.full-height {
min-height: 100vh; /* ขยายได้ถ้าเนื้อหามากกว่า */
/* หรือ */
height: auto;
min-height: 100vh;
}
3. Nested Flexbox Height Collapse
.parent {
display: flex;
flex-direction: column;
height: 100vh;
}
.child {
flex: 1;
min-height: 0; /* Critical! */
overflow: auto;
}
Modern Layout Patterns
Holy Grail Layout (Header + Sidebar + Main + Footer)
.page {
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-columns: 250px 1fr;
min-height: 100vh;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; overflow: auto; }
footer { grid-area: footer; }
Sticky Sidebar
.sidebar {
height: 100vh;
position: sticky;
top: 0;
overflow-y: auto;
}
Best Practices
- ใช้
min-height: 100vhแทนheight: 100vhส่วนใหญ่ - ใช้
100dvh(Dynamic) สำหรับ Mobile-First Projects - รวมกับ
box-sizing: border-boxทุก Element - ทดสอบบน Mobile จริง (Address Bar Behavior)
- หลีกเลี่ยง Nested 100vh หลายชั้น (Infinite Height Loop)