พร็อพเพอร์ตี้ CSS ที่ช่วยรักษาระยะห่างในเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์
สัดส่วนภาพ
โดยทั่วไปแล้ว สัดส่วนภาพจะแสดงเป็นจำนวนเต็ม 2 จำนวนและเครื่องหมายโคลอนในมิติข้อมูลของ ความกว้าง:ความสูง หรือ x:y สัดส่วนภาพที่พบบ่อยที่สุดสำหรับการถ่ายภาพคือ 4:3 และ 3:2 ส่วนวิดีโอ และกล้องสำหรับผู้บริโภคที่ใหม่กว่ามักจะมีสัดส่วนภาพ 16:9
เมื่อการออกแบบที่ปรับเปลี่ยนตามพื้นที่โฆษณาเข้ามามีบทบาท การรักษาสัดส่วนภาพจึงมีความสำคัญมากขึ้นสำหรับ นักพัฒนาเว็บ โดยเฉพาะอย่างยิ่งเมื่อขนาดรูปภาพแตกต่างกันและขนาดองค์ประกอบเปลี่ยนไปตามพื้นที่ ที่มี
ตัวอย่างบางส่วนที่การรักษาอัตราส่วนภาพมีความสำคัญมีดังนี้
- การสร้าง iframe ที่ปรับเปลี่ยนตามอุปกรณ์ ซึ่งมีความกว้าง 100% ขององค์ประกอบระดับบนสุด และความสูงควรคงอัตราส่วนวิวพอร์ตที่เฉพาะเจาะจงไว้
- สร้างคอนเทนเนอร์ตัวยึดตำแหน่งโดยธรรมชาติสำหรับรูปภาพ วิดีโอ และการฝัง เพื่อป้องกันการจัดวางใหม่เมื่อรายการโหลดและใช้พื้นที่
- สร้างพื้นที่ที่สอดคล้องกันและปรับเปลี่ยนตามพื้นที่โฆษณาสำหรับภาพข้อมูลแบบอินเทอร์แอกทีฟหรือภาพเคลื่อนไหว SVG
- การสร้างพื้นที่ที่สอดคล้องและตอบสนองสำหรับคอมโพเนนต์แบบหลายองค์ประกอบ เช่น การ์ดหรือวันที่ในปฏิทิน
- สร้างพื้นที่ที่สอดคล้องกันและปรับเปลี่ยนตามพื้นที่โฆษณาสำหรับรูปภาพหลายรูปที่มีขนาดแตกต่างกัน (ใช้ร่วมกับ
object-fitได้)
Object-fit
การกำหนดสัดส่วนภาพช่วยให้เราปรับขนาดสื่อในบริบทที่ตอบสนองได้ เครื่องมืออีกอย่างในกลุ่มนี้คือพร็อพเพอร์ตี้ object-fit ซึ่งช่วยให้ผู้ใช้สามารถอธิบายวิธีที่ออบเจ็กต์ (เช่น รูปภาพ) ภายในบล็อกควรเติมบล็อกนั้น
object-fit ต่างๆ ดูการสาธิตใน Codepenค่า initial และ fill จะปรับรูปภาพอีกครั้งให้เต็มพื้นที่ ในตัวอย่างของเรา การดำเนินการนี้จะทำให้
รูปภาพบีบและเบลอ เนื่องจากระบบจะปรับพิกเซลใหม่ ไม่เหมาะสม object-fit: cover ใช้
ขนาดที่เล็กที่สุดของรูปภาพเพื่อเติมพื้นที่และครอบตัดรูปภาพให้พอดีกับพื้นที่ตามขนาดนี้
โดยจะ "ซูมเข้า" ที่ขอบเขตล่างสุด object-fit: contain ช่วยให้มั่นใจว่ารูปภาพทั้งหมด
จะมองเห็นได้เสมอ ซึ่งตรงข้ามกับ cover ซึ่งจะใช้ขนาดของขอบเขตที่ใหญ่ที่สุด
(ในตัวอย่างด้านบนคือความกว้าง) และปรับขนาดรูปภาพเพื่อรักษาสัดส่วนการแสดงผลเดิม
ขณะที่พอดีกับพื้นที่ object-fit: none เคสแสดงรูปภาพที่ครอบตัดตรงกลาง
(ตำแหน่งออบเจ็กต์เริ่มต้น) ในขนาดจริง
object-fit: cover มักจะใช้ได้ในสถานการณ์ส่วนใหญ่เพื่อให้มั่นใจว่าอินเทอร์เฟซจะดูดีและสม่ำเสมอเมื่อต้องจัดการกับรูปภาพที่มีขนาดแตกต่างกัน แต่คุณจะสูญเสียข้อมูลไปในลักษณะนี้ (ระบบจะครอบตัดรูปภาพที่ขอบที่ยาวที่สุด)
หากรายละเอียดเหล่านี้มีความสำคัญ (เช่น เมื่อทำงานกับภาพถ่ายผลิตภัณฑ์ความงามแบบวางราบ) การครอบตัดเนื้อหาสำคัญจึงไม่เป็นที่ยอมรับ ดังนั้นสถานการณ์ที่เหมาะสมที่สุดคือรูปภาพที่ปรับเปลี่ยนตามพื้นที่โฆษณาซึ่งมีขนาดแตกต่างกันและพอดีกับพื้นที่ UI โดยไม่ต้องครอบตัด
เคล็ดลับเก่า: การรักษาสัดส่วนภาพด้วย padding-top
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
aspect-ratio เพื่อตั้งค่าสัดส่วนภาพ 1:1 ในรูปภาพตัวอย่างโพสต์ภายในภาพสไลด์อย่างไรก็ตาม การคำนวณค่า padding-top เหล่านี้ไม่ใช่เรื่องง่าย และต้องมีค่าใช้จ่ายเพิ่มเติมและการวางตำแหน่ง aspect-ratio พร็อพเพอร์ตี้ CSS แบบใหม่ช่วยให้ภาษาที่ใช้ในการรักษาอัตราส่วน
ภาพชัดเจนยิ่งขึ้น
มาร์กอัปเดียวกันนี้ช่วยให้เราแทนที่ 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;
}
ตัวอย่าง: การป้องกันไม่ให้เลย์เอาต์เปลี่ยนแปลง
อีกฟีเจอร์ที่ยอดเยี่ยมของ aspect-ratio คือการสร้างพื้นที่ตัวยึดตำแหน่งเพื่อป้องกันCumulative Layout Shift และมอบ Web Vitals ที่ดียิ่งขึ้น ในตัวอย่างแรกนี้
การโหลดชิ้นงานจาก API เช่น Unsplash จะทำให้เกิด
การเปลี่ยนเลย์เอาต์เมื่อโหลดสื่อเสร็จ
ในทางกลับกัน การใช้ aspect-ratio จะสร้างตัวยึดตำแหน่งเพื่อป้องกันการเปลี่ยนแปลงเลย์เอาต์นี้
img {
width: 100%;
aspect-ratio: 8 / 6;
}
เคล็ดลับเพิ่มเติม: แอตทริบิวต์รูปภาพสำหรับสัดส่วนภาพ
อีกวิธีในการตั้งค่าสัดส่วนภาพของรูปภาพคือผ่านแอตทริบิวต์รูปภาพ หากทราบขนาดของรูปภาพล่วงหน้า แนวทางปฏิบัติแนะนำคือการตั้งค่าขนาดเหล่านี้เป็น 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%;
height: auto;
}
ท้ายที่สุดแล้ว ผลลัพธ์จะเหมือนกับการตั้งค่า aspect-ratio ในรูปภาพผ่าน CSS และหลีกเลี่ยงการเปลี่ยนแปลงเลย์เอาต์แบบสะสม (ดูการสาธิตใน
Codepen)
บทสรุป
aspect-ratioพร็อพเพอร์ตี้ CSS ใหม่นี้เปิดตัวในเบราว์เซอร์สมัยใหม่หลายเบราว์เซอร์ การรักษาสัดส่วนภาพที่เหมาะสมในคอนเทนเนอร์สื่อและเลย์เอาต์จึงง่ายขึ้นเล็กน้อย
รูปภาพโดย Amy Shamblen และ Lionel Gustave ผ่าน Unsplash