CSS
Layout Basics
Float & Clear
เรียนรู้ float และ clear — เทคนิค layout ยุคคลาสสิกที่ทำให้ element ลอยไปทางซ้ายหรือขวา และให้เนื้อหาไหลล้อมรอบ เข้าใจแล้วจะอ่านโค้ดเก่าได้ และเข้าใจพฤติกรรม browser ได้ลึกขึ้น
หัวข้อนี้คืออะไร
float (โฟลต) คือ CSS property ที่ใช้ทำให้ element "ลอย" ออกไปทางซ้ายหรือขวาของ parent container แล้วให้เนื้อหาที่อยู่ถัดมาไหลล้อมรอบ element นั้น clear (เคลียร์) คือ CSS property ที่ใช้บอก element ว่า "อย่าไหลชิด float" — ให้เริ่มต้นที่ตำแหน่งใหม่หลังจาก float สิ้นสุดลง ทั้งสองต้องเรียนคู่กัน เพราะ float สร้างพฤติกรรมบางอย่างที่ต้องใช้ clear จัดการ 📌 หมายเหตุ: float เป็นเทคนิคที่มีมาตั้งแต่ยุคแรกของ CSS ปัจจุบัน Flexbox และ Grid เข้ามาแทนที่สำหรับการทำ layout หลัก แต่การรู้จัก float ยังสำคัญมาก เพราะ: - โค้ดเก่าหลายล้านบรรทัดยังใช้อยู่ - พฤติกรรมบางอย่างของ float ยังไม่มีสิ่งทดแทน เช่น ข้อความไหลรอบรูป
- float: left — ให้ element ลอยชิดซ้าย เนื้อหาที่ตามมาไหลมาด้านขวา
- float: right — ให้ element ลอยชิดขวา เนื้อหาที่ตามมาไหลมาด้านซ้าย
- float: none — ค่า default ไม่ลอย (ยกเลิก float ที่ถูกกำหนดไว้ก่อน)
- clear: left — ไม่ยอมชิดกับ float ที่ลอยอยู่ด้านซ้าย
- clear: right — ไม่ยอมชิดกับ float ที่ลอยอยู่ด้านขวา
- clear: both — ไม่ยอมชิดกับ float ทั้งสองด้าน (ใช้บ่อยที่สุด)
ทำไมหัวข้อนี้จึงสำคัญ
แม้ float จะไม่ใช่เครื่องมือ layout หลักของยุคนี้ แต่มีเหตุผลสำคัญที่ควรเรียนรู้: 1. อ่านโค้ดเก่าได้ โปรเจกต์เก่าจำนวนมากยังใช้ float-based layout คุณจะต้องเข้าใจมันเพื่อบำรุงรักษาหรือ migrate โค้ดได้ 2. เข้าใจพฤติกรรม browser ลึกขึ้น float เปลี่ยนวิธีที่ browser คำนวณ layout — เข้าใจ float จะทำให้เข้าใจ normal flow และ block formatting context ได้ดีขึ้น 3. กรณีที่ float ยังดีกว่าในปัจจุบัน การให้ข้อความไหลล้อมรอบรูปภาพในบทความ ยังเป็นสิ่งที่ float ทำได้ดีที่สุด Flexbox และ Grid ไม่มีพฤติกรรมแบบนี้โดยตรง 4. ฐานความรู้ CSS ที่สมบูรณ์ นักพัฒนาที่ดีควรเข้าใจทั้ง tool เก่าและใหม่ เพื่อเลือกใช้ได้ถูกสถานการณ์
ตัวอย่างจากชีวิตจริง
ลองนึกภาพบทความในหนังสือพิมพ์: 📰 รูปภาพในบทความ เวลาคุณอ่านหนังสือพิมพ์หรือนิตยสาร รูปภาพมักวางอยู่ด้านซ้ายหรือขวา และข้อความในบทความไหลล้อมรอบรูป ไม่ใช่อยู่บนหรือล่างของรูปเพียงอย่างเดียว — นี่คือสิ่งที่ float ทำให้เกิดขึ้นบนเว็บ 🛑 ส่วนท้ายบทความ หลังจากรูปภาพและข้อความ มี "เส้นแบ่ง" หรือ "ส่วนท้าย" ที่ต้องเริ่มต้นใหม่ ไม่ว่ารูปจะสูงแค่ไหน ส่วนนั้นต้องอยู่ด้านล่างรูปเสมอ — นี่คือสิ่งที่ clear ทำให้เกิดขึ้น 🏗️ Layout คอลัมน์ในยุคก่อน ก่อนจะมี Flexbox และ Grid นักพัฒนาใช้ float เพื่อสร้าง layout หลายคอลัมน์ เช่น คอลัมน์ sidebar + เนื้อหาหลัก แม้วิธีนี้จะมีข้อจำกัด แต่มันคือวิธีเดียวที่ใช้ได้มานานกว่าสิบปี
แนวคิดหลักที่ต้องเข้าใจ
float ทำให้ element ลอยออกจาก flow — clear บังคับให้ element ถัดมาเริ่มใหม่หลัง float
มีสี่แนวคิดสำคัญที่ต้องเข้าใจก่อนใช้ float: ── 1. float ทำให้ element หลุดออกจาก normal flow บางส่วน ── เมื่อ element มี float มันจะถูก "ยก" ออกจาก normal flow แต่ไม่เหมือน position: absolute ที่หลุดออกสมบูรณ์ — text และ inline content ยังคงไหลรอบ float ได้ ── 2. block element จะไม่เห็น float ── ถ้ามี div ถัดจาก float ตัว div นั้นจะขยับขึ้นมาเหมือนไม่มี float อยู่ แต่ข้อความ (text) ภายใน div นั้นจะยังไหลรอบ float — นี่คือพฤติกรรมที่สร้างความสับสนมากที่สุด ── 3. parent อาจ "พัง" เพราะ float ── ถ้า parent มีแค่ float element ทั้งหมด parent จะมีความสูงเป็น 0 เพราะ float element ไม่ "ดัน" parent ให้สูงขึ้น ปัญหานี้เรียกว่า "collapsing parent" ── 4. clear หยุด element จากการไหลรอบ float ── เมื่อ element มี clear: both มันจะเลื่อนลงมาจนพ้น float ทั้งหมดก่อน แล้วจึงเริ่มแสดงผล
การทำงานทีละขั้นตอน
นี่คือลำดับที่ browser ทำงานเมื่อพบ float:
- ขั้นที่ 1 — browser วาง element ตาม normal flow ปกติ: block element วางซ้อนกันจากบนลงล่าง inline element เรียงในบรรทัดเดียว
- ขั้นที่ 2 — เมื่อพบ float: left หรือ float: right: browser ดึง element นั้นออกจาก flow บางส่วน และชิดมันไปด้านที่กำหนด
- ขั้นที่ 3 — block element ที่ตามมาจะ 'ไม่เห็น' float: มันขยับขึ้นมาเหมือนไม่มี float แต่ข้อความและ inline content ภายในจะไหลรอบ float
- ขั้นที่ 4 — float สะสมกัน: ถ้ามีหลาย float ต่อกัน จะเรียงชิดกันในทิศทางเดียว จนเต็มแถวแล้วจึงขึ้นบรรทัดใหม่
- ขั้นที่ 5 — เมื่อพบ clear: both: browser บังคับให้ element นั้นเลื่อนลงมาจนพ้น float ทั้งหมด ก่อนจึงแสดงผล element นั้น
ตัวอย่างโค้ด
ดูการใช้ float และ clear ในสถานการณ์พื้นฐาน:
margin ด้านขวาของ float ช่วยให้ข้อความไม่ชิดรูปมากเกินไป — clearfix เป็นเทคนิคคลาสสิกที่แก้ปัญหา parent collapse
/* ── ตัวอย่าง 1: รูปภาพลอยซ้าย ── */
.article-image {
float: left;
width: 160px;
margin: 0 16px 8px 0; /* เว้นระยะห่างด้านขวาและล่าง */
}
/* ข้อความจะไหลมาด้านขวาของรูปโดยอัตโนมัติ */
.article-text {
/* ไม่ต้องทำอะไรพิเศษ — text ไหลรอบ float เองเลย */
}
/* ── ตัวอย่าง 2: หยุดการไหลด้วย clear ── */
.article-footer {
clear: both; /* เริ่มใหม่หลัง float ทั้งหมด */
border-top: 1px solid #e2e8f0;
padding-top: 16px;
}
/* ── ตัวอย่าง 3: clearfix — แก้ parent collapse ── */
.clearfix::after {
content: "";
display: block;
clear: both;
}
/* ใช้ clearfix กับ parent ที่มีแต่ float element */ทดลองใช้ float และ clear
จุดที่ผู้เริ่มต้นมักสับสน
ตรวจสอบว่าคุณเข้าใจถูกต้องหรือยัง:
- ❌ คิดว่า float คือเครื่องมือ layout หลักของปัจจุบัน — ไม่ใช่ ปัจจุบัน Flexbox และ Grid คือทางเลือกที่ดีกว่าสำหรับ layout หลัก float เหมาะกับกรณีเฉพาะ เช่น ข้อความไหลรอบรูปภาพ
- ❌ ไม่เข้าใจว่า parent ทำไมสูง 0 — เกิดจาก 'collapsing parent' เมื่อ parent มีแต่ float element browser ไม่นับ float เข้า height ของ parent แก้ด้วย clearfix หรือ overflow: hidden ให้ parent
- ❌ สับสนว่าต้องใส่ clear กับ element ไหน — clear ต้องใส่กับ element ที่ต้องการ 'ขึ้นบรรทัดใหม่หลัง float' ไม่ใช่ใส่กับ float element เอง
- ❌ คิดว่า clear: left แก้ทุกกรณี — clear: left แก้เฉพาะ float ที่ลอยซ้าย clear: both ปลอดภัยกว่าเมื่อไม่แน่ใจว่า float อยู่ทิศทางไหน
- ❌ float element ล้นออกนอก parent — เพราะ float element ไม่ดัน parent ให้สูงขึ้น ต้องใช้ clearfix หรือ overflow: hidden กับ parent
เปรียบเทียบกับสิ่งที่ใกล้เคียง
เมื่อไรควรใช้อะไร:
| เครื่องมือ | เหมาะกับ | ข้อจำกัด | สถานะปัจจุบัน |
|---|---|---|---|
| float | ข้อความไหลรอบรูป, อ่านโค้ดเก่า | ต้องจัดการ clear/clearfix, parent collapse | ใช้เฉพาะกรณี |
| Flexbox | layout 1 มิติ (แถวหรือคอลัมน์), จัด align | ไม่เหมาะ layout ตาราง 2 มิติ | แนะนำ |
| Grid | layout 2 มิติ (แถว + คอลัมน์พร้อมกัน) | อาจซับซ้อนสำหรับเบื้องต้น | แนะนำ |
| position: absolute | วาง element ที่ตำแหน่งเจาะจง | หลุดจาก flow ทำให้ layout รอบข้างพัง | ใช้เฉพาะกรณี |
สรุปท้ายบท
จำหลักการนี้ไว้: "float ให้เนื้อหาไหลรอบ element — clear บอกว่า 'หยุดไหลแล้ว เริ่มใหม่ที่นี่'"
- float: left / right — ดึง element ออกจาก flow บางส่วน ทำให้ text ไหลรอบได้
- float เหมาะกับการให้ข้อความล้อมรูปภาพ ไม่ใช่ layout หลักในยุคปัจจุบัน
- clear: both — บังคับให้ element นั้นเริ่มต้นหลัง float ทั้งหมด
- collapsing parent — parent ที่มีแต่ float จะสูง 0 แก้ด้วย clearfix หรือ overflow: hidden
- clearfix เป็นเทคนิคคลาสสิกที่ใช้ ::after เพื่อ clear float ใน parent
- ควรอ่านโค้ดเก่าที่ใช้ float ได้ แต่เขียนใหม่ให้ใช้ Flexbox หรือ Grid แทน
- float ใน CSS ปัจจุบันยังมีประโยชน์เฉพาะเรื่องข้อความไหลรอบรูป
Lab 1 — ให้รูปภาพลอยซ้าย
เป้าหมาย: ฝึกใช้ float: left เพื่อให้รูปภาพลอยออกไปทางซ้ายและข้อความไหลรอบ โจทย์: .photo ปัจจุบันเป็น block element วางอยู่เหนือข้อความ กำหนด float: left และ margin-right: 12px ให้กับ .photo เพื่อให้ข้อความไหลมาทางด้านขวาของรูป ระบบจะตรวจ: 1. .photo มี float: left ใน CSS 2. .photo มี margin-right: 12px ใน CSS 3. computed float ของ .photo = left ใน browser 4. .photo อยู่ทางซ้ายของ container (offsetLeft ≈ 0) เงื่อนไข: ห้ามเปลี่ยน HTML
Lab 2 — ใช้ clear หยุดการไหล
เป้าหมาย: ฝึกใช้ clear: both เพื่อให้ element ถัดจาก float เริ่มต้นใหม่หลัง float สิ้นสุด โจทย์: .photo มี float: left อยู่แล้ว .footer ปัจจุบันไหลชิดอยู่ข้างรูป แต่ควรอยู่ด้านล่างรูปเสมอ กำหนด clear: both ให้กับ .footer เพื่อให้มันเริ่มต้นที่ตำแหน่งใหม่หลัง float ระบบจะตรวจ: 1. .footer มี clear: both ใน CSS 2. computed clear ของ .footer = both ใน browser 3. .footer อยู่ด้านล่างของ .photo (offsetTop ของ .footer > offsetTop + height ของ .photo) เงื่อนไข: ห้ามเปลี่ยน HTML และห้ามลบ float ของ .photo
Lab 3 — แก้ layout ที่พังเพราะ float
เป้าหมาย: แก้ปัญหาในโลกจริง — layout พังเพราะ float ไม่มี clear โจทย์: มี layout ที่ประกอบด้วย .sidebar (float: left) และ .main-content ส่วน .page-footer ควรอยู่ด้านล่างของทั้งสอง แต่ตอนนี้มันลอยขึ้นมาทับอยู่ กำหนด float: left ให้ .sidebar (width: 120px) กำหนด clear: both ให้ .page-footer เพื่อให้มันอยู่ใต้ทั้ง .sidebar และ .main-content ระบบจะตรวจ: 1. .sidebar มี float: left ใน CSS 2. .sidebar มี width: 120px ใน CSS 3. .page-footer มี clear: both ใน CSS 4. .page-footer อยู่ด้านล่างของ .sidebar ใน browser เงื่อนไข: ห้ามเปลี่ยน HTML