CSS Selector ตัวใหม่ :is(), :where() มาเขียน CSS ให้สั้นลงกันเถอะ
: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 สั้นลงและเข้าใจง่ายมากขึ้นด้วย
Browser support
ทั้ง :is() และ :where() รองรับกับ Chromium (>=88), Firefox (>= 78) และ Safari (>=14) ตามภาพข้างล่าง
ในส่วนของ 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.
: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.
จากตัวอย่างด้านบนจะเห็นได้ว่าเรากำหนด footer selector แสดงผลสีส้ม ซึ่งผลลัพธ์ในส่วนของ :where() ที่ตำแหน่ง footer จะเปลี่ยนเป็นสีส้มตาม footer selector แต่ในส่วนของ :is() ตำแหน่ง footer กลับแสดงผลสีแดงอยู่ แสดงว่า :is() มีค่า Spec score สูงกว่า footer selector นั่นเอง
แล้วปัจจุบัน Selector มี Browser รองรับมากน้อยแค่ไหน? มาดูจากภาพด้านล่างนี้ได้เลยครับ
ดูจาก percentage ของ browser ที่รองรับแล้วก็ถือว่าสูงมาก ๆ เลยครับ มากกว่า 84% มั่นใจว่าใช้ได้ปลอดภัยหายห่วง
ขอบคุณเนื้อหาอ้างอิงจากเว็บไซต์
- New CSS functional pseudo-class selectors
:is()
and:where()
- :where() MDN Web docs
- Specificity
- :is() CSS-Tricks
- :is() MDN Web docs
- How to Use New CSS “:is()” for Easy Element Targeting
บทความที่เกี่ยวข้อง