CSS
Box Model
overflow
เรียนรู้วิธีควบคุมสิ่งที่เกิดขึ้นเมื่อเนื้อหาใหญ่เกินกว่าพื้นที่ของ element — ตั้งแต่ปล่อยให้ล้น ซ่อนส่วนเกิน ไปจนถึงเปิดแถบเลื่อน (scroll) เพื่อไม่ให้ layout พัง
หัวข้อนี้คืออะไร
โอเวอร์โฟลว์ (overflow) คือ CSS property ที่บอก browser ว่าจะ "จัดการอย่างไร" เมื่อเนื้อหาของ element มีขนาดใหญ่กว่าพื้นที่ที่กำหนดไว้ โดยปกติถ้าคุณกำหนด height: 100px ให้กล่อง แต่ข้อความข้างในยาวกว่านั้น — เนื้อหาจะล้นออกมานอกกล่องโดยอัตโนมัติ overflow คือตัวควบคุมพฤติกรรมนั้น overflow มีค่าหลักสี่แบบ:
- visible (วิซิเบิล) — ค่า default: เนื้อหาที่ล้นจะแสดงให้เห็นนอกกล่อง ไม่ถูกตัดหรือซ่อน
- hidden (ฮิดเดน) — ซ่อนเนื้อหาที่ล้นออกไป ผู้ใช้ไม่เห็นและเลื่อนดูไม่ได้
- scroll (สกรอล) — มีแถบเลื่อน (scrollbar) เสมอ แม้เนื้อหาจะไม่ล้น
- auto (ออโต้) — มีแถบเลื่อนเฉพาะเมื่อเนื้อหาล้นจริง ถ้าไม่ล้นจะไม่แสดง scrollbar
ทำไมหัวข้อนี้จึงสำคัญ
เนื้อหาที่ล้นกล่องคือหนึ่งในปัญหา layout ที่พบบ่อยที่สุดในงาน frontend ถ้าไม่จัดการ overflow ให้ดี คุณจะพบปัญหาเหล่านี้: - ข้อความล้นออกนอกการ์ด ทับกับ element อื่นจนหน้าตาแปลก - กล่องที่กำหนดขนาดไว้แล้วดูใหญ่กว่าที่ต้องการบนมือถือ - Layout พังบนหน้าจอขนาดเล็กเพราะเนื้อหายาวเกิน - กล่องเนื้อหาที่ควรเลื่อนได้ แต่ไม่มี scrollbar overflow ถูกใช้บ่อยใน: - กล่องข้อความที่มีความสูงคงที่ (เช่น คำอธิบายสินค้า) - การ์ดที่ต้องการตัดข้อความที่ยาวเกิน - ตารางที่มีคอลัมน์กว้างเกิน - พื้นที่ที่เลื่อนได้ เช่น sidebar หรือ chat box
ตัวอย่างจากชีวิตจริง
ลองนึกภาพการใส่เสื้อผ้าลงกระเป๋าเดินทางที่มีขนาดจำกัด กระเป๋าเต็มแล้ว แต่ยังมีเสื้อเหลืออยู่อีกหลายตัว — จะทำอย่างไร? แบบที่ 1 — overflow: visible "ยัดของให้พ้นออกมาด้านบน ฝาปิดไม่ได้ แต่มองเห็นว่ามีอะไรอยู่" → เนื้อหาล้นออกมานอกกล่อง มองเห็นได้แต่อาจทับกับสิ่งรอบข้าง แบบที่ 2 — overflow: hidden "ทุกอย่างที่ไม่ลงในกระเป๋าให้ทิ้งไปเลย ฝาปิดสนิท" → เนื้อหาที่ล้นถูกซ่อน ผู้ใช้ไม่เห็นและเข้าถึงส่วนที่เกินไม่ได้ แบบที่ 3 — overflow: scroll "ซิปกระเป๋าขยายได้ พร้อม handle ดึงเสมอ แม้ของจะยังไม่เต็ม" → แถบเลื่อนปรากฏเสมอ ไม่ว่าเนื้อหาจะล้นหรือไม่ แบบที่ 4 — overflow: auto "กระเป๋าพับขยายได้อัตโนมัติเมื่อของเต็ม ถ้ายังว่างก็ดูปกติ" → แถบเลื่อนปรากฏเฉพาะเมื่อเนื้อหาล้นจริง — แนะนำสำหรับงานส่วนใหญ่
แนวคิดหลักที่ต้องเข้าใจ
visible = ล้นออกมา | hidden = ซ่อน | scroll = แถบเลื่อนเสมอ | auto = แถบเลื่อนเมื่อจำเป็น
สิ่งสำคัญก่อนใช้ overflow: overflow มีผลก็ต่อเมื่อ element มีขนาดจำกัด ถ้าไม่กำหนด width หรือ height ไว้ browser จะขยาย element ตามเนื้อหาเองอยู่แล้ว overflow จึงไม่มีผล — คุณต้องกำหนดขนาดก่อนเสมอ ลำดับที่ overflow ทำงาน: 1. Browser render เนื้อหาข้างใน element 2. ตรวจสอบว่าเนื้อหาเกิน width หรือ height ที่กำหนดหรือไม่ 3. ถ้าเกิน ใช้กติกาของ overflow ที่กำหนดไว้ overflow-x และ overflow-y: คุณสามารถควบคุมแนวนอนและแนวตั้งแยกกันได้ - overflow-x: hidden — ซ่อนเฉพาะส่วนที่ล้นแนวนอน - overflow-y: auto — แถบเลื่อนแนวตั้งเมื่อจำเป็น
การทำงานทีละขั้นตอน
เมื่อ browser เจอ element ที่มีขนาดกำหนดและเนื้อหาล้น — นี่คือสิ่งที่เกิดขึ้น:
- 1. กำหนดขนาดกล่อง — คุณระบุ width และ height เช่น width: 200px; height: 100px; ทำให้ browser รู้ว่าพื้นที่มีเท่าไหร่
- 2. browser render เนื้อหาข้างใน — ข้อความ, รูปภาพ, หรือ element ลูกถูก render ตามปกติ ไม่สนใจขนาดของ parent ก่อน
- 3. browser ตรวจสอบการล้น — ถ้าเนื้อหาสูงหรือกว้างกว่าพื้นที่ที่กำหนด browser รู้ว่า overflow เกิดขึ้น
- 4. ใช้กติกา overflow — visible: แสดงส่วนที่เกิน | hidden: ตัดส่วนที่เกินออก | scroll: เพิ่ม scrollbar | auto: เพิ่ม scrollbar เฉพาะเมื่อจำเป็น
- 5. แสดงผลสุดท้าย — ผู้ใช้เห็นกล่องตามพฤติกรรมที่กำหนด กล่อง element อื่นรอบข้างไม่ถูกกระทบ (ยกเว้น visible ที่อาจทับกัน)
ตัวอย่างเชิงเทคนิค — โค้ดจริง
กล่องสี่ใบนี้มีขนาดเท่ากัน แต่ overflow ต่างกัน — ดูผลที่แตกต่าง:
overflow: auto เป็นค่าที่แนะนำสำหรับกรณีทั่วไป เพราะไม่แสดง scrollbar ที่ไม่จำเป็น แต่พร้อมให้เลื่อนได้เมื่อเนื้อหาล้นจริง
/* กล่องฐาน */
.box {
width: 200px;
height: 80px;
border: 2px solid #64748b;
padding: 8px;
}
/* 1. visible — ค่า default เนื้อหาล้นออกมา */
.box-visible {
overflow: visible;
}
/* 2. hidden — ซ่อนส่วนที่ล้น */
.box-hidden {
overflow: hidden;
}
/* 3. scroll — แถบเลื่อนเสมอ แม้เนื้อหาไม่ล้น */
.box-scroll {
overflow: scroll;
}
/* 4. auto — แถบเลื่อนเมื่อจำเป็นเท่านั้น */
.box-auto {
overflow: auto;
}
/* ควบคุมแยกแนวนอน / แนวตั้ง */
.box-x-only {
overflow-x: auto; /* แถบเลื่อนแนวนอนเมื่อจำเป็น */
overflow-y: hidden; /* ซ่อนส่วนที่ล้นแนวตั้ง */
}ดูความแตกต่างแบบ Interactive
ทดลองเปลี่ยนค่า overflow ของแต่ละกล่อง แล้วสังเกตว่าเนื้อหาที่ล้นถูกจัดการต่างกันอย่างไร:
จุดที่ผู้เริ่มต้นมักสับสน
ตรวจสอบว่าคุณเข้าใจถูกต้องหรือยัง:
- ❌ คิดว่า overflow ทำงานได้แม้ไม่กำหนดขนาด — ไม่ถูก overflow มีผลก็ต่อเมื่อ element มี width หรือ height กำหนดไว้ ถ้าไม่กำหนด element จะขยายตามเนื้อหาเองอยู่แล้ว ไม่มีส่วนที่ล้น
- ❌ สับสนระหว่าง hidden กับ scroll — hidden ซ่อนเนื้อหาที่ล้นโดยตัดทิ้ง ผู้ใช้ไม่สามารถเลื่อนดูได้ ส่วน scroll เพิ่ม scrollbar ให้เลื่อนดูส่วนที่ล้นได้
- ❌ ไม่รู้ว่า auto ต่างจาก scroll ตรงไหน — scroll แสดง scrollbar เสมอแม้เนื้อหาไม่ล้น (ดูเกะกะ) ส่วน auto แสดง scrollbar เฉพาะเมื่อจำเป็น — ในงานจริงแนะนำ auto มากกว่า
- ❌ งงว่าทำไม overflow: hidden แล้วยังล้นอยู่ — อาจเป็นเพราะไม่ได้กำหนด height ไว้ หรือเนื้อหาเป็น element ที่ใช้ position: absolute ซึ่ง overflow: hidden ควบคุมได้ในบางกรณีเท่านั้น
- ❌ ลืมว่า overflow: hidden ซ่อน ::before / ::after และ box-shadow ที่ล้นออกมาด้วย — ถ้า element มี drop-shadow หรือ pseudo-element ที่ยื่นออกมา overflow: hidden อาจตัดส่วนนั้นด้วย
เปรียบเทียบค่า overflow
สรุปความแตกต่างของแต่ละค่าในตารางเดียว:
| ค่า | เนื้อหาที่ล้น | แถบเลื่อน | เหมาะสำหรับ |
|---|---|---|---|
| visible | แสดงให้เห็นนอกกล่อง | ไม่มี | ค่า default — ใช้เมื่อต้องการให้เนื้อหาล้นได้ |
| hidden | ถูกซ่อน/ตัดออก | ไม่มี | การ์ด, thumbnail, ตัดข้อความที่ยาวเกิน |
| scroll | เลื่อนดูได้ | แสดงเสมอ (แม้ไม่ล้น) | กรณีพิเศษที่ต้องการ scrollbar ตายตัว |
| auto | เลื่อนดูได้ | แสดงเมื่อจำเป็น | กล่องข้อความ, sidebar, chat box — แนะนำ |
| overflow-x / overflow-y | ควบคุมแยกแนวนอน/ตั้ง | ขึ้นกับค่าที่กำหนด | ตาราง, slider แนวนอน |
สรุปท้ายบท
จำง่ายๆ แบบนี้: "overflow บอก browser ว่าจะทำอะไรกับเนื้อหาที่ล้น — แต่มีผลก็ต่อเมื่อกล่องมีขนาดกำหนดไว้"
- overflow จัดการเนื้อหาที่ใหญ่เกินกว่า width/height ของ element
- visible = ล้นออกมาให้เห็น (ค่า default)
- hidden = ซ่อนส่วนที่เกิน ผู้ใช้เข้าถึงไม่ได้
- scroll = แถบเลื่อนเสมอ แม้เนื้อหาไม่ล้น
- auto = แถบเลื่อนเฉพาะเมื่อจำเป็น — แนะนำสำหรับงานทั่วไป
- overflow มีผลก็ต่อเมื่อ element มีขนาด (width/height) กำหนดไว้เท่านั้น
- overflow-x และ overflow-y ใช้ควบคุมแนวนอน/แนวตั้งแยกกันได้
Lab 1 — ซ่อนเนื้อหาที่ล้น
เป้าหมาย: ฝึกใช้ overflow: hidden เพื่อซ่อนเนื้อหาที่เกินพื้นที่ โจทย์: .card มีข้อความยาวที่ล้นออกนอกกล่อง เพิ่ม overflow: hidden ให้กับ .card เพื่อซ่อนส่วนที่เกิน ระบบจะตรวจ: 1. .card มี overflow: hidden ใน CSS 2. computed overflow ใน browser = hidden 3. ความสูงของ .card ไม่เปลี่ยนแปลงหลังจาก overflow: hidden เงื่อนไข: ห้ามเปลี่ยน height ของ .card
Lab 2 — เปิดแถบเลื่อน
เป้าหมาย: ฝึกใช้ overflow: auto เพื่อให้เนื้อหาที่ล้นเลื่อนดูได้ โจทย์: .chat-box มีข้อความหลายบรรทัดที่ยาวเกินความสูงที่กำหนด เพิ่ม overflow-y: auto ให้กับ .chat-box เพื่อให้เลื่อนดูเนื้อหาที่ล้นได้ ระบบจะตรวจ: 1. .chat-box มี overflow-y: auto ใน CSS 2. computed overflowY ใน browser = auto 3. scrollHeight ของ .chat-box มากกว่า clientHeight (มีเนื้อหาที่ล้นจริง) เงื่อนไข: ต้องใช้ overflow-y ไม่ใช่ overflow ทั้งบรรทัด และต้องไม่เปลี่ยน height
Lab 3 — เลือกค่า overflow ให้เหมาะกับสถานการณ์
เป้าหมาย: ฝึกเลือกค่า overflow ที่เหมาะสมกับแต่ละสถานการณ์จริง โจทย์: มีกล่องสามใบที่ต้องการพฤติกรรมต่างกัน 1. .thumbnail — รูปภาพที่ใหญ่เกินกล่อง ต้องการซ่อนส่วนเกิน ไม่ให้เลื่อนได้ → ใช้ overflow: hidden 2. .article-preview — ข้อความบทความที่ยาว ต้องการให้เลื่อนดูได้เฉพาะแนวตั้งเมื่อจำเป็น → ใช้ overflow-y: auto 3. .tag-list — รายการแท็กที่อาจเกินแนวนอน ต้องซ่อนแนวตั้งและเลื่อนแนวนอนได้ → ใช้ overflow-x: auto และ overflow-y: hidden ระบบจะตรวจ css declaration และ computed style ของแต่ละกล่อง เงื่อนไข: ต้องใช้ค่าที่ถูกต้องตามโจทย์ ห้ามเปลี่ยน width, height, หรือ CSS อื่น