Flexbox: จัดของในแถว 1 มิติ
flexbox จบ 80% ของ layout สมัยใหม่ด้วย display:flex + 3 property หลัก (justify-content, align-items, gap) เข้าใจ main กับ cross axis mental model ก็พอใช้จริง
ถึงจุดนี้เราเข้าใจแล้วว่าแต่ละ element เป็นกล่อง 4 ชั้น คำถามถัดไปคือจะ จัดกล่องหลายๆ อัน ให้อยู่ในตำแหน่งที่ต้องการยังไง เรียงแนวนอน เรียงแนวตั้ง กลางจอ หรือชิดขวา
สมัยก่อน (ก่อนปี 2015) คนใช้ float, table, position: absolute จัด layout ซึ่งทรมานมาก แฮ็คเยอะ พังบ่อย วันนี้ไม่ต้องทำแบบนั้นแล้ว เพราะ CSS มี Flexbox ให้ใช้
บทนี้จะไม่สอน property ทั้ง 15 ตัวของ flexbox เพราะ 80% ของ layout สมัยใหม่ ใช้แค่ 3 property กับ 1 concept สำคัญเท่านั้น รู้เท่านี้ก็พอจัด layout เว็บได้สบาย
เปิด Flexbox ด้วย display: flex
กฎข้อแรกคือทุกอย่างของ flexbox เริ่มที่ parent ไม่ใช่ลูก ใส่ display: flex ที่ parent แล้วลูกทุกตัวจะกลายเป็น "flex item" โดยอัตโนมัติ
.container {
display: flex;
}
/* children ไม่ต้องทำอะไร กลายเป็น flex item เอง */พอเปิด flex แล้ว 2 สิ่งจะเปลี่ยนทันที:
- ลูกที่เคยวางเรียงแนวตั้ง (block default) จะกลายเป็น แนวนอน
- ลูกทุกตัวสูงเท่ากันอัตโนมัติ (เท่ากับลูกที่สูงที่สุด)
Concept ที่ต้องเข้าใจก่อนคือเรื่อง 2 แกน
Flexbox มี 2 แกนที่ตั้งฉากกัน:
- Main axis คือทิศทางที่ items เรียง (default คือแนวนอนซ้ายไปขวา)
- Cross axis คือทิศตั้งฉากกับ main (default คือแนวตั้งบนลงล่าง)
กฎสำคัญคือ ทุก property ใน flexbox อ้างอิงจาก axis ไม่ใช่ทิศทางจริงjustify-content คือ "จัดยังไงตาม main axis"align-items คือ "จัดยังไงตาม cross axis"
ลองเล่นดู กดสลับ direction ดูว่า axis หมุนตามอย่างไร:
.container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
gap: 12px;
}justify-contentCross axis คือทิศตั้งฉากกับ main ควบคุมด้วย
align-itemsลอง switch direction ดู ลูกศรข้างบนจะหมุนตาม แปลว่าทุก property อื่นความหมายก็สลับไปด้วย
3 property ที่ใช้จริงถึง 80%
สามตัวที่ต้องจำให้แม่น เพราะใช้ทุก project:
1. justify-content จัด items ตาม main axis
flex-start(default) คือชิดต้น main axiscenterคือกลาง main axisflex-endคือชิดท้ายspace-betweenคือตัวแรกกับตัวสุดท้ายชิดขอบ ที่เหลือห่างเท่าๆ กันspace-aroundคือห่างเท่ากันรวมขอบด้วย
2. align-items จัด items ตาม cross axis
flex-start,center,flex-endใช้เหมือน justify-contentstretch(default) คือ items ยืดเต็ม cross axis (ถ้าไม่ได้ fix ขนาด)
3. gap ช่องว่างระหว่าง items
.container {
display: flex;
gap: 16px; /* เพิ่มพื้นที่ระหว่างทุก item โดยไม่ต้องใช้ margin */
}สมัยก่อนต้องใช้ margin-right บน item (ยกเว้นตัวสุดท้าย) ซึ่งรกมาก ปัจจุบัน gap จบในบรรทัดเดียว
Flex-grow แบ่งพื้นที่ที่เหลือ
เมื่อ container กว้างกว่า items รวมกัน จะเหลือพื้นที่ว่าง flex-grow คือตัวบอกว่าลูกแต่ละคนควร "ขยาย" เอาพื้นที่เหลือไปใช้ยังไง
flex-grow เป็น สัดส่วน ไม่ใช่ขนาด ถ้า A grow=1 กับ B grow=2 แปลว่า B ได้พื้นที่เหลือ 2 เท่าของ A
• grow =
0 → item นี้ไม่ขยาย (ใช้ขนาด content หรือ flex-basis เท่านั้น)• grow =
1 ทุกตัว → แบ่งพื้นที่เหลือเท่าๆ กัน• grow =
2 ตัวหนึ่ง, 1 อีกตัว → ตัว grow 2 ได้พื้นที่ 2xPattern ที่ใช้ทุกวัน
จำ pattern พวกนี้ได้ flexbox คุณใช้ได้แล้ว 80%:
จัดปุ่มให้อยู่ตรงกลางจอ
.parent {
display: flex;
justify-content: center; /* กลางแนวนอน */
align-items: center; /* กลางแนวตั้ง */
min-height: 100vh;
}Navbar logo ซ้าย เมนูขวา
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
}Sidebar กับ content (fill rest)
.app { display: flex; }
.sidebar { width: 240px; }
.content { flex-grow: 1; }กล่อง cards เรียงแนวนอน ห่างเท่ากัน
.cards {
display: flex;
gap: 16px;
}สรุป
- Flexbox เริ่มด้วย
display: flexที่ parent แล้วลูกจะกลายเป็น flex item อัตโนมัติ - มี 2 แกนคือ main (ทิศที่ items เรียง) และ cross (ตั้งฉาก) เปลี่ยนด้วย
flex-direction - 3 property ที่ใช้ 80% คือ
justify-content(main),align-items(cross) และgap(ระยะห่าง) flex-growคือสัดส่วนของพื้นที่เหลือ ไม่ใช่ขนาด- Flexbox จัดของใน 1 มิติ เช่น bar, toolbar, cards แถวเดียว ถ้าต้องการ 2 มิติให้ใช้ Grid
บทถัดไปคือ Typography กับ Color เราจะได้รู้ว่าทำไม default ของ browser ถึงน่าเกลียด และแค่ 5 rule ง่ายๆ ก็ทำให้เว็บดูเหมือนถูก design แล้ว พร้อมกับเรื่อง WCAG contrast ที่เช็คว่าเว็บเราอ่านได้จริงหรือเปล่า