CSS
Responsive Design
Fluid layout
fluid layout คือ layout ที่ยืดหยุ่นตามพื้นที่ที่มี โดยใช้หน่วยแบบสัมพัทธ์เช่น %, fr, vw แทนค่า px ตายตัว — ทำให้ layout ปรับตัวได้อย่างราบรื่นในทุกขนาดหน้าจอโดยไม่จำเป็นต้องมี breakpoint จำนวนมาก
หัวข้อนี้คืออะไร
fluid layout คือแนวคิดการออกแบบ layout ที่ให้ขนาดขององค์ประกอบยืดหดตามพื้นที่ที่มี แทนที่จะกำหนดค่าตายตัวเป็น px แทนที่จะบอกว่า "กล่องนี้กว้าง 600px เสมอ" — fluid layout บอกว่า "กล่องนี้กว้าง 80% ของพื้นที่ที่มี แต่ไม่เกิน 800px" หน่วยที่ใช้ใน fluid layout:
width: 100% ทำให้ยืดเต็มพื้นที่, max-width จำกัดขนาดสูงสุด, padding ป้องกันชนขอบ
/* ❌ Fixed layout — กว้างตายตัว ไม่ยืดหยุ่น */
.container {
width: 960px;
}
/* ✅ Fluid layout — ยืดตามพื้นที่ มีขอบเขตสูงสุด */
.container {
width: 100%;
max-width: 960px;
margin: 0 auto;
padding: 0 16px;
}ทำไมหัวข้อนี้สำคัญ
หน้าจอมีหลากหลายขนาด — 320px (มือถือเก่า), 390px (iPhone), 768px (tablet), 1440px (desktop กว้าง), 2560px (ultrawide) ถ้าใช้ fixed layout: เว็บที่กว้าง 960px จะมี scroll bar แนวนอนบนมือถือ เว็บที่กว้าง 960px จะดูมีช่องว่างโดดเดี่ยวกลางจอบน ultrawide monitor fluid layout ช่วยให้: layout ปรับตัวได้ราบรื่นในช่วงระหว่าง breakpoints ไม่ใช่แค่ที่จุด breakpoint เท่านั้น ไม่จำเป็นต้องกำหนด breakpoint จำนวนมากเพื่อครอบคลุมทุกขนาด เนื้อหาใช้พื้นที่ที่มีได้อย่างเหมาะสม ไม่แน่นเกิน ไม่โล่งเกิน fluid layout ≠ ไม่มีขอบเขต — ยังควรมี max-width เพื่อควบคุมความกว้างสูงสุด
ตัวอย่างจากชีวิตจริง
ลองนึกถึงน้ำในภาชนะ: แก้วน้ำ — น้ำปรับรูปร่างตามแก้ว ไม่ว่าแก้วจะกว้างหรือแคบ แต่น้ำยังคงเป็นน้ำ — ถ้าแก้วใหญ่เกินไปก็ใส่แค่ปริมาณที่มี fluid layout เหมือนน้ำในแก้ว: เนื้อหาขยายตามพื้นที่ที่มี แต่มี max-width เป็น "ขนาดสูงสุดของแก้ว" บน UI จริง: Medium.com — article ขยายตามหน้าจอ แต่จำกัดความกว้างไว้ที่ประมาณ 700px เพื่อความอ่านง่าย Notion — column ยืดเต็มหน้าต่าง แต่มี padding ทั้งสองข้างเพื่อไม่ให้ข้อความติดขอบ Twitter/X — timeline ยืดตามหน้าต่าง แต่ไม่กว้างเกินขอบเขตที่กำหนด
แนวคิดหลักที่ต้องเข้าใจ
หน่วย 4 ชนิดที่ใช้บ่อยใน fluid layout: - % — สัดส่วนของ parent element ("กว้าง 80% ของ container พ่อ") - fr — fraction ใน CSS Grid ("แบ่งพื้นที่เหลือเป็น 3 ส่วนเท่ากัน") - vw — viewport width ("กว้าง 50% ของหน้าจอทั้งหมด") - max-width — ขอบเขตสูงสุดที่ยอมให้ยืดได้ ("ยืดได้แต่ไม่เกิน 1200px") ลองปรับขนาด preview ด้านล่าง — สังเกตว่า layout ยืดตามพื้นที่แต่ไม่เกิน max-width:
| หน่วย | หมายความว่า | ใช้เมื่อ |
|---|---|---|
| width: 100% | กว้างเท่า parent | ต้องการยืดเต็มพื้นที่ที่มี |
| max-width: 960px | กว้างได้ไม่เกิน 960px | จำกัดไม่ให้ยืดเกินไป |
| width: 80% | กว้าง 80% ของ parent | ต้องการ gap รอบข้าง |
| 1fr (Grid) | หนึ่งส่วนของพื้นที่เหลือ | แบ่งพื้นที่ grid อย่างยืดหยุ่น |
| vw | % ของความกว้างหน้าจอ | ต้องการอิง viewport โดยตรง |
การทำงานทีละขั้นตอน
วิธีเปลี่ยน layout จาก fixed เป็น fluid:
- 1. ระบุ element ที่ใช้ค่า px ตายตัว — มองหา width: 900px หรือ width: 600px ที่อาจยืดหยุ่นได้
- 2. เปลี่ยน width ตายตัวเป็น width: 100% — ทำให้ element ยืดเต็มพื้นที่ parent
- 3. เพิ่ม max-width เพื่อจำกัดขอบเขต — ป้องกันไม่ให้กว้างเกินที่ layout ต้องการ
- 4. เพิ่ม padding หรือ margin ทั้งสองข้าง — ป้องกันเนื้อหาชนขอบหน้าจอบนมือถือ
- 5. ทดสอบในหลายขนาด — ลากขยาย browser ดูว่า layout ยืดได้ราบรื่นตลอดช่วง
ตัวอย่างที่ 1 — Container ยืดหยุ่น
รูปแบบ container ที่ใช้บ่อยที่สุดใน web development — ยืดเต็มหน้าจอแต่จำกัด max-width เพื่อความอ่านง่าย:
ตัวอย่างที่ 2 — Card และ block ที่ไม่ใช้ความกว้างตายตัว
card ที่ใช้ fr และ % แทน px — ยืดตามพื้นที่อย่างราบรื่น ไม่มีช่องว่างเหลือทิ้ง:
ตัวอย่างที่ 3 — เปรียบเทียบ Fixed กับ Fluid layout
Fixed และ Fluid layout ให้ผลต่างกันอย่างชัดเจนเมื่อหน้าจอมีหลายขนาด:
fluid container ใช้ 3 บรรทัดหลัก: width: 100%, max-width, และ margin: 0 auto
/* ❌ Fixed layout — ปัญหาเมื่อหน้าจอแคบหรือกว้างมาก */
.fixed-container {
width: 960px; /* กว้างเกินบนมือถือ → scroll bar แนวนอน */
padding: 0 24px;
}
.fixed-card {
width: 280px; /* แคบเกินบน ultrawide ดูไม่ใช้พื้นที่ */
display: inline-block;
}
/* ✅ Fluid layout — ปรับตามพื้นที่ได้ดีทุกขนาด */
.fluid-container {
width: 100%; /* ยืดเต็มพื้นที่ที่มี */
max-width: 960px; /* ไม่กว้างเกินจนอ่านยาก */
margin: 0 auto; /* อยู่กึ่งกลางเมื่อจอกว้าง */
padding: 0 16px; /* ป้องกันชนขอบบนมือถือ */
box-sizing: border-box;
}
.fluid-card {
width: 100%; /* ยืดเต็ม column */
max-width: 320px; /* ไม่กว้างเกินไป */
/* หรือใช้ใน grid: */
/* grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); */
}จุดที่ผู้เริ่มต้นมักสับสน
- width: 100% กับ max-width ใช้แยกกันไม่ได้ — ทั้งสองต้องใช้คู่กัน width: 100% ทำให้ยืด max-width ทำให้หยุดที่ขอบเขต ขาดอย่างใดอย่างหนึ่งทำให้ layout พัง
- ลืม box-sizing: border-box — เมื่อใช้ width: 100% แล้วเพิ่ม padding element อาจกว้างเกิน 100% ได้ ต้องใส่ box-sizing: border-box เสมอเมื่อใช้ padding ร่วมกับ width: 100%
- fluid = ยืดอย่างไม่มีขอบเขต — ไม่ใช่ fluid ที่ดีต้องมี max-width เพื่อควบคุม ไม่เช่นนั้น text line จะยาวเกินอ่านยากบน ultrawide monitor
- % คิดจาก parent ไม่ใช่ viewport — width: 50% ของ element ที่มี parent กว้าง 600px คือ 300px ไม่ใช่ 50% ของหน้าจอ ถ้าต้องการ % ของหน้าจอต้องใช้ vw แทน
เปรียบเทียบ Fixed กับ Fluid layout
| Fixed Layout | Fluid Layout | |
|---|---|---|
| กำหนดความกว้างด้วย | px ตายตัว เช่น width: 960px | % หรือ fr เช่น width: 100% |
| พฤติกรรมบนจอแคบ | scroll bar แนวนอน | ยืบตามพื้นที่ |
| พฤติกรรมบนจอกว้าง | มีช่องว่างข้างๆ มาก | จำกัดด้วย max-width |
| ควบคุม | ง่าย — รู้ขนาดแน่นอน | ต้องการ max-width ร่วมด้วย |
| แนะนำสำหรับ | component เฉพาะเจาะจง (icon, button) | container, card, text block |
สรุปท้ายบทแบบจำง่าย
fluid layout = "ยืดตามพื้นที่ แต่มีขอบเขต" สูตรมาตรฐาน fluid container: width: 100% → max-width: Xpx → margin: 0 auto → padding: 0 16px
- ใช้ width: 100% แทน px ตายตัว — ทำให้ element ยืดตามพื้นที่ parent
- เพิ่ม max-width ทุกครั้ง — fluid ไม่ได้แปลว่าไม่มีขอบเขต ต้องจำกัดด้วย
- box-sizing: border-box เสมอ — ป้องกัน padding ทำให้กว้างเกิน 100%
Lab 1 — ทำ container ให้ยืดหยุ่น
โจทย์: .box มี width: 600px ตายตัว ทำให้ล้นหน้าจอบนมือถือ แก้ให้เป็น fluid container: - เปลี่ยน width: 600px เป็น width: 100% - เพิ่ม max-width: 600px - เพิ่ม box-sizing: border-box
Lab 2 — ใช้ width กับ max-width ให้เหมาะสม
โจทย์: .article เป็น text block ที่ต้องการ: - กว้างเต็มพื้นที่ แต่ไม่เกิน 680px (เพื่อความอ่านง่าย) - อยู่กึ่งกลางหน้าเมื่อจอกว้าง - มี padding ซ้าย-ขวา 20px เพื่อไม่ให้ชนขอบบนมือถือ - box-sizing: border-box
Lab 3 — แก้ layout ตายตัวให้ fluid มากขึ้น
โจทย์: .product-grid มี width: 900px ตายตัว ทำให้ล้นหน้าจอบนมือถือ แก้ให้เป็น fluid: 1. เปลี่ยน width: 900px เป็น width: 100% 2. เพิ่ม max-width: 900px 3. เพิ่ม box-sizing: border-box 4. เปลี่ยน .product-card จาก width: 260px เป็น flex: 1 1 240px (ยืดหดได้ใน flex container)