Article · programming
HTML & CSS EP3: CSS Selectors — เลือกองค์ประกอบและตกแต่งเว็บไซต์อย่างเป็นระบบ
HTML & CSS
เรียนรู้ CSS Selectors วิธีเลือกองค์ประกอบ HTML ด้วย element, class, id, descendant, pseudo-class และการจัดลำดับความสำคัญของ CSS พร้อมตัวอย่างภาพรวมและหน้าเว็บฉบับเต็มที่คัดลอกไปเปิดในเบราว์เซอร์ได้ทันที
EP3: CSS Selectors — เลือกองค์ประกอบและตกแต่งเว็บไซต์อย่างเป็นระบบ
CSS ไม่ได้มีหน้าที่เพียงกำหนดสีและขนาดตัวอักษร แต่ยังช่วยควบคุมรูปลักษณ์ขององค์ประกอบแต่ละส่วนในหน้าเว็บด้วย หัวใจสำคัญอย่างหนึ่งคือ Selector ซึ่งเป็นตัวกำหนดว่าเราต้องการนำกฎ CSS ไปใช้กับ HTML ส่วนใด หากเลือก Selector ได้ถูกต้อง เราจะสามารถตกแต่งหัวข้อ ปุ่ม การ์ด เมนู และข้อความเฉพาะส่วนได้ โดยไม่ต้องเขียนรูปแบบซ้ำไปซ้ำมา บทความนี้จะอธิบายแนวคิดทีละขั้น พร้อมตัวอย่างที่สามารถคัดลอกไปทดลองได้
1. CSS Selector คืออะไร
Selector คือส่วนหนึ่งของกฎ CSS ที่ใช้เลือกองค์ประกอบ HTML ที่ต้องการตกแต่ง เช่น เลือกหัวข้อทั้งหมด เลือกองค์ประกอบที่มี class เฉพาะ หรือเลือกปุ่มที่อยู่ภายในกล่องใดกล่องหนึ่ง เมื่อ Selector ตรงกับองค์ประกอบ เบราว์เซอร์จะนำชุดคำสั่ง CSS ที่เกี่ยวข้องไปใช้กับองค์ประกอบนั้น
HTML ตัวอย่างสำหรับทดลอง CSS Selector
<h1>ยินดีต้อนรับ</h1>
<p>ข้อความทั่วไปบนหน้าเว็บ</p>
<p class="highlight">ข้อความที่ต้องการเน้น</p>
<button id="main-button">เริ่มต้นใช้งาน</button>
โค้ดนี้เป็นเพียง HTML บางส่วน ยังไม่มี CSS และไม่ได้เป็นหน้าเว็บฉบับเต็ม จึงกำหนด preview_mode เป็น เฉพาะcode เพื่อแสดงโค้ดโดยไม่พยายามเรนเดอร์ผลลัพธ์แยกจากเอกสารจริง
2. เลือกด้วยชื่อ Element
การเลือกด้วยชื่อ Element เป็นรูปแบบพื้นฐานที่สุด เช่น h1, p, button หรือ section หากกำหนด CSS ให้ p ทุกย่อหน้าที่ตรงกับ Selector นี้จะได้รับรูปแบบเดียวกัน วิธีนี้เหมาะกับการตั้งค่าพื้นฐานของเว็บไซต์ เช่น รูปแบบตัวอักษรของย่อหน้า หรือระยะห่างของหัวข้อ แต่หากต้องการตกแต่งเฉพาะบางย่อหน้า ควรเลือกใช้ class แทน
เลือกองค์ประกอบด้วยชื่อแท็ก
body {
font-family: Tahoma, Arial, sans-serif;
color: #1e293b;
}
h1 {
color: #4338ca;
font-size: 36px;
}
p {
font-size: 16px;
line-height: 1.8;
}
ตัวอย่างนี้กำหนดฟอนต์และสีข้อความหลักที่ body แล้วตั้งสีและขนาดให้ h1 ส่วน p จะมีขนาดตัวอักษร 16 พิกเซลและระยะห่างบรรทัด 1.8 โค้ด CSS นี้เป็นชุดกฎที่ต้องใช้ร่วมกับ HTML จึงแสดงเฉพาะโค้ด
3. เลือกด้วย Class
Class ใช้จัดกลุ่มองค์ประกอบที่ต้องการให้มีรูปแบบเดียวกัน โดยใน HTML จะเขียน class="ชื่อคลาส" และใน CSS จะใช้เครื่องหมายจุดนำหน้าชื่อคลาส เช่น .highlight คลาสเดียวกันสามารถนำไปใช้กับองค์ประกอบหลายรายการได้ จึงเหมาะสำหรับปุ่ม การ์ด ป้ายสถานะ และข้อความที่ต้องการเน้น
กำหนด Class ให้ HTML
<p class="highlight">ข้อความสำคัญ</p>
<p>ข้อความปกติ</p>
<div class="highlight">กล่องที่ต้องการเน้น</div>
ตกแต่งองค์ประกอบที่มี Class
.highlight {
color: #4338ca;
background: #eef2ff;
padding: 10px 14px;
border-radius: 10px;
}
เมื่อใช้กฎ .highlight องค์ประกอบทั้งสองที่มี class="highlight" จะได้รับสีพื้นหลัง สีตัวอักษร และระยะห่างตามที่กำหนด ส่วนย่อหน้าที่ไม่มีคลาสนี้จะไม่รับกฎดังกล่าวโดยตรง นี่คือเหตุผลที่ class เหมาะกับการนำรูปแบบเดิมกลับมาใช้ซ้ำ
4. เลือกด้วย ID
ID ใช้ระบุองค์ประกอบเฉพาะรายการหนึ่งในเอกสาร และใน CSS จะใช้เครื่องหมาย # นำหน้าชื่อ ID เช่น #main-button โดยทั่วไปควรกำหนด ID แต่ละค่าให้ไม่ซ้ำกันภายในหน้าเดียวกัน เหมาะกับจุดที่มีเอกลักษณ์เฉพาะ เช่น ส่วนหลักของหน้า หรือองค์ประกอบที่เป็นเป้าหมายของลิงก์ภายใน
ตัวอย่างองค์ประกอบที่มี ID
<button id="main-button">เริ่มต้นใช้งาน</button>
กำหนดรูปแบบให้ ID
#main-button {
color: #ffffff;
background: #4338ca;
padding: 12px 20px;
border: 0;
border-radius: 10px;
}
ควรใช้ Class หรือ ID ดีใช้ class เมื่อรูปแบบเดียวกันสามารถใช้กับหลายองค์ประกอบ เช่น ปุ่มหลายปุ่มหรือการ์ดหลายใบ ใช้ id เมื่อจำเป็นต้องอ้างถึงองค์ประกอบที่มีเอกลักษณ์เฉพาะในเอกสาร และอย่าใช้ id ซ้ำโดยไม่จำเป็น
5. Universal Selector
Universal Selector ใช้เครื่องหมายดอกจัน * เพื่อเลือกองค์ประกอบทั้งหมดที่ตรงกับขอบเขตการเลือก มักใช้ตั้งค่าพื้นฐาน เช่น box-sizing เพื่อให้การคำนวณความกว้างและความสูงขององค์ประกอบเข้าใจง่ายขึ้น อย่างไรก็ตาม การใช้กฎกับทุกองค์ประกอบควรเลือกคุณสมบัติอย่างระมัดระวัง เพราะบางคุณสมบัติอาจไม่เหมาะกับทุกแท็ก
ตั้งค่าพื้นฐานด้วย Universal Selector
* {
box-sizing: border-box;
}
body {
margin: 0;
}
เมื่อกำหนด box-sizing: border-box ขนาดที่กำหนดให้ width และ height จะรวมพื้นที่ padding และ border เข้าไปด้วย ช่วยลดปัญหาที่องค์ประกอบกว้างเกินกว่าค่าที่ระบุ ส่วน margin: 0 ที่ body ช่วยลบระยะขอบเริ่มต้นของเบราว์เซอร์
6. Descendant Selector: เลือกองค์ประกอบที่อยู่ภายใน
บางครั้งเราไม่ต้องการเลือกทุกปุ่มในหน้าเว็บ แต่ต้องการเลือกเฉพาะปุ่มที่อยู่ภายในกล่องที่กำหนด Descendant Selector ทำได้ด้วยการเขียน Selector ขององค์ประกอบภายนอก ตามด้วยช่องว่าง และ Selector ขององค์ประกอบภายใน เช่น .card p จะเลือกย่อหน้าที่อยู่ภายในองค์ประกอบที่มีคลาส card
เลือกย่อหน้าภายใน Card
.card p {
color: #64748b;
line-height: 1.8;
}
.card h2 {
color: #1e293b;
margin-top: 0;
}
Selector .card p ไม่ได้หมายถึงองค์ประกอบ p ทั้งหมดในเว็บไซต์ แต่หมายถึง p ที่เป็นลูกหลานขององค์ประกอบ .card วิธีนี้ช่วยแยกรูปแบบตามพื้นที่และลดผลกระทบต่อส่วนอื่นของหน้าเว็บ
7. Grouping Selector: ใช้กฎร่วมกัน
หากองค์ประกอบหลายประเภทต้องใช้กฎชุดเดียวกัน สามารถเขียน Selector คั่นด้วยเครื่องหมายจุลภาคได้ เช่น h1, h2, h3 เพื่อกำหนดสีให้หัวข้อหลายระดับพร้อมกัน วิธีนี้ช่วยลดการเขียนโค้ดซ้ำและทำให้การแก้ไขรูปแบบส่วนกลางสะดวกขึ้น
กำหนดสีให้หัวข้อหลายระดับ
h1,
h2,
h3 {
color: #312e81;
line-height: 1.3;
}
button,
.button {
font: inherit;
cursor: pointer;
}
8. Attribute Selector
Attribute Selector ใช้เลือกองค์ประกอบจาก attribute ที่มีอยู่ เช่น เลือก input ที่มี type="email" หรือเลือก a ที่มี target="_blank" วิธีนี้มีประโยชน์เมื่อ HTML มี attribute ที่สื่อชนิดหรือหน้าที่ขององค์ประกอบอยู่แล้ว และต้องการตกแต่งโดยไม่ต้องเพิ่ม class ใหม่
เลือกองค์ประกอบด้วย Attribute
input[type="email"] {
width: 100%;
padding: 12px;
border: 1px solid #cbd5e1;
border-radius: 10px;
}
a[target="_blank"] {
text-decoration-thickness: 2px;
}
กฎแรกเลือกช่องกรอกข้อมูลที่มี type="email" ส่วนกฎที่สองเลือกเฉพาะลิงก์ที่เปิดในแท็บใหม่ ตัวอย่างนี้เป็น CSS ที่ต้องมีองค์ประกอบ HTML ที่ตรงกันจึงจะเห็นผล จึงกำหนดให้แสดงเฉพาะโค้ด
9. Pseudo-class เช่น hover และ focus
Pseudo-class ใช้เลือกองค์ประกอบตามสถานะหรือเงื่อนไข เช่น :hover เมื่อเมาส์ชี้อยู่บนองค์ประกอบ และ :focus เมื่อองค์ประกอบได้รับโฟกัสจากการใช้งานด้วยคีย์บอร์ดหรือการโต้ตอบที่เหมาะสม การออกแบบสถานะเหล่านี้ช่วยให้ผู้ใช้เข้าใจว่าองค์ประกอบใดสามารถโต้ตอบได้ และช่วยให้การใช้งานด้วยคีย์บอร์ดชัดเจนขึ้น
เพิ่มสถานะให้ปุ่ม
.button {
display: inline-block;
padding: 12px 20px;
color: #ffffff;
background: #4f46e5;
border-radius: 10px;
text-decoration: none;
transition: background 160ms ease, transform 160ms ease;
}
.button:hover {
background: #3730a3;
transform: translateY(-2px);
}
.button:focus-visible {
outline: 3px solid #67e8f9;
outline-offset: 3px;
}
อย่าลืมผู้ใช้คีย์บอร์ดอย่าลบเส้นขอบ focus ออกโดยไม่มีรูปแบบทดแทน เพราะผู้ใช้ที่นำทางด้วยคีย์บอร์ดจำเป็นต้องรู้ว่าองค์ประกอบใดกำลังได้รับโฟกัส
10. Pseudo-element สำหรับตกแต่งเพิ่มเติม
Pseudo-element เช่น ::before และ ::after ใช้สร้างส่วนตกแต่งเพิ่มเติมผ่าน CSS โดยไม่จำเป็นต้องเพิ่มองค์ประกอบ HTML แยก เช่น เส้นสีเล็ก ๆ ก่อนหัวข้อหรือเครื่องหมายตกแต่งในกล่องข้อมูล เหมาะกับการตกแต่งที่ไม่ใช่เนื้อหาสำคัญ หากเป็นข้อมูลที่ผู้ใช้ต้องอ่านหรือเข้าใจ ควรใส่ใน HTML จริงแทนการสร้างด้วย content
เพิ่มแถบสีด้านหน้าหัวข้อ
.section-title::before {
display: inline-block;
width: 8px;
height: 28px;
margin-right: 12px;
border-radius: 999px;
background: #06b6d4;
content: "";
vertical-align: middle;
}
11. Specificity: เมื่อ CSS หลายกฎชนกัน
หากองค์ประกอบหนึ่งถูกเลือกโดย CSS หลายกฎ เบราว์เซอร์จะพิจารณาความสำคัญของ Selector หรือ Specificity ร่วมกับที่มาของกฎ ลำดับใน stylesheet และเงื่อนไขอื่น ๆ โดยทั่วไป ID มีน้ำหนักมากกว่า class และ class มีน้ำหนักมากกว่า element selector แต่ไม่ได้หมายความว่าควรใช้ ID กับทุกอย่างเพื่อบังคับให้กฎชนะ การออกแบบ CSS ให้ชัดเจนและลดความขัดแย้งมักดูแลรักษาง่ายกว่า
| Selector | ตัวอย่าง | น้ำหนักโดยทั่วไป |
|---|---|---|
| Element | p | ต่ำ |
| Class | .notice | สูงกว่า Element |
| ID | #main | สูงกว่า Class |
| Inline style | style="color: red" | โดยทั่วไปสูงกว่ากฎปกติใน stylesheet |
ตัวอย่างกฎที่มีความสำคัญต่างกัน
p {
color: #64748b;
}
.notice {
color: #0f766e;
}
#special-notice {
color: #4338ca;
}
หากย่อหน้ามีทั้ง class="notice" และ id="special-notice" กฎที่ใช้ ID จะมี Specificity สูงกว่ากฎ class และ element ในตัวอย่างนี้ อย่างไรก็ตาม ยังมีปัจจัย CSS อื่นที่มีผลต่อการตัดสินกฎสุดท้าย เช่น !important, cascade layer และแหล่งที่มาของกฎ จึงควรหลีกเลี่ยงการพึ่งพา !important โดยไม่จำเป็น
12. Inheritance: คุณสมบัติที่ส่งต่อจากองค์ประกอบแม่
คุณสมบัติ CSS บางชนิด เช่น color และ font-family สามารถสืบทอดจากองค์ประกอบแม่ไปยังองค์ประกอบลูกได้ ขณะที่คุณสมบัติอื่น เช่น margin และ border โดยทั่วไปไม่ได้สืบทอดแบบเดียวกัน การเข้าใจเรื่องนี้ช่วยให้ไม่ต้องกำหนดสีและฟอนต์ซ้ำทุกแท็ก แต่หากต้องการให้บางส่วนแตกต่างจากแม่ ก็สามารถเขียนกฎเฉพาะสำหรับส่วนนั้นได้
กำหนดฟอนต์ส่วนกลางและสีเฉพาะส่วน
body {
font-family: Tahoma, Arial, sans-serif;
color: #1e293b;
}
.muted {
color: #64748b;
}
13. ตั้งชื่อ Class ให้สื่อความหมาย
การตั้งชื่อ class ที่สื่อความหมายทำให้ทีมงานเข้าใจโค้ดได้ง่ายขึ้น เช่น .product-card, .site-header, .primary-button หรือ .article-title ชื่อเหล่านี้บอกบทบาทขององค์ประกอบได้ดีกว่าชื่อที่บอกเฉพาะสีหรือหน้าตา เช่น .blue-box เพราะหน้าตาขององค์ประกอบอาจเปลี่ยนภายหลัง แต่หน้าที่ของมันยังคงเดิม
| ชื่อที่แนะนำ | เหตุผล |
|---|---|
| .product-card | บอกว่าเป็นการ์ดสินค้า |
| .primary-button | บอกบทบาทของปุ่มหลัก |
| .article-title | บอกว่าเป็นหัวข้อบทความ |
| .site-header | บอกว่าเป็นส่วนหัวของเว็บไซต์ |
14. ใช้ CSS Variables เพื่อจัดการสี
CSS Custom Properties หรือ CSS Variables ช่วยให้กำหนดค่าที่นำกลับมาใช้ซ้ำได้ เช่น สีหลัก สีข้อความ และพื้นหลัง โดยมักกำหนดไว้ใน :root แล้วอ้างอิงด้วย var() วิธีนี้ทำให้เปลี่ยนธีมเว็บไซต์ได้สะดวก เพราะไม่ต้องค้นหาและแก้รหัสสีเดียวกันหลายตำแหน่ง
กำหนดตัวแปรสี
:root {
--primary: #4f46e5;
--text: #1e293b;
--surface: #ffffff;
--page: #f1f5f9;
}
body {
color: var(--text);
background: var(--page);
}
.button {
background: var(--primary);
}
ตัวอย่างนี้เป็นชุด CSS ที่นำไปใช้กับ HTML ซึ่งมีองค์ประกอบ body และ .button ได้ เมื่อเปลี่ยนค่า --primary สีพื้นหลังของปุ่มที่ใช้ var(--primary) ก็จะเปลี่ยนตามไปด้วย จึงกำหนดให้แสดงเฉพาะโค้ด
15. หลักการจัด CSS ให้อ่านง่าย
ควรจัดกฎ CSS ตามส่วนของหน้าเว็บ เช่น Base, Header, Hero, Content, Cards และ Footer แยกบรรทัดให้ชัดเจน ใช้ชื่อ class ที่สื่อความหมาย และหลีกเลี่ยง Selector ที่ซับซ้อนเกินจำเป็น เมื่อมีปัญหาให้ตรวจว่ากฎใดเลือกองค์ประกอบนั้นอยู่ และตรวจค่าที่ถูกแทนที่ในเครื่องมือ Developer Tools ของเบราว์เซอร์
แนวทางแก้ปัญหาอย่างเป็นระบบเริ่มจากตรวจว่า Selector ตรงกับองค์ประกอบหรือไม่ จากนั้นตรวจว่ากฎถูกโหลดหรือไม่ แล้วจึงตรวจ Specificity และลำดับของกฎ การตรวจทีละขั้นช่วยให้หาสาเหตุได้เร็วกว่าการเพิ่ม !important ไปเรื่อย ๆ
16. แบบฝึกหัด: ตกแต่งหน้าเว็บด้วย Selector หลายชนิด
ลองนำแนวคิดในบทความนี้ไปใช้กับหน้าเว็บตัวอย่างของคุณ โดยกำหนดสีพื้นฐานด้วย element selector กำหนดรูปแบบการ์ดด้วย class ใช้ ID กับส่วนที่มีเอกลักษณ์ เลือกข้อความภายในการ์ดด้วย descendant selector และเพิ่มสถานะ hover กับ focus-visible ให้ปุ่ม จากนั้นทดลองเปลี่ยนสีหลักผ่าน CSS Variables เพื่อดูว่าการจัดการรูปแบบส่วนกลางช่วยลดงานได้อย่างไร
17. Checklist ก่อนจบบทเรียน
ก่อนจบบทเรียน ควรอธิบายความแตกต่างระหว่าง element selector, class selector และ ID selector ได้ ใช้ descendant selector เลือกองค์ประกอบภายในได้ เข้าใจการทำงานของ :hover และ :focus-visible รู้ว่า Specificity ส่งผลต่อกฎ CSS อย่างไร และสามารถใช้ CSS Variables เพื่อจัดการค่าสีที่ใช้ซ้ำได้
Full Page Code — CSS Selector Showcase
โค้ดฉบับเต็มด้านล่างรวม HTML และ CSS ไว้ในไฟล์เดียว เพื่อแสดงตัวอย่าง Selector หลายประเภทบนหน้าเว็บจริง มีเมนูนำทาง ส่วน Hero การ์ดเนื้อหา ป้ายข้อความ ลิงก์ ปุ่มที่มี hover และ focus-visible รวมถึงการปรับหน้าจอมือถือ คัดลอกโค้ดทั้งหมดไปบันทึกเป็น index.html แล้วเปิดในเบราว์เซอร์ได้ทันที
Full Page — Copy & Run | index.html
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ตัวอย่างการใช้งาน CSS Selectors บนหน้าเว็บไซต์จริง">
<title>CSS Selectors Showcase</title>
<style>
:root {
--primary: #4f46e5;
--primary-dark: #3730a3;
--accent: #06b6d4;
--text: #172033;
--muted: #64748b;
--page: #f1f5f9;
--surface: #ffffff;
--border: #e2e8f0;
--success: #047857;
--radius: 20px;
--shadow: 0 14px 34px rgba(30, 41, 59, 0.09);
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
color: var(--text);
background: var(--page);
font-family: Tahoma, Arial, sans-serif;
line-height: 1.75;
}
a {
color: var(--primary);
}
.container {
width: min(1100px, calc(100% - 36px));
margin: 0 auto;
}
.site-header {
border-bottom: 1px solid var(--border);
background: var(--surface);
}
.navigation {
display: flex;
min-height: 76px;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.brand {
color: var(--primary-dark);
font-size: 1.15rem;
font-weight: 900;
text-decoration: none;
}
.menu {
display: flex;
flex-wrap: wrap;
gap: 10px 20px;
}
.menu a {
color: var(--muted);
font-size: 0.92rem;
font-weight: 700;
text-decoration: none;
}
.menu a:hover {
color: var(--primary);
}
.hero {
padding: 72px 0;
color: #ffffff;
background: linear-gradient(130deg, #312e81, var(--primary) 55%, #0891b2);
}
.hero-inner {
display: grid;
grid-template-columns: minmax(0, 1.4fr) minmax(220px, 0.6fr);
align-items: center;
gap: 35px;
}
.eyebrow {
display: inline-block;
margin-bottom: 14px;
padding: 5px 12px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 999px;
background: rgba(255, 255, 255, 0.1);
font-size: 0.82rem;
font-weight: 800;
letter-spacing: 0.6px;
}
h1,
h2,
h3 {
line-height: 1.3;
}
h1 {
margin: 0 0 16px;
font-size: clamp(2.3rem, 5vw, 3.8rem);
letter-spacing: -1px;
}
.hero p {
max-width: 650px;
margin: 0 0 25px;
color: #e0e7ff;
font-size: 1.05rem;
}
.hero-art {
display: grid;
width: min(250px, 100%);
aspect-ratio: 1;
margin: auto;
place-items: center;
border: 1px solid rgba(255, 255, 255, 0.25);
border-radius: 35px;
background: rgba(255, 255, 255, 0.12);
box-shadow: 0 22px 55px rgba(15, 23, 42, 0.18);
font-size: 5rem;
}
.button {
display: inline-flex;
min-height: 46px;
align-items: center;
justify-content: center;
padding: 10px 19px;
border: 0;
border-radius: 11px;
color: #ffffff;
background: var(--primary);
font: inherit;
font-weight: 800;
text-decoration: none;
cursor: pointer;
transition: background 160ms ease, transform 160ms ease;
}
.hero .button {
color: var(--primary-dark);
background: #ffffff;
}
.button:hover {
background: var(--primary-dark);
transform: translateY(-2px);
}
.hero .button:hover {
color: #ffffff;
}
.button:focus-visible,
.menu a:focus-visible,
.brand:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 4px;
}
.section {
padding: 62px 0;
}
.section-heading {
max-width: 700px;
margin: 0 auto 32px;
text-align: center;
}
.section-heading .kicker {
margin: 0 0 8px;
color: var(--primary);
font-size: 0.82rem;
font-weight: 900;
letter-spacing: 1.5px;
}
.section-heading h2 {
margin: 0 0 12px;
font-size: clamp(1.8rem, 4vw, 2.5rem);
}
.section-heading p {
margin: 0;
color: var(--muted);
}
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 22px;
}
.card {
padding: 27px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
box-shadow: var(--shadow);
transition: transform 160ms ease, box-shadow 160ms ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 20px 42px rgba(30, 41, 59, 0.13);
}
.card-icon {
display: grid;
width: 54px;
height: 54px;
margin-bottom: 18px;
place-items: center;
border-radius: 16px;
background: #eef2ff;
font-size: 1.65rem;
}
.card:nth-child(2) .card-icon {
background: #cffafe;
}
.card:nth-child(3) .card-icon {
background: #dcfce7;
}
.card h3 {
margin: 0 0 10px;
font-size: 1.2rem;
}
.card p {
margin: 0 0 18px;
color: var(--muted);
}
.tag {
display: inline-block;
padding: 4px 10px;
border-radius: 999px;
color: var(--success);
background: #d1fae5;
font-size: 0.8rem;
font-weight: 800;
}
.selector-demo {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
align-items: stretch;
}
.demo-panel {
padding: 28px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
box-shadow: var(--shadow);
}
.demo-panel h3 {
margin-top: 0;
}
.highlight {
padding: 3px 8px;
border-radius: 6px;
color: var(--primary-dark);
background: #eef2ff;
font-weight: 800;
}
.demo-list {
display: grid;
gap: 10px;
margin: 0;
padding: 0;
list-style: none;
}
.demo-list li {
padding: 10px 13px;
border: 1px solid var(--border);
border-radius: 10px;
background: #f8fafc;
}
.demo-list li:first-child {
border-color: #a5b4fc;
background: #eef2ff;
}
.demo-list li:last-child {
border-color: #67e8f9;
background: #ecfeff;
}
.cta {
padding: 44px 25px;
border-radius: 24px;
color: #ffffff;
background: linear-gradient(120deg, #4338ca, #0891b2);
text-align: center;
}
.cta h2 {
margin: 0 0 12px;
font-size: clamp(1.6rem, 4vw, 2.3rem);
}
.cta p {
max-width: 650px;
margin: 0 auto 22px;
color: #e0f2fe;
}
.site-footer {
padding: 24px 0;
border-top: 1px solid var(--border);
background: #ffffff;
color: var(--muted);
text-align: center;
font-size: 0.9rem;
}
.site-footer p {
margin: 0;
}
@media (max-width: 760px) {
.navigation {
align-items: flex-start;
flex-direction: column;
justify-content: center;
padding: 15px 0;
}
.hero {
padding: 50px 0;
}
.hero-inner {
grid-template-columns: 1fr;
}
.hero-art {
width: 150px;
border-radius: 24px;
font-size: 3.5rem;
}
.cards,
.selector-demo {
grid-template-columns: 1fr;
}
.section {
padding: 45px 0;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
.button,
.card {
transition: none;
}
}
</style>
</head>
<body>
<header class="site-header">
<div class="container navigation">
<a class="brand" href="#home">CSS SELECTOR LAB</a>
<nav class="menu" aria-label="เมนูหลัก">
<a href="#home">หน้าหลัก</a>
<a href="#selectors">Selectors</a>
<a href="#practice">ตัวอย่าง</a>
</nav>
</div>
</header>
<main>
<section class="hero" id="home">
<div class="container hero-inner">
<div>
<span class="eyebrow">HTML + CSS · HANDS-ON DEMO</span>
<h1>เลือกให้ถูก<br>ตกแต่งได้ตรงจุด</h1>
<p>ทำความเข้าใจ CSS Selectors ผ่านตัวอย่างที่มองเห็นผลลัพธ์จริง ตั้งแต่การเลือกแท็ก การใช้ class ไปจนถึงสถานะ hover และการจัดวางการ์ด</p>
<a class="button" href="#selectors">สำรวจตัวอย่าง ↓</a>
</div>
<div class="hero-art" role="img" aria-label="สัญลักษณ์โค้ด"></></div>
</div>
</section>
<section class="section" id="selectors">
<div class="container">
<div class="section-heading">
<p class="kicker">SELECTOR BASICS</p>
<h2>CSS เลือกองค์ประกอบอย่างไร</h2>
<p>ตัวอย่างด้านล่างใช้ class, element selector และ pseudo-class เพื่อเปลี่ยนรูปลักษณ์ของแต่ละส่วน</p>
</div>
<div class="cards">
<article class="card">
<div class="card-icon" aria-hidden="true">🎯</div>
<h3>Element Selector</h3>
<p>เลือกองค์ประกอบจากชื่อแท็ก เช่น h3 หรือ p เพื่อกำหนดรูปแบบพื้นฐานให้เนื้อหา</p>
<span class="tag">h3, p</span>
</article>
<article class="card">
<div class="card-icon" aria-hidden="true">🏷️</div>
<h3>Class Selector</h3>
<p>ใช้ชื่อ class เพื่อกำหนดรูปแบบที่นำกลับมาใช้ซ้ำได้กับหลายองค์ประกอบ</p>
<span class="tag">.card, .highlight</span>
</article>
<article class="card">
<div class="card-icon" aria-hidden="true">✨</div>
<h3>Pseudo-class</h3>
<p>กำหนดรูปแบบตามสถานะ เช่น เมื่อเมาส์ชี้อยู่บนการ์ดหรือปุ่ม</p>
<span class="tag">:hover, :focus-visible</span>
</article>
</div>
</div>
</section>
<section class="section" id="practice">
<div class="container">
<div class="section-heading">
<p class="kicker">SEE THE DIFFERENCE</p>
<h2>ทดลองดูผลของ Selector</h2>
<p>ข้อความที่ใช้ class highlight จะได้รับสีและพื้นหลังเฉพาะ ส่วนรายการแรกและรายการสุดท้ายมีรูปแบบแตกต่างจากรายการอื่น</p>
</div>
<div class="selector-demo">
<article class="demo-panel">
<h3>ตัวอย่างการใช้ Class</h3>
<p>นี่คือข้อความปกติที่ใช้สีตามรูปแบบหลักของหน้าเว็บ</p>
<p>แต่ข้อความนี้เป็น <span class="highlight">ข้อความที่เน้นด้วย class</span> ทำให้เห็นความแตกต่างได้ทันที</p>
<a class="button" href="#summary">ดูสรุปท้ายหน้า</a>
</article>
<article class="demo-panel">
<h3>ตัวอย่าง Pseudo-class</h3>
<p>รายการแรกและรายการสุดท้ายถูกเลือกด้วย CSS โดยไม่ต้องกำหนด class เพิ่มให้แต่ละรายการ</p>
<ul class="demo-list">
<li>รายการแรก — :first-child</li>
<li>รายการตรงกลาง — รูปแบบปกติ</li>
<li>รายการสุดท้าย — :last-child</li>
</ul>
</article>
</div>
</div>
</section>
<section class="section" id="summary">
<div class="container">
<div class="cta">
<h2>เริ่มเขียน CSS อย่างมีระบบ</h2>
<p>เลือกแท็กให้ตรงหน้าที่ ใช้ class สำหรับรูปแบบที่นำกลับมาใช้ซ้ำ และตรวจสอบ hover กับ focus เพื่อให้เว็บไซต์ใช้งานได้สะดวก</p>
<a class="button" href="#home">กลับไปด้านบน ↑</a>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container">
<p>CSS Selector Lab · ตัวอย่างหน้าเว็บสำหรับฝึก HTML และ CSS</p>
</div>
</footer>
</body>
</html>
อ่านจนถึงระยะ 500px ก่อนท้ายหน้าและอยู่ในหน้านี้อย่างน้อย 5 นาที เพื่อรับ EXP วันละครั้ง
⏳ กำลังจับเวลาอ่าน...