Article · programming
HTML & CSS EP4: Box Model — เข้าใจพื้นที่ของ Element และจัด Layout ให้แม่นยำ
HTML & CSS
เรียนรู้ CSS Box Model ตั้งแต่ content, padding, border, margin ไปจนถึง box-sizing พร้อมตัวอย่างและหน้าเว็บ HTML ที่ทดลองใช้งานได้จริง
CSS Box Model คืออะไร
เมื่อเราเริ่มสร้างเว็บไซต์ เราอาจคิดว่า element แต่ละตัวมีขนาดเท่ากับพื้นที่ที่กำหนดไว้ เช่น ตั้ง width เป็น 300px ก็น่าจะได้กล่องกว้าง 300px เสมอ แต่ใน CSS ยังมีพื้นที่ด้านใน เส้นขอบ และระยะห่างด้านนอกเข้ามาเกี่ยวข้องด้วย แนวคิดที่ใช้อธิบายพื้นที่เหล่านี้เรียกว่า CSS Box Model
ทุก element ที่แสดงผลเป็นกล่องสามารถอธิบายด้วยส่วนสำคัญ 4 ชั้น ได้แก่ content, padding, border และ margin การเข้าใจความสัมพันธ์ระหว่างส่วนเหล่านี้ช่วยให้เราควบคุมขนาด การเว้นระยะ และตำแหน่งขององค์ประกอบบนหน้าเว็บได้แม่นยำขึ้น
1. ส่วนประกอบทั้ง 4 ของ Box Model
Content — พื้นที่เนื้อหา
Content คือพื้นที่สำหรับแสดงเนื้อหาของ element เช่น ข้อความ รูปภาพ หรือ element ลูก หากกำหนด width และ height โดยใช้ค่าเริ่มต้นของ box-sizing ซึ่งก็คือ content-box ขนาดที่ระบุจะหมายถึงขนาดของพื้นที่ content เป็นหลัก ยังไม่รวม padding และ border
กำหนดขนาดพื้นที่ Content
.card {
width: 300px;
height: 150px;
}
ตัวอย่างนี้กำหนดพื้นที่ content กว้าง 300px และสูง 150px หากเพิ่ม padding หรือ border ขนาดกล่องที่มองเห็นจริงอาจใหญ่กว่าค่าที่กำหนดไว้
Padding — พื้นที่ด้านใน
Padding คือพื้นที่ระหว่าง content กับ border ใช้เพิ่มระยะห่างระหว่างเนื้อหากับขอบกล่อง หากกล่องมีข้อความชิดขอบมากเกินไป การเพิ่ม padding จะทำให้เนื้อหาดูอ่านง่ายและมีพื้นที่หายใจมากขึ้น
ตัวอย่างการกำหนด Padding
.card {
padding: 20px;
}
ค่า padding: 20px หมายถึงเพิ่มพื้นที่ด้านใน 20px ทั้งด้านบน ด้านขวา ด้านล่าง และด้านซ้าย หากต้องการกำหนดแยกแต่ละด้าน สามารถใช้ padding-top, padding-right, padding-bottom และ padding-left ได้
กำหนด Padding แยกแต่ละด้าน
.card {
padding-top: 12px;
padding-right: 24px;
padding-bottom: 16px;
padding-left: 24px;
}
Border — เส้นขอบ
Border คือเส้นขอบที่ล้อมรอบ content และ padding เราสามารถกำหนดความหนา รูปแบบ และสีของเส้นขอบได้ เช่น เส้นทึบ เส้นประ หรือไม่มีเส้นขอบเลย
กำหนดเส้นขอบกล่อง
.card {
border: 2px solid #2563eb;
}
คำสั่ง border แบบย่อในตัวอย่างประกอบด้วยความหนา 2px รูปแบบเส้น solid และสี #2563eb ซึ่งเป็นสีน้ำเงิน การกำหนดเส้นขอบช่วยแยกกล่องออกจากพื้นหลังและทำให้ขอบเขตขององค์ประกอบมองเห็นได้ชัดเจน
Margin — พื้นที่ด้านนอก
Margin คือพื้นที่ด้านนอก border ใช้สร้างระยะห่างระหว่าง element กับองค์ประกอบรอบข้าง โดย margin ไม่ใช่พื้นที่ด้านในของกล่อง จึงแตกต่างจาก padding แม้ทั้งสองอย่างจะช่วยสร้างช่องว่างเหมือนกัน
เพิ่มระยะห่างด้านนอก
.card {
margin: 16px;
}
margin: 16px จะกำหนดระยะห่าง 16px ทั้งสี่ด้านของ element โดยทั่วไปเราใช้ margin เพื่อแยกกล่องออกจากกล่องอื่น ส่วน padding ใช้เพิ่มพื้นที่ระหว่างเนื้อหากับขอบของกล่องตัวเอง
จำง่าย ๆContent คือเนื้อหา, Padding คือช่องว่างด้านใน, Border คือเส้นขอบ และ Margin คือช่องว่างด้านนอก
2. มอง Box Model เป็นชั้น ๆ
ลองนึกภาพกล่องหนึ่งใบที่มีข้อความอยู่ตรงกลาง ข้อความคือ content รอบข้อความมีพื้นที่ padding ถัดออกมาเป็น border และนอกเส้นขอบคือ margin แต่ละชั้นทำหน้าที่ต่างกัน แม้จะเห็นเป็นองค์ประกอบเดียวบนหน้าเว็บก็ตาม
| ส่วนประกอบ | ตำแหน่ง | หน้าที่ |
|---|---|---|
| Content | ชั้นในสุด | แสดงข้อความ รูปภาพ หรือเนื้อหา |
| Padding | ระหว่าง Content กับ Border | เพิ่มช่องว่างภายในกล่อง |
| Border | ล้อมรอบ Padding และ Content | แสดงเส้นขอบของกล่อง |
| Margin | ด้านนอก Border | เพิ่มระยะห่างจาก element อื่น |
3. คำนวณขนาดกล่องด้วย content-box
ค่า box-sizing เริ่มต้นของ element ส่วนใหญ่คือ content-box หากเรากำหนด width: 300px และเพิ่ม padding ด้านซ้ายกับขวาด้านละ 20px พร้อม border ด้านละ 2px ความกว้างภายนอกของกล่องจะเท่ากับ 300 + 20 + 20 + 2 + 2 = 344px โดยยังไม่รวม margin
ตัวอย่างการคำนวณขนาด
.box {
box-sizing: content-box;
width: 300px;
padding: 20px;
border: 2px solid #2563eb;
}
ในตัวอย่างนี้ width ระบุความกว้างของ content เท่านั้น padding 20px ถูกเพิ่มทั้งสองด้าน และ border 2px ก็ถูกเพิ่มทั้งสองด้านเช่นกัน ดังนั้นขนาดที่เห็นจริงในแนวนอนคือ 344px
อย่าลืม MarginMargin ไม่ได้รวมอยู่ในความกว้างของ border box แต่มีผลต่อพื้นที่ที่ element ใช้ร่วมกับองค์ประกอบอื่นใน Layout
4. box-sizing: border-box ช่วยให้คุมขนาดง่ายขึ้น
CSS มีค่า box-sizing อีกแบบที่นิยมใช้ในการทำเว็บไซต์จริง คือ border-box เมื่อกำหนด width: 300px ด้วย border-box ความกว้าง 300px จะรวม content, padding และ border ไว้แล้ว ทำให้เราควบคุมขนาดกล่องได้สะดวกกว่าในหลายสถานการณ์
เปรียบเทียบการใช้ Border Box
.box {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 2px solid #2563eb;
}
เมื่อใช้ border-box กล่องตัวอย่างจะกว้างภายนอก 300px ตามที่กำหนดไว้ พื้นที่ content จะลดลงตามขนาด padding และ border ที่เพิ่มเข้ามา จึงช่วยลดปัญหากล่องล้นพื้นที่เมื่อออกแบบ Layout
แนวทางที่นิยมใช้กับทั้งเว็บไซต์
*,
*::before,
*::after {
box-sizing: border-box;
}
การตั้งค่า border-box ให้ทุก element และ pseudo-element เป็นแนวทางที่ใช้กันแพร่หลาย เพราะทำให้การคำนวณขนาดองค์ประกอบคาดเดาได้ง่ายขึ้น อย่างไรก็ตาม ในโครงการจริงควรพิจารณากฎเดิมของระบบด้วย โดยเฉพาะเมื่อทำงานกับ CSS framework หรือส่วนประกอบที่มีการกำหนด box-sizing อยู่แล้ว
5. เขียน Margin และ Padding แบบย่อ
CSS อนุญาตให้กำหนด margin และ padding หลายด้านในคำสั่งเดียวได้ รูปแบบที่ใช้บ่อยมีทั้งหนึ่งค่า สองค่า สามค่า และสี่ค่า การเข้าใจลำดับของค่าจะช่วยลดความยาวของโค้ดและทำให้ปรับแต่ง Layout ได้รวดเร็วขึ้น
| รูปแบบ | ความหมาย |
|---|---|
| padding: 10px; | ทุกด้าน 10px |
| padding: 10px 20px; | บนและล่าง 10px, ซ้ายและขวา 20px |
| padding: 10px 20px 30px; | บน 10px, ซ้ายและขวา 20px, ล่าง 30px |
| padding: 10px 20px 30px 40px; | บน 10px, ขวา 20px, ล่าง 30px, ซ้าย 40px |
สำหรับรูปแบบสี่ค่า ลำดับจะเดินตามเข็มนาฬิกา เริ่มจากด้านบน ตามด้วยด้านขวา ด้านล่าง และด้านซ้าย หากจำลำดับนี้ได้ จะช่วยลดข้อผิดพลาดเวลาเขียน CSS แบบย่อ
ตัวอย่างการใช้ค่าแบบย่อ
.article-card {
margin: 24px auto;
padding: 20px 24px;
border: 1px solid #dbe3ef;
}
ในตัวอย่าง margin: 24px auto หมายถึง margin ด้านบนและล่าง 24px ส่วนด้านซ้ายและขวาเป็น auto ซึ่งมักใช้จัดกึ่งกลาง element แบบ block ที่มีความกว้างเหมาะสมภายในพื้นที่แม่ ส่วน padding: 20px 24px หมายถึงช่องว่างด้านบนและล่าง 20px และด้านซ้ายกับขวา 24px
6. Margin ซ้อนกันในแนวตั้ง
ในบางกรณี margin บนและล่างของ block element ที่อยู่ติดกันอาจเกิด margin collapsing หรือการรวมระยะห่างเข้าด้วยกัน แทนที่จะนำค่าทั้งสองมาบวกกันเสมอ พฤติกรรมนี้มักพบกับ block element ใน Normal Flow และมีเงื่อนไขเฉพาะ ไม่ได้เกิดกับทุก Layout
ตัวอย่าง Margin แนวตั้ง
.first {
margin-bottom: 30px;
}
.second {
margin-top: 20px;
}
เมื่อ element ทั้งสองเป็น block element ตาม Normal Flow และเข้าเงื่อนไขของ margin collapsing ระยะห่างแนวตั้งระหว่างกล่องอาจเป็น 30px ไม่ใช่ 50px แต่พฤติกรรมนี้ขึ้นอยู่กับโครงสร้างและรูปแบบ Layout เช่น flex หรือ grid จะมีพฤติกรรมต่างออกไป
หากระยะห่างดูผิดปกติตรวจสอบ margin ของ element ที่อยู่ติดกัน โครงสร้าง parent และชนิด Layout ก่อน อย่ารีบเพิ่ม margin แบบสุ่ม เพราะอาจทำให้เกิดช่องว่างที่แก้ไขยากกว่าเดิม
7. ใช้ Padding และ Margin อย่างเหมาะสม
ลองใช้หลักง่าย ๆ ในการตัดสินใจ หากต้องการให้ข้อความอยู่ห่างจากขอบภายในกล่อง ให้เริ่มจาก padding หากต้องการแยกกล่องออกจากองค์ประกอบข้างเคียง ให้พิจารณา margin และหากต้องการเส้นขอบเพื่อแบ่งส่วนเนื้อหา ให้ใช้ border ทั้งสามอย่างสามารถใช้ร่วมกันได้
อย่าใช้ margin เพื่อแก้ปัญหาทุกอย่างโดยไม่ตรวจสอบโครงสร้าง ตัวอย่างเช่น หากปุ่มอยู่ชิดขอบการ์ดมากเกินไป การเพิ่ม padding ให้การ์ดอาจเป็นวิธีแก้ที่ตรงจุดกว่า ในทางกลับกัน หากการ์ดแต่ละใบอยู่ติดกันเกินไป อาจต้องปรับ gap ของ Layout หรือ margin ตามโครงสร้างที่ใช้
8. ข้อผิดพลาดที่พบบ่อย
กำหนด Width แล้วกล่องล้นพื้นที่
สาเหตุหนึ่งคือกำหนด width ไว้แล้วเพิ่ม padding และ border โดยใช้ content-box ทำให้ความกว้างจริงมากกว่าที่คาดไว้ ตรวจสอบค่า box-sizing และเลือกใช้ border-box เมื่อเหมาะสม
ใช้ Margin แทน Padding ทุกกรณี
Margin และ padding มีหน้าที่ต่างกัน การใช้ผิดตำแหน่งอาจทำให้สีพื้นหลังของกล่องไม่ครอบคลุมพื้นที่ที่ต้องการ หรือทำให้ระยะห่างระหว่างองค์ประกอบควบคุมได้ยากขึ้น ควรเริ่มจากถามตัวเองว่าต้องการช่องว่างด้านในหรือด้านนอก
กำหนดระยะห่างมากเกินไป
การเพิ่ม margin และ padding จำนวนมากโดยไม่วางแผนอาจทำให้หน้าเว็บดูหลวมเกินไปหรือเกิดการเลื่อนแนวนอนบนหน้าจอขนาดเล็ก ควรตรวจสอบผลลัพธ์ทั้งบนเดสก์ท็อปและมือถือ และใช้ค่าระยะห่างอย่างสม่ำเสมอ
9. แบบฝึกหัดท้ายบท
ลองตอบคำถามต่อไปนี้ด้วยตัวเองก่อนดูโค้ดตัวอย่างในหน้าทดลองด้านล่าง จุดประสงค์ไม่ใช่การจำคำสั่งเพียงอย่างเดียว แต่เป็นการฝึกคาดการณ์ขนาดและระยะห่างของ element จาก CSS ที่เขียนไว้
ข้อ 1: หากกล่องใช้ content-box มี width 200px, padding ซ้ายและขวาด้านละ 10px และ border ซ้ายและขวาด้านละ 1px ความกว้างภายนอกของกล่องเท่าไร โดยยังไม่รวม margin?
ข้อ 2: หากต้องการให้กล่องมีความกว้างภายนอก 200px รวม padding และ border ควรพิจารณาใช้ค่า box-sizing แบบใด?
ข้อ 3: หากต้องการเพิ่มพื้นที่ระหว่างข้อความกับขอบของการ์ด ควรปรับ margin หรือ padding?
ข้อ 4: padding: 12px 24px กำหนดช่องว่างด้านบน ล่าง ซ้าย และขวาอย่างไร?
เฉลยแบบย่อข้อ 1 ได้ 222px เพราะ 200 + 10 + 10 + 1 + 1 = 222px ข้อ 2 ใช้ box-sizing: border-box ข้อ 3 ใช้ padding และข้อ 4 คือด้านบนและล่าง 12px ส่วนด้านซ้ายและขวา 24px
10. ทดลองด้วยหน้าเว็บจริง
ตัวอย่างสุดท้ายเป็นเอกสาร HTML แบบเต็มหน้า สามารถบันทึกเป็นไฟล์ index.html แล้วเปิดด้วยเว็บเบราว์เซอร์ได้ทันที หน้าเว็บมีการ์ดตัวอย่างที่แสดง content, padding, border และ margin พร้อมตัวเลือกเปรียบเทียบ content-box กับ border-box ลองเปลี่ยนค่าแล้วสังเกตขนาดของกล่อง
หน้าเว็บทดลอง CSS Box Model แบบสมบูรณ์
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Box Model Lab</title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
:root {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #172033;
background: #f3f6fb;
}
body {
margin: 0;
padding: 32px 16px;
}
.page {
width: min(100%, 980px);
margin: 0 auto;
}
.hero {
padding: 32px;
color: #ffffff;
background: linear-gradient(135deg, #1d4ed8, #6d28d9);
border-radius: 22px;
margin-bottom: 24px;
}
.hero h1 {
margin: 0 0 12px;
font-size: clamp(1.8rem, 5vw, 3rem);
}
.hero p {
margin: 0;
line-height: 1.8;
color: #e0e7ff;
}
.panel {
background: #ffffff;
border: 1px solid #dbe3ef;
border-radius: 18px;
padding: 24px;
margin-bottom: 24px;
box-shadow: 0 10px 28px rgba(25, 45, 85, 0.06);
}
.panel h2 {
margin: 0 0 10px;
font-size: 1.35rem;
}
.muted {
color: #5b6578;
line-height: 1.75;
}
.box-stage {
margin-top: 22px;
padding: 20px;
background: #eff6ff;
border: 1px dashed #93c5fd;
border-radius: 14px;
overflow: auto;
}
.outer-box {
width: 100%;
max-width: 430px;
margin: 0 auto;
padding: 20px;
background: #fef3c7;
border: 3px solid #d97706;
}
.inner-box {
padding: 24px;
border: 3px solid #2563eb;
background: #dbeafe;
text-align: center;
line-height: 1.7;
color: #1e3a8a;
}
.labels {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
margin-top: 18px;
}
.label-card {
padding: 12px;
border-radius: 12px;
background: #f8fafc;
border: 1px solid #e2e8f0;
font-size: 0.9rem;
}
.label-card strong {
display: block;
margin-bottom: 5px;
}
.controls {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 18px;
}
button {
padding: 11px 16px;
border: 0;
border-radius: 10px;
background: #1d4ed8;
color: #ffffff;
font: inherit;
font-weight: 650;
cursor: pointer;
}
button:hover {
background: #1e40af;
}
button:focus-visible {
outline: 3px solid #93c5fd;
outline-offset: 3px;
}
button.secondary {
color: #1e293b;
background: #e2e8f0;
}
button.secondary:hover {
background: #cbd5e1;
}
.demo-box {
width: 260px;
max-width: 100%;
padding: 24px;
border: 6px solid #7c3aed;
background: #ede9fe;
color: #4c1d95;
text-align: center;
margin: 20px auto 4px;
overflow-wrap: anywhere;
}
.demo-box.content-box {
box-sizing: content-box;
}
.demo-box.border-box {
box-sizing: border-box;
}
.measurement {
padding: 14px 16px;
border-radius: 12px;
background: #f1f5f9;
color: #334155;
line-height: 1.8;
overflow-wrap: anywhere;
}
.footer {
padding: 18px 4px;
color: #64748b;
text-align: center;
font-size: 0.9rem;
}
@media (max-width: 640px) {
body {
padding: 18px 12px;
}
.hero,
.panel {
padding: 20px;
}
.labels {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
</style>
</head>
<body>
<main class="page">
<header class="hero">
<h1>CSS Box Model Lab</h1>
<p>เรียนรู้พื้นที่ของ element ผ่านตัวอย่าง Content, Padding, Border และ Margin พร้อมทดลองเปรียบเทียบขนาดกล่องจริง</p>
</header>
<section class="panel">
<h2>ส่วนประกอบของกล่อง</h2>
<p class="muted">กล่องชั้นนอกสีเหลืองแสดงพื้นที่ด้านนอกและกรอบ ส่วนกล่องสีน้ำเงินด้านในแสดงพื้นที่เนื้อหาพร้อม padding และ border</p>
<div class="box-stage">
<div class="outer-box">
<div class="inner-box">
<strong>Content</strong><br>
ข้อความและเนื้อหาของ element<br>
<small>พื้นที่ด้านในล้อมรอบด้วย Padding และ Border</small>
</div>
</div>
</div>
<div class="labels">
<div class="label-card"><strong>Content</strong>พื้นที่เนื้อหา</div>
<div class="label-card"><strong>Padding</strong>พื้นที่ด้านใน</div>
<div class="label-card"><strong>Border</strong>เส้นขอบ</div>
<div class="label-card"><strong>Margin</strong>พื้นที่ด้านนอก</div>
</div>
</section>
<section class="panel">
<h2>เปรียบเทียบ Content-box กับ Border-box</h2>
<p class="muted">กล่องทั้งสองกำหนด width: 260px, padding: 24px และ border: 6px หากเป็น content-box ความกว้างภายนอกจะเพิ่ม padding และ border เข้าไป แต่ border-box จะรวมพื้นที่เหล่านี้ไว้ใน width แล้ว</p>
<div id="demoBox" class="demo-box content-box">กล่องตัวอย่าง<br>width: 260px</div>
<div id="measurement" class="measurement" aria-live="polite">กำลังวัดขนาดกล่อง...</div>
<div class="controls">
<button id="contentButton" type="button">ใช้ Content-box</button>
<button id="borderButton" type="button">ใช้ Border-box</button>
</div>
</section>
<section class="panel">
<h2>สรุปสิ่งที่ควรจำ</h2>
<p class="muted">ใช้ padding เมื่อเพิ่มช่องว่างระหว่างเนื้อหากับขอบ ใช้ margin เมื่อเพิ่มระยะห่างจาก element อื่น และตรวจสอบ box-sizing เมื่อขนาดกล่องไม่เป็นไปตามที่คาด</p>
</section>
<footer class="footer">HTML & CSS Learning Lab · EP4</footer>
</main>
<script>
const demoBox = document.getElementById('demoBox');
const measurement = document.getElementById('measurement');
const contentButton = document.getElementById('contentButton');
const borderButton = document.getElementById('borderButton');
function updateMeasurement(mode) {
demoBox.className = 'demo-box ' + mode;
const rect = demoBox.getBoundingClientRect();
const styles = getComputedStyle(demoBox);
measurement.textContent =
'โหมด: ' + mode +
' | ความกว้างที่แสดงจริง: ' + Math.round(rect.width) + 'px' +
' | Padding ซ้ายและขวา: ' + styles.paddingLeft + ' / ' + styles.paddingRight +
' | Border ซ้ายและขวา: ' + styles.borderLeftWidth + ' / ' + styles.borderRightWidth;
}
contentButton.addEventListener('click', function () {
updateMeasurement('content-box');
});
borderButton.addEventListener('click', function () {
updateMeasurement('border-box');
});
window.addEventListener('resize', function () {
updateMeasurement(demoBox.classList.contains('border-box') ? 'border-box' : 'content-box');
});
updateMeasurement('content-box');
</script>
</body>
</html>
Reach within 500px of the page end and stay for at least 5 minutes to earn EXP once per day.
⏳ Reading timer is running...