คุณสมบัติ CSS สัดส่วนภาพใหม่ที่รองรับใน Chromium, Safari Technology Preview และ Firefox Nightly

พร็อพเพอร์ตี้ CSS ใหม่ที่ช่วยรักษาระยะห่างในเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์

สัดส่วนภาพ

การสนับสนุนเบราว์เซอร์

  • 88
  • 88
  • 89
  • 15

แหล่งที่มา

สัดส่วนภาพส่วนใหญ่แสดงเป็นจำนวนเต็ม 2 ตัวและโคลอนในขนาด width:height หรือ x:y สัดส่วนภาพที่ใช้กันมากที่สุดสำหรับการถ่ายภาพคือ 4:3 และ 3:2 ในขณะที่วิดีโอ และกล้องสำหรับผู้บริโภครุ่นล่าสุด มีแนวโน้มที่จะมีสัดส่วนภาพ 16:9

รูปภาพ 2 รูปที่มีอัตราส่วนเท่ากัน ไฟล์ขนาดหนึ่งมีขนาด 634 x 951 พิกเซล ส่วนอีกไฟล์มีขนาด 200 x 300 พิกเซล ทั้ง 2 ภาพมีสัดส่วนภาพ 2:3
รูปภาพ 2 รูปที่มีสัดส่วนภาพเท่ากัน ไฟล์ขนาดหนึ่งมีขนาด 634 x 951 พิกเซล ส่วนอีกไฟล์มีขนาด 200 x 300 พิกเซล โดยทั้ง 2 อย่างมีสัดส่วนภาพ 2:3

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

ตัวอย่างบางส่วนของการรักษาอัตราส่วนเป็นสิ่งสำคัญมีดังนี้

  • การสร้าง iframe ที่ปรับเปลี่ยนตามพื้นที่โฆษณาซึ่งมีความกว้างเท่ากับ 100% ของผู้เผยแพร่โฆษณาหลัก และความสูงควรเป็นอัตราส่วนของวิวพอร์ตที่เจาะจง
  • การสร้างคอนเทนเนอร์ตัวยึดตำแหน่งภายในสำหรับรูปภาพ วิดีโอ และการฝังเพื่อป้องกันไม่ให้มีการจัดเรียงซ้ำเมื่อรายการโหลดและกินพื้นที่
  • การสร้างพื้นที่แบบเดียวกันที่ตอบสนองตามอุปกรณ์สำหรับการแสดงภาพข้อมูลแบบอินเทอร์แอกทีฟหรือภาพเคลื่อนไหว SVG
  • การสร้างพื้นที่ที่ปรับเปลี่ยนตามอุปกรณ์ให้เป็นแบบเดียวกันสำหรับองค์ประกอบหลายองค์ประกอบ เช่น การ์ดหรือวันที่ในปฏิทิน
  • การสร้างพื้นที่ที่ปรับเปลี่ยนตามอุปกรณ์ให้เป็นแบบเดียวกันสำหรับรูปภาพหลายรูปที่มีขนาดแตกต่างกัน (ใช้ควบคู่กับ object-fit ได้)

ความเหมาะสมกับวัตถุ

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

การแสดงภาพเดโมที่เหมาะกับวัตถุ
การแสดงค่า object-fit ต่างๆ ดูการสาธิตเกี่ยวกับ Codepen

ค่า initial และ fill จะปรับรูปภาพใหม่ให้เต็มพื้นที่ ในตัวอย่างของเรา ปัญหานี้ทำให้รูปภาพถูกบีบหรือเบลอเนื่องจากมีการปรับพิกเซลใหม่ ไม่ค่อยดี object-fit: cover ใช้ขนาดที่เล็กที่สุดของรูปภาพเพื่อเติมเต็มพื้นที่และครอบตัดรูปภาพให้พอดีโดยอิงตามขนาดนี้ โดย "ซูมเข้า" ที่ขอบเขตต่ำสุด object-fit: contain ช่วยให้มองเห็นรูปภาพทั้งรูปได้ตลอดเวลา และตรงข้ามกับ cover ซึ่งใช้ขนาดของขอบเขตที่ใหญ่ที่สุด (ในตัวอย่างด้านบนคือความกว้าง) และปรับขนาดรูปภาพเพื่อคงสัดส่วนภาพดั้งเดิมไว้ขณะปรับให้พอดีกับพื้นที่ เคส object-fit: none แสดงรูปภาพที่ครอบตัดไว้ตรงกลาง (ตำแหน่งวัตถุเริ่มต้น) ในขนาดที่เป็นธรรมชาติ

object-fit: cover มักจะทำงานได้ในทุกสถานการณ์เพื่อดูแลให้อินเทอร์เฟซเป็นแบบเดียวกันเมื่อทำงานกับรูปภาพขนาดแตกต่างกัน แต่คุณจะสูญเสียข้อมูลด้วยวิธีนี้ (รูปภาพจะถูกครอบตัดตามขอบที่ยาวที่สุด)

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

เคล็ดลับแบบเดิม: การคงสัดส่วนภาพด้วย padding-top

ใช้ระยะห่างจากขอบด้านบนเพื่อตั้งค่าสัดส่วนภาพ 1:1 ในรูปภาพตัวอย่างโพสต์ภายในภาพสไลด์
การใช้ padding-top เพื่อตั้งค่าสัดส่วนภาพ 1:1 ในรูปภาพตัวอย่างโพสต์ภายในภาพสไลด์

เราจะใช้สัดส่วนภาพเพื่อทำให้ภาพเหล่านี้ตอบสนองมากขึ้นได้ ซึ่งจะช่วยให้เรากำหนดขนาดอัตราส่วนที่เจาะจงและฐานส่วนที่เหลือของสื่อบนแต่ละแกน (ความสูงหรือความกว้าง) ได้

โซลูชันข้ามเบราว์เซอร์ที่ได้รับการยอมรับในปัจจุบันสำหรับการรักษาสัดส่วนภาพตามความกว้างของรูปภาพเรียกว่า "Padding-Top Hack" โซลูชันนี้ต้องใช้คอนเทนเนอร์ระดับบนสุดและคอนเทนเนอร์ย่อยที่วางไว้แบบสัมบูรณ์ จากนั้นรายหนึ่งจะคำนวณสัดส่วนภาพเป็นเปอร์เซ็นต์เพื่อตั้งค่าเป็น padding-top เช่น

  • สัดส่วนภาพ 1:1 = 1 / 1 = 1 = padding-top: 100%
  • สัดส่วนภาพ 4:3 = 3 / 4 = 0.75 = padding-top: 75%
  • สัดส่วนภาพ 3:2 = 2 / 3 = 0.66666 = padding-top: 66.67%
  • สัดส่วนภาพ 16:9 = 9 / 16 = 0.5625 = padding-top: 56.25%

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

<div class="container">
  <img class="media" src="..." alt="...">
</div>

จากนั้นเราก็สามารถเขียน CSS ต่อไปนี้

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

กำลังรักษาสัดส่วนภาพด้วย aspect-ratio

ใช้สัดส่วนภาพเพื่อตั้งค่าสัดส่วนภาพ 1:1 ในรูปภาพตัวอย่างโพสต์ภายในภาพสไลด์
การใช้ aspect-ratio เพื่อตั้งค่าสัดส่วนภาพ 1:1 ในรูปภาพตัวอย่างโพสต์ภายในภาพสไลด์

แต่น่าเสียดายที่การคำนวณค่า padding-top เหล่านี้ไม่ใช่เรื่องง่ายนัก และต้องใช้เวลาดำเนินการเพิ่มเติมและกำหนดตำแหน่งเพิ่มเติม พร็อพเพอร์ตี้ CSS ภายในของ aspect-ratio ใหม่ช่วยให้รักษาสัดส่วนภาพไว้ชัดเจนขึ้นมาก

ด้วยมาร์กอัปเดียวกัน เราสามารถแทนที่ padding-top: 56.25% ด้วย aspect-ratio: 16 / 9 โดยตั้งค่า aspect-ratio เป็นอัตราส่วนที่ระบุเป็น width / height

การใช้ระยะห่างจากขอบบน
.container {
  width: 100%;
  padding-top: 56.25%;
}
การใช้สัดส่วนภาพ
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

การใช้ aspect-ratio แทน padding-top จะชัดเจนกว่ามาก และไม่ได้ปรับปรุงพร็อพเพอร์ตี้ระยะห่างจากขอบเพื่อทําบางสิ่งที่อยู่นอกขอบเขตปกติ

พร็อพเพอร์ตี้ใหม่นี้ยังเพิ่มความสามารถในการตั้งค่าสัดส่วนภาพเป็น auto อีกด้วย โดยที่ "องค์ประกอบที่แทนที่ด้วยสัดส่วนภาพภายในจะใช้สัดส่วนภาพนั้น หากมิเช่นนั้น ช่องดังกล่าวจะไม่มีสัดส่วนภาพที่ต้องการ" หากระบุทั้ง auto และ <ratio> ร่วมกัน สัดส่วนภาพที่ต้องการจะเป็นอัตราส่วนที่ระบุคือ width หารด้วย height เว้นแต่จะเป็นองค์ประกอบที่แทนที่ด้วยสัดส่วนภาพภายใน ซึ่งในกรณีนี้ระบบจะใช้สัดส่วนภาพแทน

ตัวอย่าง: ความสอดคล้องกันในตารางกริด

วิธีนี้ใช้ได้ผลดีกับกลไกเลย์เอาต์ของ CSS เช่น CSS Grid และ Flexbox ด้วยเช่นกัน ลองพิจารณารายการซึ่งมีเด็กที่ต้องการรักษาอัตราส่วน 1:1 ไว้ เช่น ตารางไอคอนผู้สนับสนุน

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
รูปภาพในตารางกริดที่มีองค์ประกอบระดับบนสุดตามสัดส่วนภาพขนาดต่างๆ ดูเดโมใน Codepen

ตัวอย่าง: การป้องกันการเปลี่ยนเลย์เอาต์

ฟีเจอร์ที่ยอดเยี่ยมอีกอย่างของ aspect-ratio คือสามารถสร้างพื้นที่ตัวยึดตำแหน่งเพื่อป้องกัน Cumulative Layout Shift และแสดง Web Vitals ที่ดียิ่งขึ้น ในตัวอย่างแรกนี้ การโหลดเนื้อหาจาก API เช่น Unsplash จะสร้างการเปลี่ยนเลย์เอาต์เมื่อโหลดสื่อเสร็จแล้ว

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

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

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
วิดีโอที่มีการตั้งค่าสัดส่วนภาพที่ตั้งไว้ในเนื้อหาที่โหลด วิดีโอนี้บันทึกด้วยเครือข่าย 3G จำลอง ดูเดโมใน Codepen

เคล็ดลับพิเศษ: ลักษณะของรูปภาพสำหรับสัดส่วนภาพ

อีกวิธีหนึ่งในการตั้งค่าสัดส่วนภาพของรูปภาพคือการใช้แอตทริบิวต์รูปภาพ หากคุณทราบขนาดของรูปภาพไว้ล่วงหน้า แนวทางปฏิบัติแนะนำคือการตั้งค่าขนาดเหล่านี้เป็น width และ height

จากตัวอย่างข้างต้น เมื่อทราบว่าขนาดคือ 800 x 600 พิกเซล มาร์กอัปรูปภาพจะมีลักษณะดังนี้ <img src="image.jpg" alt="..." width="800" height="600"> หากรูปภาพที่ส่งมีสัดส่วนภาพเท่ากัน แต่ไม่จำเป็นต้องมีค่าพิกเซลที่แน่นอน เรายังสามารถใช้ค่าแอตทริบิวต์รูปภาพเพื่อตั้งค่าอัตราส่วน รวมกับสไตล์ width: 100% เพื่อให้รูปภาพใช้พื้นที่ที่เหมาะสมได้ เมื่อรวมกันแล้วจะมีลักษณะดังนี้

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
}

ในท้ายที่สุด เอฟเฟกต์จะเหมือนกับการตั้งค่า aspect-ratio ในรูปภาพผ่าน CSS และหลีกเลี่ยงการเปลี่ยนเลย์เอาต์แบบสะสม (ดูการสาธิตบน Codepen)

บทสรุป

พร็อพเพอร์ตี้ aspect-ratio แบบใหม่ของ CSS เปิดตัวในเบราว์เซอร์ที่ทันสมัยหลายเบราว์เซอร์ การรักษาอัตราส่วนที่เหมาะสมในคอนเทนเนอร์สื่อและคอนเทนเนอร์เลย์เอาต์จะง่ายขึ้นเล็กน้อย

รูปภาพโดย Amy Shamblen และ Lionel Gustave จาก Unsplash