06: The Box Model & Layout

เข้าใจโครงสร้าง Box Model พื้นฐานสำคัญที่สุดของการจัดหน้าเว็บ

1. The Box Model

ในสายตาของ CSS "ทุกอย่างบนหน้าเว็บคือกล่องสี่เหลี่ยม" (Box) ซึ่งประกอบด้วย 4 ชั้นเหมือนหัวหอม

CSS Box Model
  • 1. Content (เนื้อหา): สิ่งที่อยู่ข้างในสุด เช่น ข้อความ, รูปภาพ
  • 2. Padding (เบาะกันกระแทก): พื้นที่ว่างระหว่าง Content กับขอบ (ขยายขนาดกล่อง)
  • 3. Border (กล่องพัสดุ): เส้นขอบที่หุ้มรอบ Padding
  • 4. Margin (ระยะห่าง): พื้นที่ว่างภายนอก ใช้ผลักออกจาก Element อื่น
จำง่ายๆ:
อยากดันของข้างในให้หลวม ๆ ใช้ padding
อยากดันตัวเองออกจากคนอื่น ใช้ margin
CSS Box Model
.box {
  width: 200px;         /* ความกว้าง Content */
  padding: 20px;        /* เพิ่มความอ้วนให้กล่อง 20px รอบตัว */
  border: 5px solid black; /* ความหนาขอบ */
  margin: 30px;         /* เว้นระยะห่างจากเพื่อน 30px */
}
เจาะลึกการเขียน Margin & Padding

สามารถกำหนดค่าได้ 2 แบบ คือ "ระบุเฉพาะด้าน" หรือ "เขียนรวบยอด (Shorthand)"

แบบระบุเฉพาะด้าน (Specific Side)

ใช้เมื่อต้องการแก้แค่บางด้าน

CSS
.box {
  /* กำหนดทีละด้าน (Top, Right, Bottom, Left) */
  margin-top: 10px;
  margin-right: 20px;
  padding-left: 15px;
  border-bottom: 5px solid red;
}
แบบย่อ (Shorthand)

วนตามเข็มนาฬิกา: บน → ขวา → ล่าง → ซ้าย

CSS
.box {
  /* 4 ค่า: บน ขวา ล่าง ซ้าย */
  margin: 10px 20px 30px 40px;

  /* 2 ค่า: (บน-ล่าง) (ซ้าย-ขวา) */
  padding: 20px 50px;
  
  /* 1 ค่า: เท่ากันทุกด้าน */
  padding: 20px;
}
เรื่องของ Border (เส้นขอบ)

Border มีความพิเศษคือต้องระบุ 3 อย่างเสมอ: ขนาด, รูปแบบ, สี

เขียนเต็ม (Full)
border-width: 5px;
border-style: solid; /* solid, dashed, dotted */
border-color: black;
เขียนย่อ (Shorthand)
/* นิยมใช้แบบนี้ที่สุด */
border: 5px solid black;

/* ระบุเฉพาะด้านก็ได้ */
border-bottom: 2px dashed red;

2. Display Property

คำสั่ง display กำหนดพฤติกรรมการวางตัวของกล่อง ว่าจะยอมให้ Element อื่นมาอยู่ข้าง ๆ หรือไม่

ค่า (Value) พฤติกรรม ตัวอย่าง Tag
block จอมบงการ
- กว้างเต็ม 100% เสมอ
- ขึ้นบรรทัดใหม่เสมอ (ไม่ยอมให้ Element อื่นมาอยู่บนบรรทัดเดียวกัน)
<div>, <p>, <h1>
inline เจียมเนื้อเจียมตัว
- Element อื่นอยู่ในบรรทัดเดียวกันได้
- กว้างเท่าข้อความข้างใน
- ตั้งค่า width/height/margin บน-ล่าง ไม่ได้
<span>, <a>
inline-block ลูกผสม (เทพสุด)
- อยู่บรรทัดเดียวกันได้ (เหมือน inline)
- แต่ตั้งค่า width/height ได้ครบ (เหมือน block)
<img>, <button>
none หายตัวไปเลย (พื้นที่ก็ไม่เหลือ) (ใช้ซ่อน Element)
ทำไมต้อง Inline-Block
แบบ Inline

สังเกตว่า width, height และ margin-top จะไม่ทำงานเลย ทำให้ปุ่มดูบี้แบน

ปุ่ม 1 ปุ่ม 2
CSS
.btn {
	display: inline; /* พลาดตรงนี้! */
	width: 100px;    /* ไม่ทำงาน */
	height: 50px;    /* ไม่ทำงาน */
	margin-top: 20px;/* ไม่ทำงาน */
}
แบบ Inline-Block

ปุ่มอยู่บรรทัดเดียวกันได้ และขยายขนาดได้ตามสั่งเหมือนกล่องปกติ

ปุ่ม 1 ปุ่ม 2
CSS
.btn {
	display: inline-block; /* ถูกต้อง! */
	width: 100px;    /* ทำงาน */
	height: 50px;    /* ทำงาน */
	margin-top: 20px;/* ทำงาน */
}
💡 เกร็ดความรู้: display: none vs visibility: hidden
  • display: none = หายไปเลย พื้นที่ก็หายไปด้วย (เหมือนไม่เคยมีอยู่)
  • visibility: hidden = มองไม่เห็น แต่ยังกินพื้นที่อยู่ (เหมือนใส่ผ้าคลุมล่องหน)

3. Backgrounds

การจัดการพื้นหลัง การทำภาพเปิดเว็บให้เต็มจอ ไม่ว่าจะเปิดบนมือถือหรือคอมพิวเตอร์ โดยใช้ background-size: cover

แบบ Contain (ไม่เต็ม)

ภาพจะหดตัวเพื่อให้เห็นครบใบ (เกิดพื้นที่ว่าง)

background-size: contain;
แบบ Cover (เต็มพื้นที่)

ภาพขยายเต็มกรอบ ส่วนเกินจะถูกตัดออก (Crop)

background-size: cover;
Combo Set
CSS
.hero-banner {
  /* 1. ใส่รูปพื้นหลัง */
  background-image: url('banner.jpg');
  
  /* 2. ขยายให้เต็มพื้นที่ (ส่วนเกินตัดทิ้ง) */
  background-size: cover;
  
  /* 3. จัดภาพให้อยู่กึ่งกลางเสมอ */
  background-position: center;
  
  /* 4. ความสูงเต็มหน้าจอพอดี */
  height: 100vh;
  
  /* 5. จัดข้อความให้อยู่กลางจอ */
  display: flex;
  align-items: center;
  justify-content: center;
}
เจาะลึกคำสั่งสำคัญ:
  • background-position: center: สำคัญมาก! เพราะถ้าไม่ใส่ CSS จะยึดมุม "ซ้ายบน" เป็นหลัก ทำให้เวลาขยายรูป จุดโฟกัส (เช่น หน้าคน) อาจหลุดขอบจอไป
  • height: 100vh: Viewport Height คือหน่วยวัดความสูงของหน้าจอ 100vh คือ 100% ของหน้าจอที่เปิดอยู่ขณะนั้น ทำให้แบนเนอร์เต็มพื้นที่ความสูงพอดี
Pro Tip: เทคนิคซ้อนเลเยอร์สีดำ

ปัญหาภาพพื้นหลังสวย แต่ตัวหนังสือไม่ชัด (จมไปกับภาพ) แก้ด้วยการใส่ Linear Gradient สีดำโปร่งใสทับลงไป

CSS
.hero-banner {
  /* ใส่ Gradient สีดำโปร่งใส (0.5) ซ้อนทับรูป */
  background-image: 
    linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
    url('banner.jpg');
    
  color: white; /* ตัวหนังสือจะเห็นชัดขึ้น */
}

Workshop: จัดระยะห่างให้หายอึดอัด

กลับไปที่ไฟล์ style.css (ของ travel.html) แล้วเพิ่มโค้ดเพื่อจัด Layout:

  • 1. เพิ่ม padding: 40px; ให้กับ body หรือ container หลัก (ไม่ให้เนื้อหาติดขอบจอ)
  • 2. เพิ่ม margin-bottom: 20px; ให้กับ h1, p และรูปภาพ (ให้หายใจได้สะดวก)
  • 3. แต่งปุ่ม Link (a) ให้ดูเหมือนปุ่มจริง:
    • display: inline-block; (เพื่อให้ใส่ padding ได้)
    • padding: 10px 20px; (เพิ่มความอ้วน)
    • background-color: ...; (ใส่สีพื้นหลัง)
    • text-decoration: none; (เอาขีดเส้นใต้ออก)

Practice Mission: สร้างหน้า Pricing Plan ให้ "StreamFLIX"
บรีฟจากลูกค้า (CEO StreamFLIX):

"บริษัทกำลังจะเปิดตัวแอปดูหนัง อยากได้หน้าเว็บแสดงแพ็กเกจราคา 3 ระดับ (Basic, Standard, Premium) ขอให้แต่ละกล่องดูไม่อึดอัด มีขอบสวยงาม และกล่อง Premium ต้องดูเด่นกว่าแพ็กเกจอื่น ๆ"

1. โครงสร้าง HTML (สร้างไฟล์ pricing.html)

สร้างกล่องสินค้า (Div) 3 กล่อง โดยแต่ละกล่องต้องมี:

  • Class: ทุกกล่องใช้ class .card เหมือนกัน
  • Content:
    • ชื่อแพ็กเกจ (h2) เช่น Basic
    • ราคา (h3) เช่น 199 บาท
    • รายการฟีเจอร์ (ul > li) เช่น "ดูได้ 1 จอ", "ความชัด HD"
    • ปุ่มซื้อ (a class="btn")
  • พิเศษ: กล่อง Premium ให้เพิ่ม class .popular เข้าไปอีกตัว (เป็น 2 classes)
2. ตกแต่ง CSS (Margin, Padding, Border)

เชื่อมไฟล์ CSS แล้วจัดการ Box Model ดังนี้:

  • ขนาด (.card): กำหนดความกว้าง 300px และจัดกึ่งกลางหน้าจอ (ใช้ margin: 20px auto;)
  • พื้นที่ภายใน (.card): ขนาด 30px เพื่อไม่ให้ตัวหนังสือเบียดขอบ
  • เส้นขอบ (.card): เป็นสีเทาบางๆ และทำมุมมน (border-radius)
  • ปุ่ม (.btn): ใส่พื้นที่ขอบในเพื่อให้ปุ่มมีขนาดใหญ่ขึ้น และใส่พื้นที่ขอบนอกทางด้านบน เพื่อดันให้ห่างจากรายการสินค้า
3. เน้นกล่อง Premium (.popular)

ใช้ Class ที่ 2 มาทับ (Override) ค่า Box Model เพื่อให้เด่นขึ้น:

  • Border: เปลี่ยนเส้นขอบให้หนาขึ้น (เช่น 4px) และเป็นสีทอง (Gold) หรือสีส้ม
  • Effect: ลองใส่ Shadow หรือเปลี่ยนสีพื้นหลังให้ดูพรีเมียม