ช่วยให้เบราว์เซอร์ปรับให้เหมาะสมด้วย CSS Contain Property

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ คุณสมบัติ CSS contain วิธีการอธิบายเลย์เอาต์ของคุณแก่เบราว์เซอร์ จึงสามารถทำการเพิ่มประสิทธิภาพได้ อย่างไรก็ตาม มันมาพร้อมกับผลข้างเคียงบางประการในแง่ของการจัดวางของคุณ

ในบทความนี้ ผมจะมาแนะนำ CSS Specification ที่เพิ่งกลายมาเป็น W3C Recommendation CSS Containment Specifications กำหนดคุณสมบัติเดียว contain และช่วยให้คุณอธิบายให้เบราว์เซอร์ทราบว่าส่วนใดของเค้าโครงของคุณเป็นอิสระ และไม่จำเป็นต้องคำนวณใหม่หากส่วนอื่นของเค้าโครงมีการเปลี่ยนแปลง

แม้ว่าคุณสมบัตินี้จะมีอยู่เนื่องจากเหตุผลในการเพิ่มประสิทธิภาพ แต่ก็อาจส่งผลต่อเค้าโครงหน้าของคุณได้เช่นกัน ดังนั้น ในบทความนี้ ฉันจะอธิบายประเภทของการกักกันที่คุณสามารถใช้ประโยชน์ได้ แต่ยังรวมถึงสิ่งที่คุณต้องระวังหากใช้ contain กับองค์ประกอบในไซต์ของคุณ

ปัญหาการคำนวณเค้าโครงใหม่

หากคุณกำลังสร้างหน้าเว็บที่ไม่ซับซ้อนซึ่งไม่ได้เพิ่มหรือเปลี่ยนแปลงองค์ประกอบแบบไดนามิกหลังจากที่โหลดโดยใช้ JavaScript คุณไม่จำเป็นต้องกังวลเกี่ยวกับปัญหาที่ CSS Containment แก้ไข เบราว์เซอร์จำเป็นต้องคำนวณเค้าโครงของคุณเพียงครั้งเดียว เมื่อมีการโหลดหน้าเว็บ

กรณีที่ Containment มีประโยชน์คือเมื่อคุณต้องการเพิ่มองค์ประกอบในหน้าของคุณโดยที่ผู้ใช้ไม่จำเป็นต้องโหลดซ้ำ ในตัวอย่างของฉัน ฉันสร้างรายการกิจกรรมจำนวนมาก หากคุณคลิกปุ่ม เหตุการณ์แรกจะได้รับการแก้ไข เพิ่มองค์ประกอบแบบลอย และข้อความจะเปลี่ยนไป:

รายการสินค้าพร้อมปุ่มเปลี่ยนเนื้อหาบางส่วนในรายการแรก
(ดูตัวอย่างเริ่มต้นใน CodePen)

เมื่อเนื้อหาในกล่องของเรามีการเปลี่ยนแปลง เบราว์เซอร์จะต้องพิจารณาว่าองค์ประกอบใดๆ อาจมีการเปลี่ยนแปลง โดยทั่วไปแล้วเบราว์เซอร์สามารถจัดการกับสิ่งนี้ได้ค่อนข้างดี เนื่องจากเป็นเรื่องปกติที่จะเกิดขึ้น อย่างที่กล่าวไปในฐานะนักพัฒนา คุณจะรู้ว่าส่วนประกอบแต่ละอย่างเป็นอิสระหรือไม่ และการเปลี่ยนแปลงหนึ่งไม่มีผลกับองค์ประกอบอื่นๆ ดังนั้นจึงเป็นการดีหากคุณสามารถแจ้งให้เบราว์เซอร์ทราบสิ่งนี้ผ่าน CSS ของคุณ นี่คือสิ่งที่การกักเก็บและคุณสมบัติ CSS contain ให้คุณ

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การกักกันช่วยได้อย่างไร?

เอกสาร HTML เป็นโครงสร้างแบบต้นไม้ที่คุณสามารถมองเห็นได้เมื่อตรวจสอบองค์ประกอบใดๆ ด้วย DevTools ในตัวอย่างด้านบนของฉัน ฉันระบุรายการหนึ่งที่ฉันต้องการเปลี่ยนแปลงโดยใช้ JavaScript แล้วทำการเปลี่ยนแปลงบางอย่างกับ internals (ซึ่งหมายความว่าฉันกำลังเปลี่ยนแปลงเฉพาะในทรีย่อยสำหรับรายการนั้น)

DevTools พร้อมรายการของรายการเด่นที่ขยายเพื่อดูองค์ประกอบภายใน
การตรวจสอบรายการใน DevTools

การใช้คุณสมบัติคุณสมบัติกับ contain จะบอกเบราว์เซอร์ว่าการเปลี่ยนแปลงถูกกำหนดขอบเขตไปยังทรีย่อยขององค์ประกอบนั้น เพื่อให้เบราว์เซอร์ทำการเพิ่มประสิทธิภาพที่เป็นไปได้ — ปลอดภัยโดยที่รู้ว่าสิ่งอื่นนอกองค์ประกอบนั้นจะไม่เปลี่ยนแปลง สิ่งที่เบราว์เซอร์บางตัวอาจทำนั้นขึ้นอยู่กับเอ็นจิ้น คุณสมบัติ CSS ช่วยให้คุณ — ในฐานะนักพัฒนาและผู้เชี่ยวชาญในเลย์เอาต์นี้ — มีโอกาสที่จะแจ้งให้ทราบ

ในหลายกรณี คุณจะปลอดภัยในการดำเนินการต่อและเริ่มใช้คุณสมบัติ contain อย่างไรก็ตาม ค่าต่างๆ นั้นมาพร้อมกับผลข้างเคียงที่อาจเกิดขึ้นซึ่งควรค่าแก่ความเข้าใจก่อนที่จะเพิ่มคุณสมบัติให้กับองค์ประกอบในไซต์ของคุณ

ใช้การกักกัน

คุณสมบัติ contain สามารถตั้งค่าการกักกันได้สามประเภท:

  • layout
  • paint
  • size

หมายเหตุ : มีค่า style ในข้อกำหนดระดับ 2 มันถูกลบออกจากระดับ 1 ดังนั้นจึงไม่ปรากฏในคำแนะนำและไม่ได้ใช้งานใน Firefox

เค้าโครง

การจัดวางเลย์เอาต์ทำให้เกิดประโยชน์สูงสุด หากต้องการเปิดการจัดวาง ให้ใช้ข้อมูลโค้ดต่อไปนี้:

 .item { contain: layout; }

เมื่อเปิดใช้งานการจัดวางเลย์เอาต์ เบราว์เซอร์จะรู้ว่าไม่มีสิ่งใดภายนอกองค์ประกอบที่สามารถส่งผลกระทบต่อเลย์เอาต์ภายใน และไม่มีสิ่งใดจากภายในองค์ประกอบสามารถเปลี่ยนแปลงอะไรเกี่ยวกับเลย์เอาต์ของสิ่งต่าง ๆ ภายนอกได้ ซึ่งหมายความว่าสามารถเพิ่มประสิทธิภาพที่เป็นไปได้สำหรับสถานการณ์นี้

มีสิ่งเพิ่มเติมสองสามอย่างเกิดขึ้นเมื่อเปิดใช้งานการจำกัดเลย์เอาต์ สิ่งเหล่านี้คือทุกสิ่งที่ทำให้แน่ใจว่ากล่องและเนื้อหานี้ไม่ขึ้นกับส่วนที่เหลือของทรี

กล่องสร้าง บริบทการจัดรูปแบบอิสระ เพื่อให้แน่ใจว่าเนื้อหาของกล่องยังคงอยู่ในกล่อง โดยเฉพาะอย่างยิ่งลอยจะถูกบรรจุและระยะขอบจะไม่ยุบผ่านกล่อง นี่เป็นพฤติกรรมเดียวกับที่เราเปิดเมื่อเราใช้ display: flow-root ตามที่อธิบายในบทความของฉัน "การทำความเข้าใจเค้าโครง CSS และบริบทการจัดรูปแบบบล็อก" หากทุ่นสามารถโผล่ออกมาจากกล่องของคุณได้ ทำให้ข้อความต่อไปนี้ไหลไปรอบๆ ทุ่น นั่นอาจเป็นสถานการณ์ที่องค์ประกอบ กำลัง เปลี่ยนเลย์เอาต์ของสิ่งต่าง ๆ ภายนอก ทำให้มันเป็นตัวเลือกที่ไม่ดีสำหรับการกักกัน

กล่องบรรจุทำหน้าที่เป็นบล็อกบรรจุสำหรับทายาทตำแหน่งที่แน่นอนหรือตายตัว ซึ่งหมายความว่าจะทำหน้าที่เสมือนว่าคุณเคยใช้ position: relative กับกล่องที่คุณใช้ contain: layout ย์เอาต์

กล่องนี้ยังสร้าง บริบทการซ้อน ดังนั้น z-index จะทำงานในองค์ประกอบนี้ ลูกจะถูกจัดเรียงตามบริบทใหม่นี้

หากเราดูตัวอย่าง คราวนี้ด้วย contain: layout คุณจะเห็นว่าเมื่อมีการแนะนำองค์ประกอบแบบลอย จะไม่โผล่ออกมาด้านล่างของกล่องอีกต่อไป นี่คือการดำเนินการตามบริบทการจัดรูปแบบบล็อกใหม่ของเรา ซึ่งประกอบด้วยทุ่น

รายการสิ่งของ องค์ประกอบที่ลอยอยู่ภายในขอบเขตของกล่องหลัก
การใช้ประกอบด้วย: เลย์เอาต์ที่ลอยอยู่ (ดูตัวอย่างการจัดเลย์เอาต์ใน CodePen)

สี

ในการเปิดการกักเก็บสี ให้ใช้สิ่งต่อไปนี้:

 .item { contain: paint; }

เมื่อเปิดใช้งานการกักเก็บสี จะเกิดผลข้างเคียงแบบเดียวกับที่เห็นในการจัดวาง: กล่องที่มีจะกลายเป็นบริบทการจัดรูปแบบอิสระ บล็อกที่มีองค์ประกอบสำหรับองค์ประกอบที่วางตำแหน่ง และการสร้างบริบทการซ้อน

สิ่งที่บรรจุสีทำนั้นบ่งบอกให้เบราว์เซอร์เห็นว่าองค์ประกอบภายในบล็อกที่บรรจุอยู่จะไม่ปรากฏให้เห็นนอกขอบเขตของกล่องนั้น เนื้อหาจะถูกตัดไปที่กล่องเป็นหลัก

เราสามารถเห็นสิ่งนี้เกิดขึ้นได้ด้วยตัวอย่างง่ายๆ แม้ว่าเราจะให้ความสูงการ์ดของเรา แต่ไอเท็มที่ลอยอยู่ก็ยังโผล่ออกมาด้านล่างของกล่องเนื่องจากการที่ทุ่นนั้นถูกดึงออกจากกระแส

กล่องลอยโผล่ด้านล่างของกล่องที่บรรจุ
ลอยไม่มีอยู่ในรายการ

เมื่อเปิดใช้การกักเก็บสี สิ่งของที่ลอยอยู่จะถูกตัดให้มีขนาดเท่ากับกล่อง ไม่มีสิ่งใดสามารถทาสีนอกขอบเขตขององค์ประกอบที่ contain: paint แล้ว

กล่องที่มีกล่องลอยอยู่ข้างในซึ่งถูกตัดออกจากกล่อง
เนื้อหาของกล่องถูกตัดไปที่ความสูงของกล่อง (ดูตัวอย่างการระบายสีบน CodePen)

ขนาด

การควบคุมขนาดเป็นค่าที่มีแนวโน้มสูงที่จะก่อให้เกิดปัญหาแก่คุณ หากคุณไม่ทราบถึงวิธีการทำงานอย่างเต็มที่ ในการใช้การจำกัดขนาด ให้ใช้:

 .item { contain: size; }

หากคุณใช้การจำกัดขนาด แสดงว่าคุณกำลังบอกเบราว์เซอร์ว่าคุณทราบขนาดของกล่องและจะไม่เปลี่ยนแปลง ซึ่งหมายความว่าหากคุณมีกล่องที่ปรับขนาดอัตโนมัติในมิติบล็อก จะถือว่ากล่องนั้นไม่มีขนาด ดังนั้นกล่องจะยุบลงเหมือนกับว่าไม่มีเนื้อหา

ในตัวอย่างด้านล่าง ฉันไม่ได้ li ความสูง พวกเขายังมี contain: size ที่ใช้ คุณจะเห็นได้ว่ารายการทั้งหมดได้ยุบลงราวกับว่าไม่มีเนื้อหาเลย ทำให้รายการดูแปลกมาก!

รายการสินค้าพร้อมปุ่มเปลี่ยนเนื้อหาบางส่วนในรายการแรก
(ดูตัวอย่างขนาดใน CodePen)

หากคุณกำหนดความสูงให้กับกล่อง ความสูงจะได้รับการเคารพเมื่อ contain: size เพียงอย่างเดียว การควบคุมขนาดจะไม่สร้างบริบทการจัดรูปแบบใหม่ ดังนั้นจึงไม่มีส่วนลอยและระยะขอบตามการจัดวางและระบายสี มีโอกาสน้อยที่คุณจะใช้มันคนเดียว แต่เป็นไปได้มากที่สุดที่คุณจะใช้มันร่วมกับค่าอื่น ๆ ของการ contain เพื่อให้สามารถกักกันได้มากที่สุด

ค่าชวเลข

ในกรณีส่วนใหญ่ คุณสามารถใช้ค่าชวเลขค่าใดค่าหนึ่งจากสองค่าเพื่อกำจัดการกักกันให้ดีที่สุด ในการเปิดใช้การจัดวางและการระบายสี ให้ใช้ contain: content; และเพื่อเปิดการกักเก็บที่เป็นไปได้ทั้งหมด (โปรดทราบว่าไอเท็มที่ไม่มีขนาดจะยุบลง) ให้ใช้ contain: strict

ข้อมูลจำเพาะกล่าวว่า:

contain: content มีเหตุผล "ปลอดภัย" เพื่อนำไปใช้ในวงกว้าง ในทางปฏิบัติผลกระทบของมันค่อนข้างน้อย และเนื้อหาส่วนใหญ่จะไม่ละเมิดข้อจำกัดของมัน อย่างไรก็ตาม เนื่องจากไม่ได้ใช้การจำกัดขนาด องค์ประกอบจึงยังคงตอบสนองต่อขนาดของเนื้อหาได้ ซึ่งอาจทำให้เลย์เอาต์ไม่ถูกต้องขยายขึ้นไปบนต้นไม้มากกว่าที่ต้องการ ใช้การจำกัด contain: strict เมื่อเป็นไปได้ เพื่อให้ได้การกักกันมากที่สุด”

ดังนั้น หากคุณไม่ทราบขนาดของรายการล่วงหน้า และเข้าใจข้อเท็จจริงว่าจะมีลอยตัวและระยะขอบ ให้ใช้ contain: content หากคุณทราบขนาดของสิ่งของนอกเหนือจากการพอใจกับผลข้างเคียงอื่นๆ ของการกักกัน ให้ใช้ contain: strict ที่เหลือขึ้นอยู่กับเบราว์เซอร์ คุณทำเสร็จแล้วโดยอธิบายว่าเค้าโครงของคุณทำงานอย่างไร

ฉันสามารถใช้การกักกันตอนนี้ได้ไหม

ข้อกำหนด CSS Containment ตอนนี้เป็น W3C Recommendation ซึ่งบางครั้งเราเรียกว่า มาตรฐานเว็บ เพื่อให้ข้อมูลจำเพาะมาถึงขั้นตอนนี้ จำเป็นต้องมีการใช้งานคุณลักษณะสองอย่าง ซึ่งเราสามารถเห็นได้ทั้งใน Firefox และ Chrome:

สกรีนช็อตของข้อมูลสนับสนุนเบราว์เซอร์เกี่ยวกับ Containment on Can I Use
การสนับสนุนเบราว์เซอร์สำหรับการกักกัน (ที่มา: ฉันใช้ได้ไหม)

เนื่องจากคุณสมบัตินี้โปร่งใสต่อผู้ใช้ จึงปลอดภัยอย่างสมบูรณ์ที่จะเพิ่มไปยังไซต์ใดๆ แม้ว่าคุณจะมีผู้เข้าชมจำนวนมากในเบราว์เซอร์ที่ไม่สนับสนุนก็ตาม หากเบราว์เซอร์ไม่รองรับการกักกัน ผู้เยี่ยมชมจะได้รับประสบการณ์ที่พวกเขามักจะได้รับ ผู้ที่อยู่ในเบราว์เซอร์ที่รองรับจะได้รับประสิทธิภาพที่เพิ่มขึ้น

ฉันขอแนะนำว่านี่เป็นสิ่งที่ดีที่จะเพิ่มส่วนประกอบใด ๆ ที่คุณสร้างในส่วนประกอบหรือไลบรารีรูปแบบ หากคุณทำงานในลักษณะนี้ มีแนวโน้มว่าแต่ละองค์ประกอบได้รับการออกแบบให้เป็นสิ่งที่เป็นอิสระซึ่งไม่มีผลกระทบกับองค์ประกอบอื่น ๆ บน หน้าทำให้ contain: content ที่เป็นประโยชน์เพิ่มเติม

ดังนั้น หากคุณมีหน้าที่เพิ่มเนื้อหาลงใน DOM หลังจากโหลด ฉันขอแนะนำให้ลองดู — หากคุณได้ผลลัพธ์ที่น่าสนใจ แจ้งให้เราทราบในความคิดเห็น!

แหล่งข้อมูลที่เกี่ยวข้อง

แหล่งข้อมูลต่อไปนี้จะให้รายละเอียดเพิ่มเติมเกี่ยวกับการนำการกักกันไปใช้และประโยชน์ด้านประสิทธิภาพที่อาจเกิดขึ้น:

  • “คุณสมบัติ CSS ที่ containเอกสารเว็บ MDN
  • “การกักเก็บ CSS ใน Chrome 52” Google Developers
  • “โมดูลบรรจุ CSS ระดับ 1” คำแนะนำของ W3C
  • “บทนำสู่การควบคุม CSS” Manuel Rego Casasnovas