ไวยากรณ์ที่สื่อความหมาย

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

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

กำลังอธิบายความหนาแน่นด้วย x

<img> ที่มีความกว้างคงที่จะใช้ขนาดวิวพอร์ตเท่ากันในทุกบริบทของการท่องเว็บ โดยไม่คำนึงถึงความหนาแน่นในจอแสดงผลของผู้ใช้ คือจำนวนพิกเซลจริงที่ทำให้หน้าจอของผู้ใช้ เช่น รูปภาพที่มีความกว้างตามปกติเป็น 400px จะใช้พื้นที่เกือบทั้งวิวพอร์ตของเบราว์เซอร์ทั้งใน Google Pixel รุ่นเดิมและ Pixel 6 Pro รุ่นใหม่กว่า โดยอุปกรณ์ทั้งสองมีวิวพอร์ตแบบกว้าง 412px ตรรกะ

Pixel 6 Pro มีจอแสดงผลที่คมชัดมาก แต่ 6 Pro มีความละเอียดจริง 1440 × 3120 พิกเซล ส่วน Pixel จะมีความละเอียด 1080 × 1920 พิกเซล คือจำนวนพิกเซลฮาร์ดแวร์ที่ประกอบกันเป็นหน้าจอ

อัตราส่วนระหว่างพิกเซลเชิงตรรกะของอุปกรณ์กับพิกเซลจริงคืออัตราส่วนพิกเซลของอุปกรณ์สําหรับจอแสดงผลนั้น (DPR) DPR จะคำนวณโดยการหารความละเอียดหน้าจอจริงของอุปกรณ์ด้วยพิกเซล CSS ของวิวพอร์ต

DPR 2 ที่แสดงในหน้าต่างคอนโซล

Pixel รุ่นแรกมี DPR อยู่ที่ 2.6 ส่วน Pixel 6 Pro มี DPR อยู่ที่ 3.5

iPhone 4 ซึ่งเป็นอุปกรณ์เครื่องแรกที่มี DPR มากกว่า 1 รายงานอัตราส่วนพิกเซลของอุปกรณ์เป็น 2 ซึ่งหมายความว่าความละเอียดของหน้าจอจริงจะเป็น 2 เท่าของความละเอียดเชิงตรรกะ อุปกรณ์รุ่นก่อนหน้า iPhone 4 มี DPR เป็น 1: 1 พิกเซลตรรกะกับพิกเซลจริง 1 พิกเซล

หากคุณเห็นรูปภาพที่มีความกว้าง 400px ในจอแสดงผลที่มี DPR เป็น 2 พิกเซลเชิงตรรกะแต่ละพิกเซลจะแสดงผลในพิกเซลจริงของจอแสดงผล 4 พิกเซล ได้แก่ แนวนอน 2 รูปและแนวตั้ง 2 แบบ รูปภาพจะไม่ได้รับประโยชน์จากจอแสดงผลความหนาแน่นสูง แต่จะดูเหมือนกับในจอแสดงผลที่มี DPR เท่ากับ 1 แน่นอนว่าเครื่องมือแสดงผลของเบราว์เซอร์ เช่น ข้อความ รูปร่าง CSS หรือ SVG จะถูกวาดเพื่อให้เหมาะสมกับการแสดงผลที่มีความหนาแน่นสูง แต่ตามที่คุณได้เรียนรู้จากรูปแบบภาพและการบีบอัด ภาพแรสเตอร์จะเป็นตารางกริดพิกเซลแบบคงที่ แม้ว่าภาพอาจไม่ชัดเจนนักแต่ภาพแรสเตอร์ที่มีการปรับเพิ่มขนาดเพื่อให้เหมาะกับการแสดงผลที่มีความหนาแน่นสูงจะดูเหมือนความละเอียดต่ำเมื่อเทียบกับภาพโดยรอบ

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

ภาพระยะใกล้ของกลีบดอกไม้ที่แสดงความหนาแน่นของความคลาดเคลื่อน

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

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

คุณคงเดาได้ว่าอุปกรณ์มือถือที่มี DPR เป็น 1 นั้นพบได้น้อยมาก แต่ยังคงพบได้บ่อยในบริบทการท่องเว็บบน "เดสก์ท็อป" จากข้อมูลที่แชร์โดย Matt Hobbs เซสชันการท่องเว็บใน GOV.UK ประมาณ 18% จากเดือนพฤศจิกายน 2022 รายงาน DPR อยู่ที่ 1 แม้ว่ารูปภาพความหนาแน่นสูงจะดูแบบเดียวกับที่ผู้ใช้คาดหวัง แต่จะใช้แบนด์วิดท์และต้นทุนในการประมวลผลที่สูงขึ้นมาก โดยเฉพาะอย่างยิ่งผู้ใช้ที่ใช้อุปกรณ์รุ่นเก่าและอุปกรณ์ที่มีประสิทธิภาพต่ำกว่าซึ่งอาจยังใช้จอแสดงผลความหนาแน่นต่ำอยู่

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

แอตทริบิวต์ srcset ระบุตัวเลือกที่คั่นด้วยคอมมาอย่างน้อย 1 รายการสำหรับการแสดงผลรูปภาพ ผู้สมัครแต่ละรายการประกอบด้วย 2 สิ่งคือ URL เช่นเดียวกับที่คุณใช้ใน src และไวยากรณ์ที่อธิบายแหล่งที่มาของรูปภาพนั้น ผู้สมัครแต่ละรายใน srcset อธิบายด้วยความกว้าง ("ไวยากรณ์ w") หรือความหนาแน่นที่ต้องการ ("ไวยากรณ์ x")

ไวยากรณ์ x เป็นสัญญาณสั้นๆ ของ "แหล่งที่มานี้เหมาะสำหรับการแสดงผลที่มีความหนาแน่นนี้" คำที่รอพิจารณาตามด้วย 2x คือหน้าจอที่มี DPR เท่ากับ 2

<img src="low-density.jpg" srcset="double-density.jpg 2x" alt="...">

เบราว์เซอร์ที่รองรับ srcset จะมีตัวเลือก 2 ตัวเลือก ได้แก่ double-density.jpg ซึ่ง 2x อธิบายว่าเหมาะสมสำหรับจอแสดงผลที่มี DPR เป็น 2 และ low-density.jpg ในแอตทริบิวต์ src คือตัวเลือกที่เลือกไว้หากไม่มีที่เหมาะสมมากกว่าใน srcset สำหรับเบราว์เซอร์ที่ไม่มีการรองรับ srcset ระบบจะไม่สนใจแอตทริบิวต์และเนื้อหา โดยจะขอเนื้อหาของ src ตามปกติ

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

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

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

การอธิบายความกว้างด้วย w

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

srcset="small.jpg 600w, large.jpg 1200w"

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

กำลังอธิบายการใช้งานด้วย sizes

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

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

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

อาจฟังดูซับซ้อนสักเล็กน้อย แต่ในทางปฏิบัติแล้วจะเข้าใจได้ง่ายกว่ามาก:

<img
 sizes="80vw"
 srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
 src="fallback.jpg"
 alt="...">

ในตัวอย่างนี้ ค่า sizes นี้จะแจ้งให้เบราว์เซอร์ทราบว่าพื้นที่ในเลย์เอาต์ของเราที่ img ใช้ความกว้าง 80vw-80% ของวิวพอร์ต โปรดทราบว่านี่ไม่ใช่วิธีการ แต่เป็นคำอธิบายขนาดของรูปภาพในเลย์เอาต์ของหน้า แต่ไม่ได้บอกว่า "ทำให้รูปภาพนี้ใช้พื้นที่ 80% ของวิวพอร์ต" แต่ "รูปภาพนี้จะใช้พื้นที่ 80% ของวิวพอร์ตเมื่อหน้าเว็บแสดงผลแล้ว"

ในฐานะนักพัฒนาซอฟต์แวร์ งานทุกอย่างก็เสร็จสมบูรณ์แล้ว คุณได้อธิบายรายการแหล่งที่มาของตัวเลือกอย่างถูกต้องใน srcset และความกว้างของรูปภาพใน sizes และไวยากรณ์ x ใน srcset ส่วนที่เหลือจะขึ้นอยู่กับเบราว์เซอร์

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

คุณได้แจ้งเบราว์เซอร์ว่ารูปภาพนี้จะใช้พื้นที่ 80% ของวิวพอร์ตที่มีอยู่ ดังนั้นหากเราแสดง img นี้ในอุปกรณ์ที่มีวิวพอร์ตกว้าง 1,000 พิกเซล รูปภาพนี้จะใช้พื้นที่ 800 พิกเซล เบราว์เซอร์จะนำค่านั้นมาหารด้วยความกว้างของตัวเลือกแหล่งที่มาของรูปภาพแต่ละรายการที่เราระบุไว้ใน srcset แหล่งที่มาขนาดเล็กที่สุดมีขนาดเริ่มต้นอยู่ที่ 600 พิกเซล ดังนั้น: 600÷800=.75 รูปภาพขนาดกลางของเรากว้าง 1,200 พิกเซล: 1200÷800=1.5 รูปภาพที่ใหญ่ที่สุดของเรามีขนาดกว้าง 2,000 พิกเซล: 2000÷800=2.5

ผลลัพธ์ของการคำนวณดังกล่าว (.75, 1.5 และ 2.5) คือตัวเลือก DPR ปรับแต่งให้เหมาะกับขนาดวิวพอร์ตของผู้ใช้โดยเฉพาะ เนื่องจากเบราว์เซอร์มีข้อมูลเกี่ยวกับความหนาแน่นของการแสดงผลของผู้ใช้อยู่แล้ว ระบบจึงทำการตัดสินใจต่างๆ ดังนี้

สำหรับขนาดวิวพอร์ตนี้ ระบบจะทิ้งตัวเลือก small.jpg โดยไม่คำนึงถึงความหนาแน่นของการแสดงผลของผู้ใช้ หากมี DPR ที่คำนวณแล้วต่ำกว่า 1 แหล่งที่มานี้จะต้องมีการปรับขนาดสำหรับผู้ใช้ ดังนั้นข้อมูลนี้จึงไม่เหมาะสม ในอุปกรณ์ที่มี DPR เท่ากับ 1 ระบบของ medium.jpg จะให้ค่าที่ใกล้เคียงที่สุดซึ่งเหมาะสมที่สุดในการแสดงที่อัตรา DPR ที่ 1.5 ดังนั้นจึงมีขนาดใหญ่กว่าที่จำเป็นเล็กน้อย แต่โปรดทราบว่าการลดการปรับขนาดเป็นขั้นตอนที่ราบรื่นด้วยการมองเห็น อุปกรณ์ที่มี DPR เท่ากับ 2 นั้น large.jpg เป็นการจับคู่ที่ใกล้เคียงที่สุด จึงได้รับเลือก

หากรูปภาพเดียวกันแสดงผลในวิวพอร์ตที่มีความกว้าง 600 พิกเซล ผลลัพธ์ที่ได้จากการคำนวณครั้งนี้จะต่างออกไปโดยสิ้นเชิง นั่นคือตอนนี้ 80vw กลายเป็น 480px เมื่อนำความกว้างของแหล่งที่มาไปหารด้วยค่านั้น เราจะได้ 1.25, 2.5 และ 4.1666666667 ที่ขนาดวิวพอร์ตนี้ ระบบจะเลือก small.jpg ในอุปกรณ์ 1 เครื่อง และ medium.jpg จะตรงกับอุปกรณ์ 2 เครื่อง

ภาพนี้จะมีลักษณะเหมือนกันในบริบทการเรียกดูทั้งหมด กล่าวคือ ไฟล์ต้นฉบับทั้งหมดของเราจะแตกต่างจากขนาดอื่นๆ และแต่ละไฟล์จะแสดงผลได้คมชัดเท่าที่ความหนาแน่นในการแสดงผลของผู้ใช้จะสามารถแสดง อย่างไรก็ตาม แทนที่จะแสดง large.jpg แก่ผู้ใช้ทุกคนเพื่อรองรับวิวพอร์ตขนาดใหญ่ที่สุดและจอแสดงผลที่มีความหนาแน่นสูงสุด ผู้ใช้จะเห็นตัวเลือกขนาดเล็กที่สุดที่เหมาะสมเสมอ การใช้ไวยากรณ์ที่สื่อความหมายแทนการใช้ไวยากรณ์ที่กำหนดไว้ คุณไม่จำเป็นต้องตั้งค่าเบรกพอยท์และพิจารณาวิวพอร์ตและ DPR ในอนาคต คุณเพียงแค่ให้ข้อมูลแก่เบราว์เซอร์และอนุญาตให้เบราว์เซอร์พิจารณาคำตอบสำหรับคุณ

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

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

<img
    sizes="calc(100vw-2em)"
    srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w, x-large.jpg 2400w"
    src="fallback.jpg"
    alt="...">

อธิบายเบรกพอยท์

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

สมมติว่าคุณมีรูปภาพที่ตั้งใจจะใช้ 80% ของวิวพอร์ต ลบด้วยระยะห่างจากขอบ em 1 ด้านทั้งสองด้าน ในวิวพอร์ตที่สูงกว่า 1,200 พิกเซล ในวิวพอร์ตขนาดเล็ก รูปภาพนั้นจะใช้เต็มความกว้างของวิวพอร์ต

  <img
     sizes="(min-width: 1200px) calc(80vw - 2em), 100vw"
     srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     src="fallback.jpg"
     alt="...">

หากวิวพอร์ตของผู้ใช้มีขนาดใหญ่กว่า 1, 200 พิกเซล calc(80vw - 2em) จะอธิบายความกว้างของรูปภาพในเลย์เอาต์ของเรา หากเงื่อนไข (min-width: 1200px) ไม่ตรงกัน เบราว์เซอร์จะย้ายไปที่ค่าถัดไป เนื่องจากไม่มีเงื่อนไขสื่อที่เฉพาะเจาะจงซึ่งเชื่อมโยงกับค่านี้ เราจึงใช้ 100vw เป็นค่าเริ่มต้น หากคุณเขียนแอตทริบิวต์ sizes นี้โดยใช้ max-widthคำค้นหาสื่อ

  <img
     sizes="(max-width: 1200px) 100vw, calc(80vw - 2em)"
     srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     src="fallback.jpg"
     alt="...">

ในภาษาง่ายๆ: "(max-width: 1200px) ตรงไหม หากไม่ใช่ ให้ดำเนินการต่อ ค่าถัดไป calc(80vw - 2em) ไม่มีเงื่อนไขที่มีคุณสมบัติ ค่านี้จึงเป็นค่าที่เลือก

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

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

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

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

กำลังใช้ sizes และ srcset

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

srcset คือกรอบการทำงานอัตโนมัติที่ล้ำสมัย การสร้างรูปภาพหลายเวอร์ชันด้วยมือของคุณเองสำหรับสภาพแวดล้อมของเวอร์ชันที่ใช้งานจริงนั้นแทบจะไม่เกิดขึ้นเลย โดยทำให้กระบวนการเป็นแบบอัตโนมัติโดยใช้ตัวเรียกใช้งานอย่าง Gulp, Bundler เช่น Webpack, CDN ของบุคคลที่สาม เช่น Cloudinary หรือฟังก์ชันการทำงานที่มีอยู่ใน CMS ที่คุณต้องการอยู่แล้ว เมื่อมีข้อมูลเพียงพอที่จะสร้างแหล่งที่มาตั้งแต่แรก ระบบจะมีข้อมูลเพียงพอที่จะเขียนลงในแอตทริบิวต์ srcset ที่ใช้งานได้

sizes จะทำงานอัตโนมัติได้ยากกว่าเล็กน้อย อย่างที่ได้ทราบดี วิธีเดียวที่ระบบจะคำนวณขนาดของรูปภาพในเลย์เอาต์ที่แสดงผลได้คือการแสดงผลเลย์เอาต์ โชคดีที่มีเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จำนวนหนึ่งได้ปรากฏขึ้นเพื่อขจัดกระบวนการเขียนแอตทริบิวต์ sizes ด้วยลายมือ ซึ่งมีประสิทธิภาพที่คุณไม่มีทางเทียบได้ด้วยตัวเอง ตัวอย่างเช่น respImageLint เป็นข้อมูลโค้ดที่มีไว้เพื่อตรวจสอบแอตทริบิวต์ sizes ในเรื่องความแม่นยำและให้คำแนะนำในการปรับปรุง โปรเจ็กต์ Lazysizes ลดความเร็วด้านประสิทธิภาพบางส่วนด้วยการเลื่อนคำขอรูปภาพไปจนกว่าจะสร้างเลย์เอาต์แล้ว ซึ่งจะช่วยให้ JavaScript สร้างค่า sizes ให้คุณได้ หากคุณใช้เฟรมเวิร์กการแสดงผลฝั่งไคลเอ็นต์อย่างเต็มรูปแบบ เช่น React หรือ Vue มีโซลูชันจำนวนหนึ่งสำหรับการเขียนและ/หรือสร้างแอตทริบิวต์ srcset และ sizes ซึ่งเราจะกล่าวถึงเพิ่มเติมใน CMS และเฟรมเวิร์ก