Kodokon kodokon.com

Selector สมัยใหม่: :has, :is, :where, :nth-child ขั้นสูง

ใช้ประโยชน์จาก functional pseudo-class ที่เพิ่งเกิดขึ้นเพื่อเลือกตามเนื้อหา จัดกลุ่ม selector โดยไม่ทำให้ specificity พองขึ้น และเจาะรูปแบบที่ซับซ้อน

9 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

:is() และ :where() ต่างก็จัดกลุ่ม selector แต่แตกต่างกันในจุดชี้ขาดจุดหนึ่ง: specificity :is(nav, .menu, #main a) รับ specificity ของอาร์กิวเมนต์ที่แข็งแกร่งที่สุด (ในที่นี้คือ ID) แม้ว่า nav จะเป็นตัวที่ตรงก็ตาม ส่วน :where() มี specificity เป็น ศูนย์ ไม่ว่าอาร์กิวเมนต์จะเป็นอะไร ผลในทางปฏิบัติ: :where() เป็นเครื่องมือที่เหมาะสำหรับ reset และสไตล์เริ่มต้นของ design system ซึ่ง selector คลาสธรรมดา ๆ ตัวใดก็สามารถ override ได้โดยไม่ต้องต่อสู้

CSS
:where(h1, h2, h3, h4) {
  margin-block: 0;
  line-height: 1.2;
}

:is(article, aside, section) :is(h2, h3) {
  font-family: var(--font-heading);
}

.prose :is(ul, ol) li + li {
  margin-top: 0.5em;
}
การจัดกลุ่มและควบคุม specificity

:has() ในที่สุดก็กลับทิศทางการอ่าน: selector เจาะไปที่ element ที่เป็นเจ้าบ้าน ไม่ใช่สิ่งที่มันบรรจุอยู่ .card:has(> img) เลือก card ที่มีรูปภาพเป็นลูกโดยตรง เมื่อรวมกับ pseudo-class ของสถานะ มันช่วยให้ข้อมูลไหลขึ้นด้านบนได้โดยไม่ต้องใช้ JavaScript: จัดสไตล์ label เมื่อฟิลด์ของมัน invalid, จัดสไตล์ฟอร์มเมื่อฟิลด์หนึ่งได้รับ focus, จัดสไตล์แถวตารางเมื่อ checkbox ของมันถูกเลือก

CSS
.field:has(input:invalid:not(:focus)) label {
  color: #dc2626;
}

.card:has(> img) {
  padding-top: 0;
}

tr:has(input[type="checkbox"]:checked) {
  background: #eef2ff;
}
การเลือกตามเนื้อหาหรือสถานะภายใน

เรื่อง :nth-child() มีทักษะสองอย่างที่ต้องเสริมให้แน่น อย่างแรก การอ่านสูตร An+B: 2n (คู่), 2n+1 (คี่), -n+3 (สามตัวแรก), n+4 (จากตัวที่สี่ไปจนจบ) ส่วนช่วง "จากตัวที่ 2 ถึงตัวที่ 5" เขียนได้โดยรวม :nth-child(n+2):nth-child(-n+5) อย่างที่สอง คือ syntax of S ที่ใหม่กว่า: :nth-child(2n of .visible) นับ เฉพาะในหมู่ลูกที่ตรงกับ .visible ในขณะที่ .visible:nth-child(2n) นับลูกทั้งหมดแล้วค่อยกรอง ให้ผลลัพธ์ที่ต่างกันมากทันทีที่มี element อื่นแทรกอยู่

CSS
tr:nth-child(odd) {
  background: #fafafa;
}

li:nth-child(-n + 3) {
  font-weight: 600;
}

li:nth-child(n + 2):nth-child(-n + 5) {
  border-top: 1px solid #e5e7eb;
}

.row:nth-child(2n of .visible) {
  background: #eef2ff;
}
สูตร An+B และ syntax of S

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. specificity ของ :where(#main, .nav, a) คือเท่าไร?
    • ของ ID กล่าวคือ (1,0,0)
    • ผลรวมของอาร์กิวเมนต์ทั้งสาม
    • ศูนย์ ไม่ว่าอาร์กิวเมนต์จะเป็นอะไร
    • ของอาร์กิวเมนต์ที่ตรงกันจริง ๆ
  2. .card:has(> img) เลือกอะไร?
    • รูปภาพที่เป็นลูกโดยตรงของ card
    • card ที่บรรจุรูปภาพเป็นลูกโดยตรง
    • card ที่อยู่หลังรูปภาพใน DOM
    • รูปภาพทั้งหมดที่เป็นลูกหลานของ card
  3. ในลิสต์ที่มีเพียงบาง element li ที่มี .visible li:nth-child(2n of .visible) ทำอะไร?
    • มันเจาะ element li ตัวคู่ของลิสต์ที่มีคลาส .visible ด้วย
    • มันเจาะ li ทุกตัวเว้นตัว โดยนับเฉพาะ element li.visible
    • มันเจาะ element li ตัวคู่แล้วเพิ่มคลาส .visible ให้พวกมัน