CSS ใช้ numeric scale กำหนด power ของ selector Power = selector ไหนแรงที่สุด หรือ selector ไหนมี specificity สูงสุด Selector ที่มี specificity number สูงสุด จะ dictate ว่า HTML element long อย่างไร ไม่ว่า styles อื่นจาก weaker selectors จะเป็นยังไง
มี button element หลายวิธี apply styles ใน CSS 3 commonly used selectors: type, class, id
Style element โดยตรง via type selector:
button { background-color: red; }
ใช้ class attribute:
.button { background-color: red; }
หรือ id attribute:
#button { background-color: red; }
แต่ละ selector มี numeric value = 1
ถ้าทุก CSS selectors (type, class, id) มีค่าเท่ากัน (1) rule-set ไหนชนะใน stylesheet เดียวกัน?
ID ชนะ (#button) เพราะ IDs takes precedence over class และ type selectors
ถ้าไม่มี ID involved?
Class selector (.button) ชนะ เพราะ classes takes precedence over type selectors
CSS "Cascade" (CSS = Cascading Style Sheets) ยังไง?
ใน CSS ถ้าสิ่งต่างๆ เท่ากัน selector ที่ apply สุดท้ายใน Style Sheet จะชนะ
สมมติเพิ่ม 3 classes ชื่อเดียวกัน (.hero-button) ใน stylesheet แต่ละ class target styling property เดียวกัน (background-color) แตะค่า property ต่างกัน คือ green, blue, red ตามลำดับ
.hero-button { background-color: green; } .hero-button { background-color: blue; } .hero-button { background-color: red; }
apply ทั้ง 3 ตัวให้ HTML element เดียวกัน:
<button class="hero-button">Button</button>
.hero-button class สุดท้ายใน stylesheet จะ precede over previous classes ชื่อเดียวกัน ทำให้ button background color แดง นั่นคือ CSS cascade ทำงาน: order of specificity จากบนลงล่าง ตัวล่างชนะ จำได้ว่า: true 100% เฉพาะเมื่อ all things are equal
สำคัญ: multiple selectors ชื่อเดียวกัน ตัวล่าง won't override all styles จาก previous selector ชื่อเดียวกัน จะ override แค่ specified styling property
สับสน? ไม่เป็นไร จะเข้าใจในไม่ช้า
3 .hero-button classes เดิม ทุกตัวมี background-color properties เดิม แตะ 2 class แรกแต่ละตัวมี additional styling property (padding & font-size):
.hero-button { background-color: green; padding: 2rem; } .hero-button { background-color: blue; font-size: 2rem; } .hero-button { background-color: red; }
Stylesheet มี 3 CSS classes ชื่อเดียวกัน target background-color property เดียวกันไปที่ HTML button — แต่ 2 class แรกมี additional styling properties คิดว่าจะเกิดอะไร?
ผลลัพธ์: https://codepen.io/StrengthandFreedom/pen/mdyMGPL
เห็นไหม button element stack (combine) ทุก styling properties จาก 3 .hero-button classes ตอนนี้ button ได้ทั้ง 3 properties:
padding: 2rem; font-size: 2rem; background-color: red;
คือ CSS selectors ใน stylesheet ชื่อเดียวกัน จะได้ properties overridden เฉพาะตอน selectors target properties เดียวกัน
ตัวอย่างข้างต้น 3 classes target background-color property ตัวล่างชนะเพราะ CSS Cascade rule (Order Specificity) แต่ class สุดท้ายไม่ target padding หรือ font-size properties ดังนั้น properties จาก 2 classes แรกจึงได้ apply ให้ button element
เหตุผลที่ผมเน้นจุดนี้: จะเจอสถานการณ์ massive, disorganized CSS codebase หลาย developers ทำให้ชีวิตมันมiserable
Common scenario: developers ต่างกันเพิ่ม CSS classes ใน stylesheet ที่มีอยู่แล้ว ทำให้สับสนเร็วถ้าไม่รู้/ลืมว่า CSS จะ stack properties together
อาจเพิ่ม CSS class primary-button properties:
.primary-button { background-color: red padding: 1rem; font-size: 1.125rem; }
แตะ button มี shadow ที่ไม่ได้เพิ่ม สาเหตุ 2 อย่าง: ใครสองคน apply styling โดยตรงบน button element:
button { box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); }
หรือใครเพิ่ม class ชื่อเดียวกันใน stylesheet ก่อนหน้านี้ พร้อม box-shadow property:
.primary-button { box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); }
ลบ unwanted styling: locate ที่ใน codebase unwanted property applied ลบ หรือ target ลบใน ของคุณ .primary-button class:
.primary-button { background-color: red padding: 1rem; font-size: 1.125rem; box-shadow: 0; /*removes existing box shadow value*/ }
รู้ว่าวิธีนี้ messy แตะบางครั้งเจอ massive disorganized project (typically legacy code) ไม่มี access ทุก existing CSS code (developer ที่มี experience relate ได้) ไม่ได้ modify existing code ตามใจ — ต้อง override existing code รู้ CSS Specificity และ Source Order จึงสำคัญ
ใช้ Specificity Calculator บนเว็บไซต์เปรียบเทียบ specificity number ของ CSS selectors ต่างๆ รวม group selectors (combining selectors)
Tip: หลีกเลี่ยง specificity issues ใช้ primarily classes สไตล์ UI แทน type selectors ใช้ IDs น้อยๆ หลีกเลี่ยง group selectors เพราะนำไปสู่ unpredictable problems ใน growing codebase