กลับหน้าบทเรียน
Export PDF
# สัปดาห์ที่ 4 CSS Layout: Flexbox และ Grid --- ## เป้าหมายบทเรียน - เข้าใจ Normal Flow และ `display` - ใช้ Flexbox จัด layout มิติเดียว - อธิบาย Main Axis และ Cross Axis - ใช้ CSS Grid จัด layout สองมิติ - สร้าง responsive layout - ใช้ Media Queries และ DevTools ตรวจ layout --- ## Layout Problem เราต้องจัดตำแหน่งองค์ประกอบให้สัมพันธ์กับพื้นที่จริงของหน้าจอ --- ## 1. Normal Flow ถ้าไม่กำหนด layout พิเศษ เบราว์เซอร์จะวาง element ตามลำดับ HTML - block เรียงจากบนลงล่าง - inline ไหลไปตามบรรทัดข้อความ - พื้นที่และลำดับมาจาก document structure --- ## Display | `display` | พฤติกรรม | |---|---| | `block` | ขึ้นบรรทัดใหม่ กินแนวกว้าง | | `inline` | อยู่ในบรรทัดเดียว | | `inline-block` | อยู่ในบรรทัด แต่กำหนดขนาดได้ | | `none` | ไม่แสดงผล | | `flex` | เปิด Flexbox | | `grid` | เปิด CSS Grid | --- ## ตัวอย่าง Normal Flow ```html
หัวข้อหลัก
ย่อหน้าที่หนึ่ง
ย่อหน้าที่สอง
Link ที่หนึ่ง
Link ที่สอง
``` --- ## เปลี่ยนพฤติกรรมด้วย display ```css .tag { display: inline-block; padding: 4px 10px; border: 1px solid #d1d5db; border-radius: 999px; } .hidden { display: none; } ``` --- ## 2. Flex Container และ Flex Items Flexbox เริ่มทำงานเมื่อ parent มี `display: flex` ```html
Home
Courses
Contact
``` ```css .nav { display: flex; gap: 16px; align-items: center; } ``` --- ## Flexbox เหมาะกับ layout มิติเดียว ```css .nav { display: flex; gap: 12px; justify-content: space-between; } ``` --- ## Flex Container Properties - `flex-direction` - `justify-content` - `align-items` - `gap` - `flex-wrap` --- ## Flex Item Properties - `flex` - `flex-grow` - `flex-shrink` - `flex-basis` - `align-self` --- ## Card Row ```css .card-row { display: flex; gap: 16px; } .card { flex: 1; padding: 16px; border: 1px solid #d1d5db; } ``` --- ## flex-wrap ```css .toolbar { display: flex; flex-wrap: wrap; gap: 8px; } ``` ใช้เมื่อ item มีหลายชิ้นและพื้นที่แนวนอนไม่พอ --- ## 3. Main Axis และ Cross Axis ```mermaid flowchart LR A[Main Axis] --> B[ทิศทางตาม flex-direction] C[Cross Axis] --> D[แกนตั้งฉากกับ main axis] ``` --- ## flex-direction: row ```css .nav { display: flex; flex-direction: row; justify-content: space-between; align-items: center; } ``` - `justify-content` จัดแนวนอน - `align-items` จัดแนวตั้ง --- ## flex-direction: column ```css .sidebar { display: flex; flex-direction: column; gap: 12px; align-items: stretch; } ``` เมื่อเป็น column, main axis เปลี่ยนเป็นแนวตั้ง --- ## จัดกลางทั้งสองแกน ```css .center-box { min-height: 240px; display: flex; justify-content: center; align-items: center; } ``` --- ## 4. CSS Grid เหมาะกับ layout สองมิติ ทั้งแถวและคอลัมน์ ```css .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; } ``` --- ## Grid Vocabulary | คำ | ความหมาย | |---|---| | Grid Container | element ที่ใช้ `display: grid` | | Grid Item | ลูกโดยตรงของ grid container | | Track | แถวหรือคอลัมน์ | | Gap | ช่องว่างระหว่าง track | | Grid Area | พื้นที่ที่ตั้งชื่อได้ | --- ## Responsive Card Grid ```css .course-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; } ``` `auto-fit` และ `minmax()` ช่วยปรับจำนวนคอลัมน์อัตโนมัติ --- ## Grid Areas ```css .page { display: grid; grid-template-areas: "header header" "sidebar main" "footer footer"; grid-template-columns: 240px 1fr; gap: 16px; } .header { grid-area: header; } .sidebar { grid-area: sidebar; } .main { grid-area: main; } .footer { grid-area: footer; } ``` --- ## Grid Areas ทำให้เห็นภาพหน้า ```mermaid flowchart TB H[header header] --> SM[sidebar | main] SM --> F[footer footer] ``` --- ## 5. Responsive Layout Responsive Layout คือการทำให้หน้าเว็บใช้งานได้ดีบนหลายขนาดหน้าจอ - Mobile first - Fluid layout - Content first - Flexible images --- ## Flexible Images ```css img { max-width: 100%; height: auto; } ``` รูปภาพไม่ควรล้น container --- ## Responsive Container ```css .container { width: min(100% - 32px, 960px); margin-inline: auto; } ``` อ่านง่ายบนจอเล็กและไม่กว้างเกินไปบนจอใหญ่ --- ## Grid โดยไม่ต้องใช้ Media Query ```css .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; } ``` --- ## 6. Media Queries ใช้เปลี่ยน layout เมื่อหน้าจอเข้าเงื่อนไขที่กำหนด ```css .layout { display: grid; gap: 16px; } @media (min-width: 768px) { .layout { grid-template-columns: 240px 1fr; } } ``` --- ## Navigation แบบ Mobile First ```css .nav { display: flex; flex-direction: column; gap: 8px; } @media (min-width: 640px) { .nav { flex-direction: row; justify-content: space-between; align-items: center; } } ``` --- ## เลือก Breakpoint อย่างไร 1. เริ่มจากเนื้อหาจริงบน mobile 2. ขยายหน้าจอจน layout เริ่มแน่น 3. ตั้ง breakpoint ตรงจุดที่ต้องเปลี่ยน layout 4. หลีกเลี่ยง breakpoint มากเกินจำเป็น --- ## 7. Layout Debugging ด้วย DevTools ใช้ DevTools ตรวจ - HTML structure - CSS rule ที่ถูกใช้หรือถูกขีดทับ - Box Model - Flex/Grid overlay - Device Mode --- ## Debug Flow ```mermaid flowchart LR Inspect[Inspect Element] --> Styles[Check Styles] Styles --> Box[Box Model] Box --> Overlay[Flex/Grid Overlay] Overlay --> Device[Device Mode] ``` --- ## ปัญหาที่พบบ่อย | ปัญหา | จุดที่ควรตรวจ | |---|---| | item ไม่เรียง | `display`, `flex-direction`, grid columns | | ระยะห่างแปลก | `margin`, `padding`, `gap` | | element ล้นจอ | `width`, `min-width`, image | | media query ไม่ทำงาน | syntax, breakpoint, viewport meta | --- ## Debug Outline ชั่วคราว ```css * { outline: 1px solid rgba(37, 99, 235, 0.35); } ``` ใช้ดูขอบเขต element แล้วลบออกก่อนส่งงาน --- ## Checklist ก่อนส่งงาน Layout - ใช้ normal flow เมื่อเพียงพอ - ใช้ Flexbox กับ layout มิติเดียว - ใช้ Grid กับ layout สองมิติ - ใช้ `gap` ใน flex/grid - รูปภาพไม่ล้น container - ทดสอบ mobile, tablet, desktop - ใช้ media query เมื่อจำเป็น - ตรวจด้วย DevTools --- ## กิจกรรม สร้าง card layout ที่ปรับตามขนาดหน้าจอ --- ## คำถามท้ายบท 1. Normal Flow ช่วยให้ layout พื้นฐานทำงานอย่างไร 2. Flexbox เหมาะกับ layout แบบใด 3. Grid เหมาะกับ layout แบบใด 4. Main Axis เปลี่ยนอย่างไรเมื่อใช้ `flex-direction: column` 5. ควรตั้ง breakpoint จากอะไร