06: The Box Model & Layout
เข้าใจโครงสร้าง Box Model พื้นฐานสำคัญที่สุดของการจัดหน้าเว็บ
1. The Box Model
ในสายตาของ CSS "ทุกอย่างบนหน้าเว็บคือกล่องสี่เหลี่ยม" (Box) ซึ่งประกอบด้วย 4 ชั้นเหมือนหัวหอม
- 1. Content (เนื้อหา): สิ่งที่อยู่ข้างในสุด เช่น ข้อความ, รูปภาพ
- 2. Padding (เบาะกันกระแทก): พื้นที่ว่างระหว่าง Content กับขอบ (ขยายขนาดกล่อง)
- 3. Border (กล่องพัสดุ): เส้นขอบที่หุ้มรอบ Padding
- 4. Margin (ระยะห่าง): พื้นที่ว่างภายนอก ใช้ผลักออกจาก Element อื่น
อยากดันของข้างในให้หลวม ๆ ใช้
paddingอยากดันตัวเองออกจากคนอื่น ใช้
margin
.box {
width: 200px; /* ความกว้าง Content */
padding: 20px; /* เพิ่มความอ้วนให้กล่อง 20px รอบตัว */
border: 5px solid black; /* ความหนาขอบ */
margin: 30px; /* เว้นระยะห่างจากเพื่อน 30px */
}
เจาะลึกการเขียน Margin & Padding
สามารถกำหนดค่าได้ 2 แบบ คือ "ระบุเฉพาะด้าน" หรือ "เขียนรวบยอด (Shorthand)"
แบบระบุเฉพาะด้าน (Specific Side)
ใช้เมื่อต้องการแก้แค่บางด้าน
.box {
/* กำหนดทีละด้าน (Top, Right, Bottom, Left) */
margin-top: 10px;
margin-right: 20px;
padding-left: 15px;
border-bottom: 5px solid red;
}
แบบย่อ (Shorthand)
วนตามเข็มนาฬิกา: บน → ขวา → ล่าง → ซ้าย
.box {
/* 4 ค่า: บน ขวา ล่าง ซ้าย */
margin: 10px 20px 30px 40px;
/* 2 ค่า: (บน-ล่าง) (ซ้าย-ขวา) */
padding: 20px 50px;
/* 1 ค่า: เท่ากันทุกด้าน */
padding: 20px;
}
เรื่องของ Border (เส้นขอบ)
Border มีความพิเศษคือต้องระบุ 3 อย่างเสมอ: ขนาด, รูปแบบ, สี
border-width: 5px;
border-style: solid; /* solid, dashed, dotted */
border-color: black;
/* นิยมใช้แบบนี้ที่สุด */
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 จะไม่ทำงานเลย ทำให้ปุ่มดูบี้แบน
.btn {
display: inline; /* พลาดตรงนี้! */
width: 100px; /* ไม่ทำงาน */
height: 50px; /* ไม่ทำงาน */
margin-top: 20px;/* ไม่ทำงาน */
}
แบบ Inline-Block
ปุ่มอยู่บรรทัดเดียวกันได้ และขยายขนาดได้ตามสั่งเหมือนกล่องปกติ
.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
.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 สีดำโปร่งใสทับลงไป
.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 หรือเปลี่ยนสีพื้นหลังให้ดูพรีเมียม