SVG preserveAspectRatio: จัดภาพให้พอดีโดยไม่ยืดผิดสัดส่วน
เลือก meet, slice หรือ none เพื่อจัด SVG ให้พอดี ทดสอบการจัดแนว การตัดภาพ และพื้นที่ว่างด้วยตราสัญลักษณ์เดียว พร้อมแยกการแมป SVG ออกจาก CSS object-fit
ในหน้านี้
ใช้ preserveAspectRatio="xMidYMid meet" เมื่อต้องการให้ viewBox ของ SVG ทั้งหมดพอดีกับพื้นที่แสดงผลโดยไม่ยืดผิดสัดส่วน ใช้ slice เมื่อต้องการให้ภาพครอบคลุมพื้นที่นั้นและยอมให้บางส่วนเลยขอบออกไป ใช้ none เฉพาะเมื่อตั้งใจให้มาตราส่วนแนวนอนและแนวตั้งต่างกัน
สิ่งสำคัญคือต้องแยกสี่เหลี่ยมพิกัดของงานภาพที่กำหนดด้วย viewBox ออกจากวิวพอร์ตที่ใช้แสดงภาพ การจัดให้พอดีเปลี่ยนวิธีแมปพื้นที่หนึ่งไปยังอีกพื้นที่หนึ่ง ไม่ได้วาดโลโก้ใหม่ ลบพื้นที่ว่างในต้นฉบับ หรือลบพาธส่วนที่ถูกตัดออกอย่างถาวร
เลือกพฤติกรรมการจัดให้พอดีก่อน
| เป้าหมาย | ค่าแอตทริบิวต์ | สิ่งที่ต้องยอมรับเมื่ออัตราส่วนต่างกัน |
|---|---|---|
| แสดง viewBox ทั้งหมด | xMidYMid meet | มีพื้นที่ไม่ได้ใช้เหลืออยู่ตามแกนหนึ่ง |
| ครอบคลุมวิวพอร์ต | xMidYMid slice | บางส่วนของ viewBox เลยออกนอกวิวพอร์ต |
| เติมเต็มด้วยมาตราส่วนแต่ละแกนที่เป็นอิสระ | none | วงกลมและสัดส่วนอื่น ๆ อาจบิดเบี้ยว |
เอกสารอ้างอิง preserveAspectRatio ของ MDN อธิบายค่าเหล่านี้และค่าปริยาย xMidYMid meet สำหรับองค์ประกอบ svg การแมปนี้ต้องมี viewBox แอตทริบิวต์นี้แยกตัวพิมพ์ใหญ่และเล็ก: ต้องคง A และ R เป็นตัวพิมพ์ใหญ่
สำหรับโลโก้ ให้เริ่มด้วย meet การทำตัวอักษรหายไปหนึ่งตัวหรือเปลี่ยนวงกลมให้เป็นวงรีมักให้ผลแย่กว่าการเว้นพื้นที่ไว้บ้าง สำหรับพื้นหลังตกแต่ง การตัดภาพอย่างตั้งใจอาจยอมรับได้ ตัดสินใจเรื่องนี้ก่อนเลือกการจัดแนว

ทดสอบตราสัญลักษณ์เดียวในวิวพอร์ตสองรูปทรง
ตัวอย่างที่เราสร้างนี้ใช้วงกลม สี่เหลี่ยมผืนผ้า และสามเหลี่ยมที่เยื้องจากกึ่งกลาง วงกลมทำให้มองเห็นการยืดผิดสัดส่วน ส่วนองค์ประกอบที่ไม่สมมาตรทำให้สังเกตการเปลี่ยนการจัดแนวได้ง่ายกว่าตราสัญลักษณ์ที่สมมาตร
วางโค้ดนี้ในไฟล์ HTML แล้วเปิดในเบราว์เซอร์:
<svg width="300" height="100" viewBox="0 0 200 100"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
role="img" aria-label="Circle, rectangle, and triangle emblem"
style="background:#f4ead4; overflow:hidden">
<circle cx="40" cy="50" r="25" fill="#147d78" />
<path d="M85 20 H130 V80 H85Z" fill="#e5a340" />
<path d="M145 70 L170 25 L190 70Z" fill="#183549" />
</svg>viewBox กว้าง 200 หน่วยและสูง 100 หน่วย มีอัตราส่วน 2:1 วิวพอร์ตแรกมีขนาด 300 คูณ 100 พิกเซล CSS หรืออัตราส่วน 3:1 เปลี่ยนเฉพาะแอตทริบิวต์เพื่อเปรียบเทียบ xMidYMid slice และ none จากนั้นเปลี่ยนวิวพอร์ตเป็น width="100" height="300" แล้วทดสอบซ้ำ
เราเรนเดอร์รูปทรงนี้ใน Chrome ด้วยชุดทดสอบขนาดเล็กที่เลือกองค์ประกอบผ่านตัวเลือก ค่าที่อ่านใช้เมทริกซ์การแปลงปัจจุบันของกลุ่มงานภาพ มาตราส่วนและระยะเลื่อนที่ได้ตรงกับค่าต่อไปนี้ โดยระยะเลื่อนของ slice ประมาณ −25 พิกเซลแสดงเป็นค่าปัดเศษในตาราง
| วิวพอร์ต | การตั้งค่า | มาตราส่วนแนวนอน / แนวตั้ง | ระยะเลื่อนเพื่อจัดกึ่งกลางในหน่วยพิกเซลวิวพอร์ต |
|---|---|---|---|
| 300 × 100 | meet | 1 / 1 | แนวนอน 50 แนวตั้ง 0 |
| 300 × 100 | slice | 1.5 / 1.5 | แนวนอน 0 แนวตั้ง −25 |
| 300 × 100 | none | 1.5 / 1 | 0 / 0 |
| 100 × 300 | meet | 0.5 / 0.5 | แนวนอน 0 แนวตั้ง 125 |
| 100 × 300 | slice | 3 / 3 | แนวนอน −250 แนวตั้ง 0 |
| 100 × 300 | none | 0.5 / 3 | 0 / 0 |
ในวิวพอร์ตแนวสูง meet แสดงรูปทรงเล็กทั้งสามครบ ส่วน slice ที่จัดกึ่งกลางแสดงเพียงบางส่วนขององค์ประกอบภาพที่ขยาย โดยสี่เหลี่ยมสีทองเป็นส่วนหลักที่เห็น none ทำให้วงกลมแคบและสูงขึ้น นี่เป็นการตรวจตัวอย่างนี้ใน Chrome ไม่ใช่คำรับประกันพฤติกรรมนำเข้าของโปรแกรมกราฟิกทุกตัว
กฎมาตราส่วนของตัวอย่างที่จุดกำเนิดเป็นศูนย์นี้ตรงไปตรงมา หารความกว้างวิวพอร์ตด้วยความกว้าง viewBox แล้วหารความสูงวิวพอร์ตด้วยความสูง viewBox meet ใช้อัตราส่วนที่เล็กกว่ากับทั้งสองแกน ส่วน slice ใช้อัตราส่วนที่ใหญ่กว่า none เก็บอัตราส่วนทั้งสองแยกกัน ข้อกำหนดระบบพิกัด SVG นิยามการแมปนี้ รวมทั้งการจัดแนวและจุดกำเนิด viewBox ที่ไม่ใช่ศูนย์
ใช้การจัดแนวเพื่อเลือกตำแหน่งของพื้นที่ที่เหลือ
คีย์เวิร์ดแรกควบคุมการจัดแนว xMin, xMid และ xMax จัดตามขอบซ้าย กึ่งกลางแนวนอน หรือขอบขวาของ viewBox ส่วน YMin, YMid และ YMax ทำหน้าที่แบบเดียวกันในแนวตั้ง ค่าเหล่านี้อ้างอิงสี่เหลี่ยม viewBox ซึ่งอาจมีพื้นที่ว่างรอบพาธจริงอยู่ภายใน
สำหรับวิวพอร์ตแนวสูงที่ใช้ทดสอบ:
xMinYMin meetวาง viewBox ที่ปรับให้พอดีไว้ด้านบนแทนการจัดกึ่งกลางในแนวตั้งxMinYMin sliceจัดด้านซ้ายของ viewBox ให้ตรงกับด้านซ้ายของวิวพอร์ต ด้านขวาที่ขยายจะเลยออกนอกวิวพอร์ตxMidYMid sliceกระจายส่วนที่ล้นในแนวนอนไปทั้งสองด้าน
เราเปลี่ยนชุดทดสอบจากการจัดกึ่งกลางเป็น xMinYMin ระยะเลื่อนของทั้ง meet และ slice กลายเป็นศูนย์ ขณะที่ตัวคูณมาตราส่วนยังคงเป็น 0.5 และ 3 ตามลำดับ การจัดแนวเลื่อนองค์ประกอบภาพ แต่ไม่ได้เปลี่ยนมาตราส่วนที่ใช้จัดให้พอดี
การเปลี่ยนการจัดแนวจะเห็นผลเฉพาะแกนที่มีพื้นที่เหลือหรือมีส่วนล้น ในกรณี meet แบบกว้าง viewBox เติมเต็มความสูงอยู่แล้ว ดังนั้นการเปลี่ยน YMid เป็น YMin จึงไม่มีพื้นที่แนวตั้งให้เลื่อน
กำหนดการตัดภาพอย่างชัดเจน
slice เลือกมาตราส่วน ส่วนการตัดภาพกำหนดว่าคุณจะเห็นส่วนที่เลยออกนอกวิวพอร์ตหรือไม่ ตัวอย่างกำหนด overflow:hidden ไว้อย่างชัดเจนเพื่อให้การตัดภาพคาดการณ์ได้
ในชุดทดสอบแนวสูง การเปลี่ยน overflow ให้มองเห็นได้เผยวงกลมและสามเหลี่ยมที่ขยายซึ่งอยู่เลยวิวพอร์ต slice ออกไป รูปทรงไม่ได้หายไป เอกสารอ้างอิง overflow ของ SVG จาก MDN อธิบายความสัมพันธ์ระหว่าง overflow กับการตัดตามวิวพอร์ต รวมทั้งความต่างของสไตล์ปริยายในบริบท SVG แต่ละแบบ
อย่าถือว่า slice เป็นการตัดแต่งพาธ หากไฟล์ส่งมอบต้องมีเฉพาะรูปทรงส่วนที่เก็บไว้ ให้แก้ไขจริงและตรวจสอบผล สำหรับช่องแสดงผลรูปทรงเฉพาะที่ไม่ใช่สี่เหลี่ยม clipPath อาจเป็นเครื่องมือที่เหมาะสมกว่า
เช่นเดียวกัน meet รับประกันว่า viewBox จะพอดี แต่ไม่ได้รับประกันว่าเนื้อหาที่วาดทั้งหมดจะพอดี เส้นขอบ ฟิลเตอร์ หรือพาธที่อยู่นอกสี่เหลี่ยมต้นทางนั้นยังอาจเลยออกไปได้ ตรวจขอบที่มองเห็นแทนการเชื่อแอตทริบิวต์เพียงอย่างเดียว
แก้พื้นที่ว่างในต้นฉบับก่อนพยายามปรับการจัดแนว
สมมติว่าเครื่องหมายขนาดเล็กอยู่เฉพาะกลาง viewBox ที่ใหญ่มาก meet จะจัดสี่เหลี่ยมพิกัดทั้งหมดนั้นให้พอดี รวมทั้งขอบว่างด้วย ผลลัพธ์จึงอาจดูเล็กเกินไปแม้มาตราส่วนจะถูกต้อง
ตรวจผืนภาพหรืออาร์ตบอร์ดที่ส่งออกในโปรแกรมแก้ไข หากเปลี่ยน viewBox ให้กระชับกับองค์ประกอบภาพ อย่าลืมรวมเส้นขอบและเอฟเฟกต์ที่ต้องการไว้ แล้วตรวจการวางภาพแต่ละตำแหน่งอีกครั้ง อย่าลบขอบว่างทั้งหมดโดยอัตโนมัติ: ต้นฉบับอาจตั้งใจเว้นพื้นที่โล่งรอบเครื่องหมายแบรนด์
ปัญหาขนาดทางกายภาพเป็นอีกเรื่องหนึ่ง SVG ที่นำเข้าแล้วมีขนาดมิลลิเมตรผิดต้องใช้ กระบวนการตรวจขนาด SVG การเปลี่ยนการจัดแนวให้พอดีไม่น่าจะแก้สมมติฐานเรื่องหน่วยได้
แยกการจัด SVG แบบอินไลน์ออกจากการจัดรูปภาพให้พอดี
สำหรับ SVG แบบอินไลน์ ให้เปลี่ยนแอตทริบิวต์บนองค์ประกอบ svg ที่เกี่ยวข้อง CSS สามารถกำหนดขนาดกล่องขององค์ประกอบนั้น ขณะที่ preserveAspectRatio แมป viewBox ลงในกล่อง
สำหรับ SVG ภายนอกที่ใช้ในองค์ประกอบรูปภาพ HTML นั้น CSS ควบคุมการจัดภาพที่มาแทนเนื้อหาให้พอดี:
<img class="brand-mark" src="emblem.svg" alt="Brand emblem">
<style>
.brand-mark {
width: 300px;
height: 100px;
object-fit: contain;
object-position: center;
}
</style>เอกสาร object-fit ของ MDN อธิบายการจัดเนื้อหาที่มาแทนองค์ประกอบให้พอดีกับกล่อง CSS ซึ่งเป็นคนละชั้นกับการแก้การแมปภายในเอกสาร SVG object-fit: contain ไม่สามารถลบพื้นที่ว่างที่มีอยู่แล้วในต้นฉบับได้เช่นกัน ดู SVG แบบอินไลน์เทียบกับองค์ประกอบรูปภาพ เมื่อเลือกวิธีฝังภาพ
นอกจากนี้ยังมีองค์ประกอบ SVG image ซึ่งสะกดเป็นคำเต็ม ต่างจาก img ของ HTML ค่า preserveAspectRatio ของมันควบคุมว่ารูปภาพที่อ้างอิงจะพอดีกับสี่เหลี่ยมที่กำหนดให้องค์ประกอบนั้นอย่างไร นี่เป็นข้อยกเว้นของข้อกำหนดทั่วไปที่ต้องมี viewBox บนองค์ประกอบเดียวกัน ตามคำอธิบายในเอกสารอ้างอิงแอตทริบิวต์ของ MDN การแยกทั้งสามกรณีนี้ช่วยเลี่ยงการพยายามแก้ภาพ HTML โดยเพิ่มแอตทริบิวต์ที่ใช้ได้เฉพาะ SVG ลงไป
รักษาสัดส่วนต้นฉบับก่อนจัดวาง
หากคุณมีเพียง PNG หรือ JPG ของเครื่องหมายที่ออกแบบเองและต้องการรูปทรงเวกเตอร์ที่แก้ไขได้ PerfectVector สามารถกู้คืนต้นฉบับ SVG ก่อนสร้างเลย์เอาต์ได้ ตรวจเส้นรอบรูป ช่องเปิดเล็ก ๆ และขอบเขตผืนภาพก่อน การจัดผลลัพธ์ให้พอดีจะรักษารูปทรงปัจจุบันของมัน แต่ไม่สามารถซ่อมต้นฉบับที่ผิดสัดส่วนหรือสร้างรายละเอียดที่ไม่ได้กู้คืนมา
SVG ที่สะอาดอยู่แล้วสามารถเข้าสู่การตรวจการจัดให้พอดีได้โดยตรง สำหรับตราสัญลักษณ์เรียบง่ายด้านบน รูปทรงที่เขียนเองก็เพียงพอแล้ว ภาพรวมการแปลงภาพเป็นเวกเตอร์ อธิบายว่าเมื่อใดการกู้คืนพาธจากภาพราสเตอร์จึงมีประโยชน์
สำหรับเครื่องหมายที่มีเพียงราสเตอร์ ให้ ลองต้นฉบับของคุณใน PerfectVector ตรวจ SVG แล้วเปรียบเทียบการวางในพื้นที่กว้างและพื้นที่สูงด้วย meet ก่อนพิจารณาตัดภาพ เก็บไฟล์หลักเวกเตอร์ต้นฉบับไว้เพื่อให้ย้อนกลับจากการตัดสินใจด้านเลย์เอาต์ได้
คำถามที่พบบ่อย
ทำไม SVG ยังมีพื้นที่ว่างเมื่อใช้ meet? วิวพอร์ตและ viewBox อาจมีอัตราส่วนต่างกัน จึงเหลือพื้นที่หลังปรับมาตราส่วนเท่ากันทั้งสองแกน viewBox ต้นฉบับอาจมีขอบว่างรอบพาธด้วย การจัดแนวเลื่อนสี่เหลี่ยมนั้น แต่ไม่ได้ลบพื้นที่ว่างภายใน
slice ตัดงานภาพออกอย่างถาวรหรือไม่? ไม่ มันเปลี่ยนมาตราส่วนที่ใช้ครอบคลุมวิวพอร์ต Overflow และการตัดภาพควบคุมว่าส่วนใดมองเห็นได้ รูปทรงพาธต้นฉบับยังอยู่ในเอกสารจนกว่าคุณจะแก้ไขแยกต่างหาก
ทำไม none เปลี่ยนวงกลมเป็นวงรี? มันอนุญาตให้ตัวคูณมาตราส่วนแนวนอนและแนวตั้งต่างกัน เมื่ออัตราส่วนวิวพอร์ตกับ viewBox ต่างกัน วงกลมอาจกลายเป็นวงรี ใช้ meet หรือ slice พร้อมคีย์เวิร์ดจัดแนวเพื่อรักษามาตราส่วนให้เท่ากัน
แหล่งอ้างอิง
- MDN preserveAspectRatio — นิยามค่าการจัดให้พอดี การจัดแนว ค่าปริยาย และข้อยกเว้นของ SVG image
- ข้อกำหนดระบบพิกัด SVG — นิยามการคำนวณมาตราส่วนและระยะเลื่อนสำหรับวิวพอร์ต
- MDN SVG overflow — อธิบายว่า overflow ควบคุมการตัดตามวิวพอร์ตอย่างไร
- MDN object-fit — อธิบายการจัดเนื้อหาภาพที่มาแทนองค์ประกอบให้พอดีในกล่อง CSS
เพิ่มเติมจากบล็อก

ภาพ SVG ใน Graphviz: ย้ายภาพในโหนดได้ครบ
เพิ่มภาพ SVG ในโหนด Graphviz ตรวจการอ้างอิงภาพ และทดสอบชุดแอสเซ็ตครบถ้วนเทียบกับแผนภาพที่ย้ายเดี่ยวและสำเนาส่งมอบที่มีข้อมูลครบในตัว

ภาพ SVG ใน WeasyPrint: แก้โลโก้หายใน PDF
แก้โลโก้ SVG ที่หายใน PDF จาก WeasyPrint ด้วย base URL ที่ถูกต้องและขนาด CSS ที่ชัดเจน แล้วตรวจพาธเวกเตอร์ สัดส่วน และภาพใน PDF ที่บันทึก