Bagaimana cara membuat elemen <svg> meluas atau berkontraksi ke penampung induknya?

112

Tujuannya adalah agar <svg>elemen diperluas ke ukuran wadah induknya, dalam hal ini a <div>, tidak peduli seberapa besar atau kecil wadah itu.

Kode:

<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>

Solusi paling umum untuk masalah ini tampaknya mengatur viewBoxatribut pada <svg>elemen.

viewBox="0 0 widthOfContainer heightOfContainer"

Namun, ini tampaknya tidak berfungsi dalam kasus di mana elemen dalam <svg>elemen memiliki lebar dan / atau tinggi yang telah ditentukan sebelumnya. Misalnya, <rect>elemen, dalam kode di atas, memiliki lebar dan tinggi yang ditetapkan secara eksplisit.

Jadi solusi yang jelas adalah dengan menggunakan% lebar dan% tinggi pada elemen tersebut juga. Tetapi apakah ini harus dilakukan? Terutama, karena <img src=test.svg >berfungsi dengan baik dan mengembang / berkontraksi tanpa masalah dengan <rect>ketinggian dan lebar yang ditetapkan secara eksplisit .

Jika elemen seperti <rect>, dan elemen lain seperti itu, harus memiliki lebar dan tinggi yang ditentukan dalam persentase, apakah ada cara di Inkscape untuk mengaturnya sehingga semua elemen dengan <svg>dokumen menggunakan persentase lebar, tinggi, dll .. daripada dimensi tetap ?

pengguna782860
sumber
1
Simpan svg sebagai file, lalu referensikan sebagai gambar, seperti <img src = "file.svg" /> dan dengan cara itu Anda dapat menggunakan lebar: 100% atau tinggi: 100%
Burimi

Jawaban:

56

Itu viewBoxbukanlah tinggi wadah, itu ukuran gambar Anda. Tentukan viewBoxlebar Anda menjadi 100 unit, lalu tentukan Anda rectmenjadi 10 unit. Setelah itu, seberapa besar skala SVG Anda, rectakan menjadi 10% lebar gambar.

robertc
sumber
33
Tetapi pertanyaannya adalah: Bagaimana cara menskalakan SVG?
Adrian Heine
6
@AdrianLang Penskalaan terjadi secara otomatis saat Anda menyetel ukuran pada objek SVG, seperti yang sudah dilakukan dalam kode di pertanyaan. Berikut adalah versi tetap dari contoh tersebut .
robertc
Anda benar, hebat, itu benar-benar berhasil untuk saya. Saya kira masalah saya adalah properti tinggi dan lebar di elemen root svg saya.
Adrian Heine
2
Saya membuat beberapa perubahan kecil pada biola itu untuk membuat pengubahan ukuran itu dipaksa secara horizontal dan vertikal tanpa mempertahankan rasio aspek, dan membuatnya berfungsi di IE, sementara biola @robertc yang dikirimkan tidak. Semoga ini akan membantu seseorang di jalan!
Mister Crimson
3
Secara default, svg Anda akan menskalakan sebesar mungkin sehingga benar-benar terlihat tetapi mempertahankan rasio aspeknya (sehingga kotak tampilan persegi tidak akan sepenuhnya mengisi induk persegi panjang). Jika Anda benar-benar ingin memaksanya untuk sepenuhnya menutupi penampung induk, tambahkan preservAspectRatio = "none" ke elemen SVG.
patricksurry
24

Misalkan saya memiliki SVG yang terlihat seperti ini: pic1

Dan saya ingin memasukkannya ke dalam div dan membuatnya mengisi div secara responsif. Cara saya melakukannya adalah sebagai berikut:

Pertama saya membuka file SVG di aplikasi seperti inkscape. Di File-> Document Properties saya mengatur lebar dokumen menjadi 800px dan tinggi menjadi 600px (Anda dapat memilih ukuran lain). Kemudian saya memasukkan SVG ke dalam dokumen ini.

pic2

Kemudian saya menyimpan file ini sebagai file SVG baru dan mendapatkan data jalur dari file ini. Sekarang dalam HTML kode yang melakukan keajaiban adalah sebagai berikut:

<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>

Perhatikan bahwa lebar dan tinggi SVG keduanya disetel ke 100%, karena kami ingin mengisi wadah secara vertikal dan horizontal, tetapi lebar dan tinggi dari viewBox sama dengan lebar dan tinggi dokumen dalam inkscape yaitu 800px X 600px. Hal berikutnya yang perlu Anda lakukan adalah menyetel preservAspectRatio ke "tidak ada". Jika Anda memerlukan informasi lebih lanjut tentang atribut ini, berikut adalah tautan yang bagus . Dan hanya itu saja.

Satu hal lagi adalah kode ini berfungsi di hampir semua browser utama bahkan yang lama, tetapi pada beberapa versi android dan ios Anda perlu menggunakan beberapa kode javascrip / jQuery agar tetap konsisten. Saya menggunakan yang berikut ini dalam fungsi siap dan ubah ukuran dokumen:

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

Semoga membantu!

Reza Baradaran Gazorisangi
sumber
5
1 untuk catatan preservAspectRatio. Setelah berburu tinggi dan rendah untuk mendapatkan SVG agar benar-benar meregang (bukan skala) ke div, ini adalah jawaban yang benar.
adelphus
@ Gazoris, Terima kasih atas jawaban yang luar biasa ini. memiliki pertanyaan yang sama. Bagaimana jika svg saya bersarang. misalnya, <svg> <svg id = "1"> </svg> <svg id = "2"> </svg> </svg> saya ingin menampilkan svg 1 dan 2 secara bersyarat dan harus mengambil lebar dan tinggi wadah. <div id = "container" style = "width: 200px; height: 200px;"> </div> bisakah Anda membantu saya dalam hal ini.
Prasad Parab
@Reza Baradaran: Jenius.
DanMad
6

Apa yang berhasil bagi saya baru-baru ini adalah menghapus semua height=""dan width=""atribut dari <svg>tag dan semua tag anak. Kemudian Anda dapat menggunakan penskalaan menggunakan persentase dari tinggi atau lebar wadah induk.

Geoff Colbath
sumber
5
Bisakah Anda memberi contoh yang berhasil? Saya tidak bisa mendapatkan ini untuk melakukan apa pun.
Michael
2

@robertc benar, tetapi Anda juga perlu memperhatikan bahwa svg, #containermenyebabkan svg diskalakan secara eksponensial untuk apa pun kecuali 100% (sekali untuk #containerdan sekali untuk svg).

Dengan kata lain, jika saya menerapkan 50% h / w ke kedua elemen, sebenarnya itu adalah 50% dari 50%, atau 0,5 * .5, yang sama dengan skala 0,25, atau 25%.

Satu pemilih berfungsi dengan baik saat digunakan seperti yang disarankan @robertc.

svg {
  width:50%;
  height:50%;
}
Justin Putney
sumber
Itu karena pemilih Anda svg, #containercocok baik dengan svgelemen dom dan para #containerelemen dom. Saya yakin Anda malah mencari svg #container, tetapi spesifikasi orang tua tidak diperlukan jika Anda tetap menggunakan ID.
Nit
Bukankah itu persis seperti yang saya katakan, "sekali untuk #container dan sekali untuk svg"?
Justin Putney
1
Oh maaf, Anda benar, tapi jawaban Anda agak aneh yang menyebabkan kesalahpahaman. Kedengarannya seolah-olah Anda berbicara tentang potensi gotcha pada awalnya.
Nit
1

Untuk iPhone Anda, Anda dapat menggunakan di head balise Anda:

"width=device-width"
Vincent
sumber