เมื่อเรียนรู้หลักการของ CSS พื้นฐาน เราจะสอนให้เขียนสไตล์แบบโมดูลาร์ ใช้ซ้ำได้ และเป็นคำอธิบายเพื่อให้แน่ใจว่ามีการบำรุงรักษา แต่เมื่อนักพัฒนาเข้าไปพัวพันกับแอปพลิเคชันในโลกแห่งความเป็นจริง มักจะรู้สึกว่าเป็นไปไม่ได้เลยที่จะเพิ่มคุณสมบัติ UI โดยที่สไตล์ไม่รั่วไหลไปยังพื้นที่ที่ไม่ได้ตั้งใจ ปัญหานี้มักจะลุกลามไปสู่การวนซ้ำที่ตอบสนองด้วยตนเอง สไตล์ที่มีการกำหนดขอบเขตตามทฤษฎีไปที่องค์ประกอบหรือคลาสเดียวจะเริ่มปรากฏขึ้นในจุดที่ไม่ได้อยู่ในนั้น สิ่งนี้บังคับให้นักพัฒนาสร้างตัวเลือกที่เฉพาะเจาะจงมากขึ้นเพื่อแทนที่สไตล์ที่รั่วไหล ซึ่งจะลบล้างสไตล์โดยรวมโดยไม่ตั้งใจ และอื่นๆ แบบแผนชื่อคลาสที่เข้มงวด เช่น BEM เป็นวิธีแก้ปัญหาทางทฤษฎีวิธีหนึ่งสำหรับปัญหานี้ วิธีการ BEM (Block, Element, Modifier) เป็นวิธีที่เป็นระบบในการตั้งชื่อคลาส CSS เพื่อให้มั่นใจว่าสามารถนำกลับมาใช้ใหม่และโครงสร้างภายในไฟล์ CSS แบบแผนการตั้งชื่อเช่นนี้สามารถลดภาระการรับรู้ได้โดยการใช้ประโยชน์จากภาษาโดเมนเพื่ออธิบายองค์ประกอบและสถานะขององค์ประกอบ และหากนำไปใช้อย่างถูกต้อง จะสามารถทำให้สไตล์สำหรับแอปพลิเคชันขนาดใหญ่ดูแลรักษาได้ง่ายขึ้น อย่างไรก็ตาม ในโลกแห่งความเป็นจริง มันไม่ได้เป็นเช่นนั้นเสมอไป ลำดับความสำคัญสามารถเปลี่ยนแปลงได้ และเมื่อมีการเปลี่ยนแปลง การนำไปปฏิบัติจะไม่สอดคล้องกัน การเปลี่ยนแปลงเล็กน้อยในโครงสร้าง HTML อาจต้องมีการแก้ไขชื่อคลาส CSS หลายครั้ง ด้วยแอปพลิเคชันส่วนหน้าที่มีการโต้ตอบสูง ชื่อคลาสที่เป็นไปตามรูปแบบ BEM อาจยาวและเทอะทะได้ (เช่น ภาพรวมผู้ใช้แอป__สถานะ--กำลังตรวจสอบสิทธิ์) และการไม่ปฏิบัติตามกฎการตั้งชื่ออย่างสมบูรณ์จะทำลายโครงสร้างของระบบ ดังนั้นจึงลบล้างประโยชน์ของระบบ เมื่อพิจารณาถึงความท้าทายเหล่านี้ จึงไม่น่าแปลกใจที่นักพัฒนาหันมาใช้เฟรมเวิร์ก Tailwind จึงเป็นเฟรมเวิร์ก CSS ที่ได้รับความนิยมมากที่สุด แทนที่จะพยายามต่อสู้กับสิ่งที่ดูเหมือนเป็นสงครามเฉพาะเจาะจงระหว่างสไตล์ที่ไม่อาจเอาชนะได้ มันง่ายกว่าที่จะยอมแพ้กับ CSS Cascade และใช้เครื่องมือที่รับประกันการแยกตัวโดยสิ้นเชิง นักพัฒนาเรียนรู้เพิ่มเติมเกี่ยวกับยูทิลิตี้ เราจะรู้ได้อย่างไรว่านักพัฒนาบางคนกระตือรือร้นที่จะหลีกเลี่ยงสไตล์แบบเรียงซ้อน? มันคือการเพิ่มขึ้นของเครื่องมือส่วนหน้า “สมัยใหม่” — เช่น กรอบงาน CSS-in-JS — ออกแบบมาเพื่อจุดประสงค์นั้นโดยเฉพาะ การทำงานกับสไตล์ที่แยกจากกันซึ่งมีการกำหนดขอบเขตไว้อย่างแน่นหนาสำหรับส่วนประกอบเฉพาะอาจดูเหมือนได้สูดอากาศบริสุทธิ์ มันขจัดความจำเป็นในการตั้งชื่อสิ่งต่าง ๆ ซึ่งยังคงเป็นหนึ่งในงานส่วนหน้าที่เกลียดชังและใช้เวลานานที่สุด และช่วยให้นักพัฒนาสามารถทำงานได้อย่างมีประสิทธิผลโดยไม่ต้องเข้าใจหรือใช้ประโยชน์จากการสืบทอด CSS อย่างถ่องแท้ แต่การละทิ้ง CSS Cascade นั้นมาพร้อมกับปัญหาในตัวมันเอง ตัวอย่างเช่น การเขียนสไตล์ใน JavaScript จำเป็นต้องมีการกำหนดค่าบิลด์จำนวนมาก และมักจะนำไปสู่สไตล์ที่ผสมผสานกับมาร์กอัปคอมโพเนนต์หรือ HTML อย่างเชื่องช้า แทนที่จะพิจารณาแบบแผนการตั้งชื่ออย่างรอบคอบ เราอนุญาตให้สร้างเครื่องมือเพื่อสร้างตัวเลือกและตัวระบุให้เราโดยอัตโนมัติ (เช่น .jsx-3130221066) โดยกำหนดให้นักพัฒนาต้องตามทันภาษาหลอกภาษาอื่นในตัวมันเอง (ราวกับว่าภาระการรับรู้ในการทำความเข้าใจว่าเอฟเฟกต์การใช้งานส่วนประกอบทั้งหมดของคุณยังไม่เพียงพอ!) การสรุปงานของการตั้งชื่อคลาสให้กับเครื่องมือเพิ่มเติมหมายความว่าการดีบักขั้นพื้นฐานมักถูกจำกัดไว้ที่เวอร์ชันแอปพลิเคชันเฉพาะที่คอมไพล์เพื่อการพัฒนา แทนที่จะใช้ประโยชน์จากคุณลักษณะดั้งเดิมของเบราว์เซอร์ที่รองรับการดีบักแบบสด เช่น เครื่องมือสำหรับนักพัฒนา เกือบจะเหมือนกับว่าเราจำเป็นต้องพัฒนาเครื่องมือเพื่อแก้ไขข้อบกพร่องของเครื่องมือที่เราใช้เพื่อสรุปสิ่งที่เว็บมีให้อยู่แล้ว — ทั้งหมดนี้เพื่อประโยชน์ในการหลีกหนีจาก “ความเจ็บปวด” ในการเขียน CSS มาตรฐาน โชคดีที่ฟีเจอร์ CSS สมัยใหม่ไม่เพียงแต่ทำให้การเขียน CSS มาตรฐานมีความยืดหยุ่นมากขึ้นเท่านั้น แต่ยังช่วยให้นักพัฒนาเช่นเรามีพลังมากขึ้นในการจัดการน้ำตกและทำให้มันทำงานให้เราด้วย CSS Cascade Layers เป็นตัวอย่างที่ดี แต่มีคุณลักษณะอื่นที่ได้รับความสนใจอย่างน่าประหลาดใจ แม้ว่าจะมีการเปลี่ยนแปลงในขณะนี้เนื่องจากเพิ่งเข้ากันได้กับ Baseline CSS @scope At-Rule ฉันถือว่า CSS @scope at-rule เป็นวิธีการรักษาที่เป็นไปได้สำหรับความวิตกกังวลที่เกิดจากการรั่วไหลของสไตล์ที่เราได้กล่าวถึง ซึ่งไม่ได้บังคับให้เราต้องประนีประนอมข้อดีของเว็บดั้งเดิมสำหรับสิ่งที่เป็นนามธรรมและเครื่องมือสร้างเพิ่มเติม “@scope CSS at-rule ช่วยให้คุณสามารถเลือกองค์ประกอบในแผนผังย่อย DOM ที่เฉพาะเจาะจง โดยกำหนดเป้าหมายองค์ประกอบอย่างแม่นยำโดยไม่ต้องเขียนตัวเลือกเฉพาะเจาะจงมากเกินไปซึ่งยากจะแทนที่ และไม่ต้องเชื่อมโยงตัวเลือกของคุณแน่นเกินไปกับโครงสร้าง DOM”— MDN
กล่าวอีกนัยหนึ่ง เราสามารถทำงานกับสไตล์ที่แยกออกมาได้ในบางกรณี โดยไม่ต้องเสียสละมรดก การเรียงซ้อน หรือแม้แต่การแยกข้อกังวลขั้นพื้นฐานซึ่งเป็นหลักการชี้แนะที่มีมายาวนานในการพัฒนาส่วนหน้า นอกจากนี้ยังมีความครอบคลุมเบราว์เซอร์ที่ยอดเยี่ยมอีกด้วย ในความเป็นจริง Firefox 146 ได้เพิ่มการรองรับ @scope ในเดือนธันวาคม ทำให้ Baseline เข้ากันได้เป็นครั้งแรก นี่คือการเปรียบเทียบง่ายๆ ระหว่างปุ่มที่ใช้รูปแบบ BEM กับกฎ @scope: <คลาสปุ่ม = "ปุ่มปุ่ม -- หลัก"> ปุ่ม>
<สไตล์> .button .button__text { /* รูปแบบข้อความของปุ่ม */ } .button .button__icon { /* รูปแบบไอคอนปุ่ม */ } .button--primary { รูปแบบปุ่มหลัก */ } สไตล์>
<คลาสปุ่ม = "ปุ่มหลัก"> คลิกฉัน → ปุ่ม>
<สไตล์> @scope (.ปุ่มหลัก) { span:ลูกคนแรก { /* รูปแบบข้อความของปุ่ม */ } span:last-child { /* รูปแบบไอคอนปุ่ม */ } } สไตล์>
กฎ @scope ช่วยให้มีความแม่นยำและซับซ้อนน้อยลง นักพัฒนาไม่จำเป็นต้องสร้างขอบเขตโดยใช้ชื่อคลาสอีกต่อไป ซึ่งจะทำให้พวกเขาสามารถเขียนตัวเลือกตามองค์ประกอบ HTML ดั้งเดิมได้ ดังนั้นจึงขจัดความจำเป็นในการใช้รูปแบบชื่อคลาส CSS ที่กำหนด เพียงขจัดความจำเป็นในการจัดการชื่อคลาส @scope ก็สามารถบรรเทาความกลัวที่เกี่ยวข้องกับ CSS ในโปรเจ็กต์ขนาดใหญ่ได้
การใช้งานขั้นพื้นฐาน
ในการเริ่มต้น ให้เพิ่มกฎ @scope ลงใน CSS ของคุณ และแทรกตัวเลือกรูทที่จะกำหนดขอบเขตสไตล์:
@scope (<ตัวเลือก>) {
/* ลักษณะที่กำหนดขอบเขตไว้ที่
ตัวอย่างเช่น หากเรากำหนดขอบเขตสไตล์ให้กับองค์ประกอบ
@scope (นำทาง) { a { /* รูปแบบลิงก์ภายในขอบเขตการนำทาง */ }
a:active { /* รูปแบบลิงก์ที่ใช้งานอยู่ */ }
a:active::before { /* Active link with pseudo-element for extra styling */ }
@media (ความกว้างสูงสุด: 768px) { a { /* การปรับแบบตอบสนอง */ } } }
นี่ไม่ใช่คุณลักษณะที่แหวกแนวด้วยตัวมันเอง อย่างไรก็ตาม คุณสามารถเพิ่มอาร์กิวเมนต์ที่สองลงในขอบเขตเพื่อสร้างขอบเขตล่าง ซึ่งกำหนดจุดเริ่มต้นและจุดสิ้นสุดของขอบเขตได้อย่างมีประสิทธิภาพ
/* องค์ประกอบใดๆ ภายใน ul จะไม่มีการใช้สไตล์ */ @scope (nav) ถึง (ul) { { ขนาดตัวอักษร: 14px; } }
แนวปฏิบัตินี้เรียกว่าการกำหนดขอบเขตแบบโดนัท และมีหลายวิธีที่เราสามารถใช้ได้ รวมถึงชุดของตัวเลือกที่คล้ายกันและมีความเฉพาะเจาะจงสูงควบคู่กับโครงสร้าง DOM อย่างแน่นหนา การ :ไม่ใช่ตัวเลือกหลอก หรือการกำหนดชื่อคลาสเฉพาะให้กับองค์ประกอบ ภายใน
บทสรุป เฟรมเวิร์ก CSS ที่เน้นยูทิลิตี้เป็นหลัก เช่น Tailwind ทำงานได้ดีสำหรับการสร้างต้นแบบและโปรเจ็กต์ขนาดเล็ก อย่างไรก็ตาม ประโยชน์ที่ได้รับจะลดลงอย่างรวดเร็วเมื่อใช้ในโครงการขนาดใหญ่ที่เกี่ยวข้องกับนักพัฒนามากกว่าสองราย การพัฒนาส่วนหน้ามีความซับซ้อนมากขึ้นในช่วงไม่กี่ปีที่ผ่านมา และ CSS ก็ไม่มีข้อยกเว้น แม้ว่ากฎ @scope จะไม่ใช่วิธีแก้ทั้งหมด แต่ก็สามารถลดความจำเป็นในการใช้เครื่องมือที่ซับซ้อนได้ เมื่อใช้แทนหรือควบคู่ไปกับการตั้งชื่อคลาสเชิงกลยุทธ์ @scope จะทำให้การเขียน CSS ที่สามารถบำรุงรักษาได้ง่ายและสนุกยิ่งขึ้น อ่านต่อ
CSS @ขอบเขต (MDN) “CSS @scope”, ฮวน ดิเอโก โรดริเกซ (CSS-Tricks) บันทึกประจำรุ่น Firefox 146 (Firefox) รองรับเบราว์เซอร์ (CanIUse) CSS Frameworks ยอดนิยม (สถานะของ CSS 2024) “C” ใน CSS: Cascade”, Thomas Yip (CSS-Tricks) บทนำ BEM (รับ BEM)