จะทำให้องค์ประกอบ <svg> ขยายหรือทำสัญญากับคอนเทนเนอร์หลักได้อย่างไร


112

เป้าหมายคือให้<svg>องค์ประกอบขยายถึงขนาดของคอนเทนเนอร์ระดับบนสุดในกรณีนี้<div>คือไม่ว่าคอนเทนเนอร์นั้นจะใหญ่หรือเล็กเพียงใด

รหัส:

<style>
    svg, #container{
        height: 100%;
        width: 100%;
    }
</style>

<div id="container">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
         <rect x="0" y="0" width="100" height="100" />
    </svg>
</div>

วิธีแก้ปัญหาที่พบบ่อยที่สุดสำหรับปัญหานี้คือการตั้งค่าviewBoxแอตทริบิวต์ใน<svg>องค์ประกอบ

viewBox="0 0 widthOfContainer heightOfContainer"

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

ดังนั้นวิธีแก้ปัญหาที่ชัดเจนคือการใช้% widths และ% height กับองค์ประกอบเหล่านั้นด้วย แต่สิ่งนี้ต้องทำหรือไม่? โดยเฉพาะอย่างยิ่งเนื่องจาก<img src=test.svg >ทำงานได้ดีและขยาย / สัญญาโดยไม่มีปัญหาใด ๆ กับ<rect>ความสูงและความกว้างที่ตั้งไว้อย่างชัดเจน

หากองค์ประกอบเช่น<rect>และองค์ประกอบอื่น ๆ เช่นนั้นจะต้องมีความกว้างและความสูงกำหนดไว้เป็นเปอร์เซ็นต์มีวิธีใดบ้างใน Inkscape ในการตั้งค่าเพื่อให้องค์ประกอบทั้งหมดใน<svg>เอกสารใช้ความกว้างเปอร์เซ็นต์ความสูง ฯลฯ แทนขนาดคงที่ เหรอ?


1
บันทึก svg เป็นไฟล์แทนที่จะอ้างอิงเป็นรูปภาพเช่น <img src = "file.svg" /> และด้วยวิธีนี้คุณสามารถใช้ width: 100% หรือ height: 100%
Burimi

คำตอบ:


56

viewBoxไม่ได้เป็นความสูงของภาชนะที่เป็นขนาดของการวาดภาพของคุณ กำหนดviewBoxความกว้างของคุณเป็น 100 หน่วยจากนั้นกำหนดrectเป็น 10 หน่วย หลังจากนั้นคุณจะปรับขนาด SVG ให้ใหญ่rectเพียงใดความกว้างของภาพจะเท่ากับ 10%


33
แต่คำถามคือจะปรับขนาด SVG ได้อย่างไร?
Adrian Heine

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

คุณพูดถูกดีที่ได้ผลสำหรับฉันจริงๆ ฉันเดาว่าปัญหาของฉันคือคุณสมบัติความสูงและความกว้างในองค์ประกอบราก svg ของฉัน
Adrian Heine

2
ฉันทำการปรับแต่งเล็กน้อยให้กับซอนั้นเพื่อให้การปรับขนาดนั้นถูกบังคับในแนวนอนและแนวตั้งโดยไม่รักษาอัตราส่วนภาพและทำให้มันใช้งานได้ใน IE ในขณะที่ fiddle @robertc ที่ส่งไม่ได้ หวังว่ามันจะช่วยใครสักคนบนถนน!
Mister Crimson

3
โดยค่าเริ่มต้น svg ของคุณจะปรับขนาดให้ใหญ่ที่สุดเท่าที่จะเป็นไปได้เพื่อให้สามารถมองเห็นได้อย่างสมบูรณ์ แต่ยังคงรักษาอัตราส่วนไว้ (ดังนั้น viewBox สี่เหลี่ยมจัตุรัสจะไม่เติมพาเรนต์สี่เหลี่ยมอย่างสมบูรณ์) หากคุณต้องการบังคับให้ปิดทับคอนเทนเนอร์หลักอย่างสมบูรณ์ให้เพิ่มPreserveAspectRatio = "none"ลงในองค์ประกอบ SVG
patricksurry

24

สมมติว่าฉันมี SVG ซึ่งมีลักษณะดังนี้: รูปที่ 1

ผมอยากใส่มันลงใน div และเติมเต็มหารตอบสนอง วิธีการทำของฉันมีดังนี้:

ก่อนอื่นฉันเปิดไฟล์ SVG ในแอปพลิเคชันเช่น inkscape ในไฟล์ -> คุณสมบัติเอกสารฉันตั้งค่าความกว้างของเอกสารเป็น 800px และและความสูงเป็น 600px (คุณสามารถเลือกขนาดอื่นได้) จากนั้นฉันก็ใส่ SVG ลงในเอกสารนี้

รูปที่ 2

จากนั้นฉันบันทึกไฟล์นี้เป็นไฟล์ SVG ใหม่และรับข้อมูลเส้นทางจากไฟล์นี้ ตอนนี้ใน HTML โค้ดที่ใช้เวทมนตร์มีดังนี้:

<div id="containerId">    
    <svg
    id="svgId" 
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    x="0"
    y="0"
    width="100%"
    height="100%"
    viewBox="0 0 800 600"
    preserveAspectRatio="none">
       <path d="m0 0v600h800v-600h-75.07031l-431 597.9707-292.445315-223.99609 269.548825-373.97461h-271.0332z" fill="#f00"/>
    </svg>
</div>

โปรดทราบว่าความกว้างและความสูงของ SVG ถูกตั้งค่าเป็น 100% เนื่องจากเราต้องการให้บรรจุคอนเทนเนอร์ในแนวตั้งและแนวนอน แต่ความกว้างและความสูงของ viewBox จะเหมือนกับความกว้างและความสูงของเอกสารใน inkscape ซึ่งเป็น 800px X 600px. สิ่งต่อไปที่คุณต้องทำคือตั้งค่า PreserveAspectRatio เป็น "none" หากคุณจำเป็นต้องมีข้อมูลเพิ่มเติมเกี่ยวกับคุณลักษณะนี้ที่นี่เป็นที่ดีลิงค์ และนั่นคือทั้งหมดที่มีให้

อีกอย่างหนึ่งคือโค้ดนี้ใช้งานได้กับเบราว์เซอร์หลัก ๆ เกือบทั้งหมดแม้แต่เบราว์เซอร์รุ่นเก่า แต่ใน Android และ iOS บางเวอร์ชันคุณต้องใช้โค้ด javascrip / jQuery เพื่อให้สอดคล้องกัน ฉันใช้สิ่งต่อไปนี้ในฟังก์ชันพร้อมและปรับขนาดเอกสาร:

$('#svgId').css({
    'width': $('#containerId').width() + 'px',
    'height': $('#containerId').height() + 'px'
});

หวังว่าจะช่วยได้!


5
+1 สำหรับบันทึก preserveAspectRatio หลังจากล่าสัตว์สูงและต่ำเพื่อให้ SVG ยืดจริง (ไม่ใช่สเกล) เป็น div นี่คือคำตอบที่ถูกต้อง
adelphus

@Gazoris ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมนี้ มีคำถามเหมือนกัน จะเกิดอะไรขึ้นถ้า svg ของฉันซ้อนกัน สำหรับเช่น <svg> <svg id = "1"> </svg> <svg id = "2"> </svg> </svg> ฉันต้องการแสดง svg 1 และ 2 ตามเงื่อนไขและควรใช้ความกว้างและความสูง ของภาชนะ <div id = "container" style = "width: 200px; height: 200px;"> </div> คุณช่วยฉันได้ไหม
Prasad Parab

@ เรซ่าบาราดารัน: อัจฉริยะ.
DanMad

6

สิ่งที่ได้ผลสำหรับฉันเมื่อเร็ว ๆ นี้คือการลบแอตทริบิวต์height=""และทั้งหมดออกwidth=""จาก<svg>แท็กและแท็กย่อยทั้งหมด จากนั้นคุณสามารถใช้การปรับขนาดโดยใช้เปอร์เซ็นต์ของความสูงหรือความกว้างของคอนเทนเนอร์หลัก


5
คุณสามารถยกตัวอย่างการทำงานได้หรือไม่? ฉันไม่สามารถทำสิ่งนี้ได้
Michael

2

@robertc ถูกต้อง แต่คุณต้องสังเกตด้วยว่าsvg, #containerทำให้ svg ถูกปรับขนาดเป็นเลขชี้กำลังสำหรับอะไรก็ได้ยกเว้น 100% (ครั้งเดียว#containerและครั้งเดียวสำหรับsvg)

กล่าวอีกนัยหนึ่งถ้าฉันใช้ 50% h / w กับทั้งสององค์ประกอบจริงๆแล้วมันคือ 50% ของ 50% หรือ. 5 * .5 ซึ่งเท่ากับสเกล. 25 หรือ 25%

ตัวเลือกหนึ่งตัวทำงานได้ดีเมื่อใช้ตามที่ @robertc แนะนำ

svg {
  width:50%;
  height:50%;
}

นั่นเพราะตัวเลือกของคุณsvg, #containerตรงกับทั้งsvgองค์ประกอบ DOM และ#containerองค์ประกอบ DOM ฉันเชื่อว่าคุณกำลังมองหาsvg #containerแต่ข้อกำหนดของผู้ปกครองไม่จำเป็นหากคุณใช้ ID อยู่แล้ว
นิตย์

นั่นไม่ใช่สิ่งที่ฉันพูดว่า "once for #container and once for svg" ใช่ไหม
Justin Putney

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.