CSS Selector ตัวใหม่ :is(), :where() มาเขียน CSS ให้สั้นลงกันเถอะ

PND777

:is() :where() CSS Selector – ไม่กี่เดือนมานี้ MDN Web docs ได้มีการ Update เกี่ยวกับ CSS selector ตัวใหม่อย่าง :is() และ :where() วันนี้ครับ Designil จะมาบอกวิธีการใช้งาน เพื่อให้เพื่อนๆนำไปลดจำนวนโค้ด CSS ที่เยอะมหาศาลลงให้เหลือเพียงไม่กี่บรรทัด ถ้าพร้อมแล้วมาเริ่มกันเลย

อ่านจบแล้วจะเขียน CSS สั้นขึ้นหลายบรรทัดเลยครับ~

:is() และ :where() ใช้งานยังไง

ทั้ง :is() และ :where() ต่างเป็น pseudo class selector ที่ใช้ในการรวบรวม selector ต่างๆไว้ในตัวมันเองเป้าหมายเพื่อลดขนาด selector ที่ยืดยาว และทำให้เข้าใจง่ายมากขึ้น ตัวอย่างเช่นในกรณีที่เพื่อนต้องการกำหนดสีชมพู <b> ทุกตัวใน header element

h1 > b, h2 > b, h3 > b, h4 > b, h5 > b, h6 > b {
  color: hotpink;
}

ทำไม selector ถึงได้ยาวขนาดนี้!!! แต่ถ้าเราใช้ :is() จะเป็นยังไงละ

:is(h1,h2,h3,h4,h5,h6) > b {
  color: hotpink;
}

จะเห็นได้ว่า code สั้นลงและเข้าใจง่ายมากขึ้นด้วย

การใช้งาน :is()

Browser support

ทั้ง :is() และ :where() รองรับกับ Chromium (>=88), Firefox (>= 78) และ Safari (>=14) ตามภาพข้างล่าง

:is() :where() Browser supoort
:is(), :where() browser support

ในส่วนของ Browser รุ่นเก่าเราสามารถใช้ :matches() และ :any() ได้เหมือนกับ :is() แต่ :any() จะไม่ต้องการ vendor prefixes และไม่ support กับ complex selector ซึ่งแตกต่างจาก :match()

:any() จะมีการเขียนการที่แตกต่างกันไปตามแต่ละ browser

:-webkit-any() {

  // Chrome and IE
}

:-moz-any() {

  // Firefox
}

เพื่อนๆ สามารถสร้าง Fallback ให้กับ :is() ได้ด้วย :match() และ :any() ตามตัวอย่าง code ข้างล่าง

:-webkit-any(article, section, aside) h1 {
    font-weight: 900;
}
 
:-moz-any(article, section, aside) h1 {
    font-weight: 900;
}
 
:matches(article, section, aside) h1 {
    font-weight: 900;
}
 
:is(article, section, aside) h1 {
    font-weight: 900;
}

Forgiving Selector Parsing

อีกสิ่งหนึ่งที่ทำให้ CSS selector ทั้งสองพิเศษก็คือมันเป็น Forgiving selector list ด้วย นั่นคือปกติเวลาที่เราใช้ selector list ถ้ามี selector ซักตัวที่ invalid นั่นจะทำให้ list รวมทั้งหมดถือว่า invalid ไปด้วย(ปลาเน่าตัวเดียวเหม็นทั้งเข่ง!!!) แต่ถ้าเราใช้ :is() และ :where() มาเป็น list รวมปัญหาพวกนี้จะหมดไป โดย selector ที่ invalid หรือ unsupport จะถูกมองข้ามไปเลย และหันไปใช้ selector ตัวอื่นแทน

:is(:valid, :unsupported) {
  ...
}

Selector grouping

ทั้ง :is() และ :where() สามารถใช้รวมกลุ่มในตำแหน่งไหนก็ได้ของ selector รวมทั้งยังสามารถทำ nesting และ stacking selector ได้ด้วย ซึ่งแสดงถึงความยืดหยุ่นของ CSS selector สองตัวนี้ เห็นได้จากตัวอย่างนี้

/* at the beginning */
:where(h1,h2,h3,h4,h5,h6) > b {
  color: hotpink;
}

/* in the middle */
article :is(header,footer) > p {
  color: gray;
}

/* at the end */
.dark-theme :where(button,a) {
  color: rebeccapurple;
}

/* multiple */
:is(.dark-theme, .dim-theme) :where(button,a) {
  color: rebeccapurple;
}

/* stacked */
:is(h1,h2):where(.hero,.subtitle) {
  text-transform: uppercase;
}

/* nested */
.hero:is(h1,h2,:is(.header,.boldest)) {
  font-weight: 900;
}

แล้ว :is() กับ :where() ต่างกันอย่างไรละ

เอิ่ม…. หลังจากอ่านมากว่า 200 กว่าคำ เพื่อนๆ คงสงสัยว่า “เอ๊ะ !!! แล้ว :is()กับ :where() มันต่างกันยังไงละแอด” โอเค เดวแอดอธิบายให้ฟัง สิ่งที่ทำให้ :is() และ :where() แตกต่างกันก็คือ Specificity

Specificity เปรียบกับกฎ priority ของแต่ละ selector ซึ่งจะถูกกำหนดจาก specificity score จะอธิบายให้เห็นภาพมากขึ้นด้วย code ข้างล่าง

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

เพื่อนๆคิดว่า button คลาส branding จะสีอะไร? CSS specification algorithm จะเป็นตัวเลือกแสดงผลจาก Specification score ที่สูงกว่า ซึ่งจากผลลัพธ์ด้านล่างจะแสดงให้เห็นว่า Class selector มี Specification score สูงกว่า button selector

See the Pen jOBdWvE by Tanapon Wijanpreecha (@tanapon-wijanpreecha) on CodePen.dark

:where() จะทำให้ selector ที่อยู่ในกลุ่ม มีค่า Specification score เป็น 0 ไม่ว่า selector ตัวนั้นจะมีค่า Spec score สูงมาก่อนเพียงใด นั่นแสดงว่าถ้าเราใช้ :where() ก็มีโอกาสสูงที่จะเกิดการแสดงผลแทนที่โดย selector ตัวอื่นที่มีค่า Spec score สูงกว่าได้

:is() จะมีค่า Spec score อ้างอิงของ selelctor ในกลุ่มที่มีค่า Spec score สูงที่สุด

See the Pen JjWxGgp by Tanapon Wijanpreecha (@tanapon-wijanpreecha) on CodePen.dark

จากตัวอย่างด้านบนจะเห็นได้ว่าเรากำหนด footer selector แสดงผลสีส้ม ซึ่งผลลัพธ์ในส่วนของ :where() ที่ตำแหน่ง footer จะเปลี่ยนเป็นสีส้มตาม footer selector แต่ในส่วนของ :is() ตำแหน่ง footer กลับแสดงผลสีแดงอยู่ แสดงว่า :is() มีค่า Spec score สูงกว่า footer selector นั่นเอง


แล้วปัจจุบัน Selector มี Browser รองรับมากน้อยแค่ไหน? มาดูจากภาพด้านล่างนี้ได้เลยครับ
ดูจาก percentage ของ browser ที่รองรับแล้วก็ถือว่าสูงมาก ๆ เลยครับ มากกว่า 84% มั่นใจว่าใช้ได้ปลอดภัยหายห่วง

ขอบคุณเนื้อหาอ้างอิงจากเว็บไซต์

บทความที่เกี่ยวข้อง

PND777

PND777

จบจากคณะวิศวะคอมพิวเตอร์ สนใจในงาน UX/UI และ Coding มีความฝันว่าอยากจะทำงานบริษัทเกมชื่อดัง
บทความทั้งหมด