หัวข้อ 2: Selector ประเภทต่าง ๆ และ Specificity

แนวคิดหลัก

Selector ใช้เลือก element ที่ต้องการตกแต่ง ส่วน specificity ใช้ตัดสินว่า style ใดมีน้ำหนักมากกว่าเมื่อมีกฎ CSS หลายชุดชนกัน การเข้าใจสองเรื่องนี้ช่วยลดปัญหา CSS ทับกันแบบคาดเดายาก

Type Selector

เลือก element ตามชื่อ tag มี specificity ต่ำ

h1 {
  color: navy;
}

p {
  line-height: 1.7;
}

เหมาะกับการกำหนด style พื้นฐานของ tag ทั่วทั้งหน้า

Class Selector

เลือก element ด้วย class มี specificity ปานกลาง ใช้ซ้ำได้

.card {
  border: 1px solid #ddd;
  padding: 16px;
}

.btn {
  padding: 8px 12px;
}

Class selector เป็นรูปแบบที่นิยมสำหรับ component และ utility classes

ID Selector

เลือก element ด้วย id มี specificity สูง

#header {
  background: #111827;
}

ควรใช้เท่าที่จำเป็น เพราะแก้ override ยากกว่า class

Attribute Selector

เลือก element จาก attribute

input[type="text"] {
  border: 1px solid #aaa;
}

a[href^="https"] {
  color: green;
}

ตัวอย่าง ^= หมายถึงขึ้นต้นด้วย เช่น URL ที่ขึ้นต้นด้วย https

Pseudo-class

Pseudo-class เลือก state หรือเงื่อนไขพิเศษของ element

a:hover {
  text-decoration: underline;
}

input:focus {
  outline: 2px solid #3b82f6;
}

li:nth-child(odd) {
  background: #f5f5f5;
}

button:not(.primary) {
  opacity: 0.8;
}

ที่พบบ่อย ได้แก่ :hover, :focus, :nth-child(), :first-child, :not()

Pseudo-element

Pseudo-element ใช้สร้างหรือเลือกส่วนเสมือนของ element

.badge::before {
  content: "★ ";
}

.badge::after {
  content: " ใหม่";
}

input::placeholder {
  color: #888;
}

::selection {
  background: #fde68a;
}

Combinator

Combinator ใช้อธิบายความสัมพันธ์ระหว่าง selector

article p {
  color: #333;
}

nav > a {
  margin-right: 12px;
}

h2 + p {
  margin-top: 0;
}

h2 ~ p {
  color: #555;
}
Combinator ความหมาย
ช่องว่าง descendant
> child โดยตรง
+ adjacent sibling ถัดไปทันที
~ sibling ที่ตามมาทั้งหมด

Specificity และ Cascade

โดยทั่วไปน้ำหนัก specificity เรียงจากสูงไปต่ำ:

  1. Inline style
  2. ID selector
  3. Class, attribute, pseudo-class
  4. Type selector, pseudo-element

ถ้า specificity เท่ากัน rule ที่เขียนทีหลังจะชนะ

p {
  color: black;
}

.lead {
  color: blue;
}

#intro {
  color: red;
}

ถ้า element เป็น <p id="intro" class="lead"> สีจะเป็นแดง เพราะ ID selector มี specificity สูงกว่า

การแก้ปัญหา Cascade

แนวทางที่ดี:

  1. ใช้ class เป็นหลัก
  2. หลีกเลี่ยง selector ที่ลึกเกินไป
  3. ลดการใช้ ID selector สำหรับ styling
  4. จัดลำดับ CSS จาก general ไป specific
  5. หลีกเลี่ยง !important ถ้าไม่จำเป็น

กิจกรรม

สร้างไฟล์ CSS ที่มี type, class, id, attribute, pseudo-class และ pseudo-element อย่างละ 1 ตัวอย่าง แล้วทดลองดูว่า rule ใดชนะเมื่อ style ชนกัน

แบบทดสอบหลังเรียน

  1. Type selector และ class selector ต่างกันอย่างไร
  2. ID selector มีข้อควรระวังอะไร
  3. :hover และ ::before ต่างกันอย่างไร
  4. Combinator > หมายถึงอะไร
  5. ถ้า selector มี specificity เท่ากัน rule ใดจะถูกใช้

กลับสัปดาห์ที่ 3