Untuk mengalih keluar ruang tidak dijangka di sekeliling instans use SVG, kenal pasti sama ada ruang itu berpunca daripada viewBox sumber, pemadanan nisbah aspek atau kotak baris CSS di sekelilingnya. Panduan ini menunjukkan cara mendiagnosis dan membetulkan setiap punca sambil memastikan koordinat peletakan kekal boleh dijangka.
Tugas ini ialah suntingan kecil halaman web desktop: letakkan bentuk boleh guna semula dengan tepat di dalam SVG, kemudian laraskan reka letak HTML di sekelilingnya supaya sepadan dengan yang dikehendaki. Anda boleh mengikuti contoh dalam penyunting teks biasa pada Mac anda dan membuka fail HTML yang disimpan dalam pelayar desktop semasa.
Sistem koordinat yang manakah mengawal ruang ini?
Terdapat tiga sempadan yang perlu diperiksa: kotak CSS elemen SVG luar, viewport yang digunakan untuk simbol yang dirujuk dan bentuk sebenar di dalam simbol itu. W3C membezakan viewport SVG daripada viewport CSS pelayar secara jelas. viewBox memetakan koordinat pengguna SVG ke dalam viewport SVG; ia tidak menerangkan tetingkap pelayar. Sistem Koordinat, Transformasi dan Unit — SVG 2
Contohnya, x="20" pada elemen use memberikan ofset dalam sistem koordinat SVGnya. Ia tidak bermaksud 20 piksel CSS dari tepi kiri tetingkap pelayar. Penskalaan dan transformasi induk boleh mengubah lokasi ofset itu pada halaman. Spesifikasi SVG menerangkan peletakan use sebagai translasi tambahan, dengan tingkah laku yang berbeza daripada reka letak kotak CSS. Struktur Dokumen — SVG 2
Mulakan dengan jadual keputusan ini. Jadual ini ialah urutan diagnostik yang diperoleh daripada mekanisme reka letak yang didokumenkan, bukannya senarai pembetulan yang boleh saling menggantikan.
| Perkara yang anda lihat | Perkara yang perlu diperiksa dahulu | Pembetulan yang berkemungkinan |
|---|---|---|
| Jalur sempit di bawah keseluruhan SVG | Pemformatan sebaris dan ketinggian baris induk | Jadikan SVG kendiri sebagai unsur aras blok atau laraskan penjajaran sebarisnya |
| Ruang kosong di dalam setiap grafik berulang | Koordinat bentuk berbanding viewBox simbol |
Ketatkan sempadan sumber jika sisipan itu tidak disengajakan |
| Ruang tambahan pada dua sisi instans simbol | Dimensi instans berbanding nisbah viewBox |
Samakan nisbah atau pilih dasar pemadanan yang disengajakan |
| Peletakan setempat betul tetapi kedudukan halaman salah | Unit pengguna SVG berbanding koordinat viewport pelayar | Tukar koordinat sebelum menetapkan x dan y |
| Perubahan dimensi instans tidak memberi kesan | Elemen yang disasarkan oleh href |
Gunakan simbol yang mentakrifkan viewport untuk pemadanan atau transformasikan geometri |
Hasilkan semula ruang itu dengan contoh setempat yang lengkap
Simpan dokumen lengkap berikut sebagai svg-spacing.html dalam penyunting teks biasa, kemudian bukanya dalam pelayar anda. Dokumen ini hanya menggunakan label sintetik dan segi empat tepat, tanpa pustaka atau fail luaran. Segi empat tepat berwarna pucat menandakan viewport instans yang dikehendaki; segi empat tepat yang lebih gelap ialah karya seni yang digunakan semula.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SVG spacing example</title>
<style>
body {
margin: 24px;
font: 16px system-ui, sans-serif;
}
#canvas {
display: block;
width: 320px;
height: 200px;
outline: 1px solid #687580;
background: #fff;
}
.viewport-guide { fill: #e4edf2; }
.artwork { fill: #356b8c; }
text { fill: #253744; font-size: 14px; }
</style>
</head>
<body>
<p>Two instances with different source bounds and fitting dimensions.</p>
<svg id="canvas" xmlns="http://www.w3.org/2000/svg"
width="320" height="200" viewBox="0 0 320 200"
role="img" aria-labelledby="drawing-title">
<title id="drawing-title">Padded and tightly fitted rectangles</title>
<defs>
<symbol id="padded" viewBox="0 0 100 100">
<rect id="source-shape" class="artwork"
x="20" y="20" width="60" height="60" />
</symbol>
<symbol id="tight" viewBox="20 20 60 60">
<rect class="artwork"
x="20" y="20" width="60" height="60" />
</symbol>
</defs>
<rect class="viewport-guide"
x="20" y="20" width="120" height="60" />
<use href="#padded" x="20" y="20" width="120" height="60" />
<text x="160" y="55">Padded source</text>
<rect class="viewport-guide"
x="20" y="110" width="60" height="60" />
<use id="tight-instance" href="#tight"
x="20" y="110" width="60" height="60" />
<text x="110" y="145">Tight source</text>
</svg>
</body>
</html>
Kedua-dua instans menetapkan dimensinya secara jelas. Ini mengelakkan pergantungan pada saiz tersirat semasa menyiasat ruang tersebut. MDN mendokumenkan use sebagai penggunaan semula kandungan SVG yang dirujuk dan menyatakan bahawa width dan height mempengaruhi pemadanan apabila sasaran ialah SVG atau simbol dengan viewBox. Contoh ini menggunakan atribut href semasa. MDN: use
Kira lokasi sebenar segi empat tepat pertama bermula
Sumber pertama mempunyai viewBox bersaiz 100-kali-100, tetapi segi empat tepatnya hanya meliputi koordinat 20 hingga 80 dalam setiap arah. Viewport instans yang diminta ialah 120-kali-60. Dengan pemadanan lalai xMidYMid meet, skalanya ialah nilai yang lebih kecil antara 120 / 100 dan 60 / 100: 0.6. viewBox berskala itu meliputi 60-kali-60, meninggalkan 30 unit pada setiap sisi mendatar. Ini mengikut algoritma transformasi viewport W3C. SVG 2: Mengira transformasi setara bagi viewport SVG
Bagi input ilustrasi ini, segi empat tepat yang dilukis bermula pada 20 + 30 + 20 × 0.6 = 62 secara mendatar dan 20 + 20 × 0.6 = 32 secara menegak. Saiznya ialah 60 × 0.6 = 36 dalam setiap arah. Pengiraan ini disemak dengan pengiraan kecil yang deterministik; ini nilai yang dikira, bukannya ukuran daripada ujian pelayar.
Instans kedua mengubah dua input yang bebas: sempadan sumbernya menjadi 20 20 60 60, dan viewport instansnya menjadi 60-kali-60. Oleh itu, segi empat tepat memenuhi viewport itu dan bermula pada koordinat SVG (20, 110). Untuk mengasingkan puncanya sendiri, ubah satu input sahaja pada satu masa.
Bagaimanakah anda mengalih keluar ruang di dalam instans?
Betulkan ruang tidak disengajakan dalam sempadan sumber
viewBox mengandungi empat nombor: x minimum, y minimum, lebar dan tinggi. Asalnya tidak semestinya sifar. Dalam contoh ini, viewBox="20 20 60 60" menerangkan sempadan sedia ada segi empat tepat tanpa menulis semula geometrinya. MDN: viewBox
Sebelum mengetatkan grafik sebenar, tentukan sama ada sisipannya disengajakan. Satu set bentuk boleh guna semula mungkin berkongsi bingkai koordinat yang sama supaya saiz dan kedudukan visualnya kekal konsisten. Mengetatkan setiap simbol secara berasingan boleh mengubah hubungan tersebut. Kekalkan sempadan bersama apabila konsistensi itu sebahagian daripada reka bentuk.
Untuk pemeriksaan geometri, getBBox() melaporkan sempadan dalam koordinat pengguna SVG. Secara lalai, ia mengecualikan strok dan penanda, serta tidak mengambil kira transformasi yang dikenakan pada elemen sasaran atau induknya. Oleh itu, kotak sempadan isi sahaja bukan bukti yang mencukupi untuk memangkas karya seni berstrok atau yang ditransformasikan. MDN: SVGGraphicsElement getBBox()
Pilih cara memadankan nisbah aspek yang tidak sepadan
Karya seni yang sempadannya sudah ketat pun boleh mempunyai ruang di sekelilingnya apabila sumber segi empat sama dipadankan ke dalam viewport lebar. Pilih dasar mengikut hasil yang dikehendaki. Gunakan preserveAspectRatio pada simbol yang dirujuk untuk pemadanan dalamannya, atau pada SVG luar apabila mendiagnosis pemetaan koordinat luar. MDN: preserveAspectRatio
| Pilihan | Hasil dan syarat |
|---|---|
| Nisbah sumber dan viewport sepadan | Mengelakkan ruang akibat pemadanan nisbah aspek sambil mengekalkan perkadaran |
xMidYMid meet |
Memaparkan keseluruhan viewBox di tengah; nisbah yang tidak sepadan meninggalkan ruang |
xMinYMin meet |
Mengalih viewBox yang dipadankan ke arah kiri atas; ruang yang selebihnya masih wujud |
none |
Membenarkan penskalaan tidak seragam; segi empat sama boleh menjadi segi empat tepat |
xMidYMid slice |
Memenuhi viewport, tetapi sebahagian kandungan sumber melangkaui sempadannya; pemotongan menentukan keterlihatan |
Menukar penjajaran mengalihkan ruang pemadanan; ia tidak menghapuskan sisipan yang sudah terkandung dalam geometri sumber. Begitu juga, slice tidak sesuai apabila semua kandungan sumber mesti kekal di dalam viewport. Perbezaan ini mengikut takrif MDN bagi penjajaran, meet, slice dan pemadanan tidak seragam. MDN: preserveAspectRatio
Periksa sasaran rujukan apabila dimensi seolah-olah tidak berkesan
Kumpulan atau laluan biasa tidak mendapat viewport pemadanan hanya kerana elemen use merujuk kepadanya. W3C menyatakan bahawa width dan height instans tidak memberi kesan apabila elemen yang dirujuk tidak mewujudkan viewport baharu. Untuk pemadanan yang boleh dijangka bagi setiap instans, letakkan geometri boleh guna semula di dalam simbol dengan sempadan yang jelas, seperti di atas. Untuk penskalaan geometri secara langsung, gunakan transformasi dan ambil kira kesannya terhadap peletakan. SVG 2: Reka letak grafik yang digunakan semula
Bagaimanakah anda mengalih keluar jalur di bawah SVG luar?
Ruang di luar SVG boleh berpunca daripada pemformatan sebaris HTML. WHATWG membenarkan SVG berada dalam kandungan frasa; oleh itu, halaman di sekelilingnya boleh meletakkannya bersebelahan teks. Kotak baris CSS merangkumi metrik fon di atas dan di bawah garis dasar, jadi grafik sebaris boleh meninggalkan ruang yang kelihatan di bawah kotaknya. Piawaian HTML: SVG, CSS 2: Pengiraan ketinggian baris
Contoh lengkap ini sudah menetapkan display: block pada #canvas, yang mengeluarkan SVG itu daripada penyertaan dalam kotak baris sebaris. Kekalkan peraturan itu untuk lukisan kendiri. Untuk menyiasat mekanismenya, ubahnya sementara kepada display: inline dan periksa baris di sekelilingnya.
Untuk SVG yang perlu kekal di sebelah teks, cuba vertical-align: bottom pada SVG luar dan periksa penjajaran teks yang terhasil. Sifat ini menjajarkan kotak aras sebaris dalam barisnya; ia tidak mengubah sempadan simbol atau pemadanan dalaman. Kandungan lain dan ketinggian baris induk masih boleh menentukan jumlah ketinggian baris. MDN: vertical-align
Anggap pengisytiharan CSS ini sebagai pilihan alternatif untuk SVG luar, bukannya pembetulan kumulatif yang perlu ditampal pada setiap instans:
/* Standalone drawing */
#canvas {
display: block;
}
/* Alternative when the drawing must stay inline */
/*
#canvas {
display: inline;
vertical-align: bottom;
}
*/
Bagaimana jika koordinat anda datang daripada viewport pelayar?
getBoundingClientRect() melaporkan kedudukan elemen berbanding viewport pelayar dalam piksel CSS. Kedudukannya berubah apabila halaman ditatal. Nilai tersebut datang daripada ruang yang berbeza daripada koordinat pengguna SVG, maka menyalin terus left dan top ke dalam x dan y instans biasanya tidak betul. MDN: Elemen getBoundingClientRect()
Gunakan transformasi koordinat apabila inputnya ialah titik viewport pelayar. getScreenCTM() memberikan matriks transformasi SVG, dan menggunakan songsangannya menukar titik itu kembali kepada koordinat setempat elemen yang dipilih. Kaedah matrixTransform() pada titik melakukan penukaran tersebut. MDN: getScreenCTM(), MDN: matrixTransform()
Petikan konsol berikut ialah sambungan pilihan kepada dokumen lengkap di atas. Ia menukar titik viewport pelayar (100, 150) kepada koordinat pengguna SVG luar dan mengalihkan instans yang sempadannya ketat ke situ. Andaian yang digunakan ialah instans dalam contoh yang tidak ditransformasikan itu kekal sebagai anak langsung SVG tersebut.
(() => {
const canvas = document.getElementById("canvas");
const instance = document.getElementById("tight-instance");
if (!canvas || !instance) {
throw new Error("Open the complete SVG spacing example first.");
}
const matrix = canvas.getScreenCTM();
if (!matrix) {
throw new Error("The SVG coordinate matrix is unavailable.");
}
const viewportPoint = new DOMPoint(100, 150);
const localPoint = viewportPoint.matrixTransform(matrix.inverse());
if (!Number.isFinite(localPoint.x) || !Number.isFinite(localPoint.y)) {
throw new Error("The SVG coordinate matrix cannot be inverted.");
}
instance.setAttribute("x", String(localPoint.x));
instance.setAttribute("y", String(localPoint.y));
})();
Semakan nombor terhingga penting kerana matriks yang tidak boleh disongsangkan menghasilkan komponen NaN. Kira semula matriks itu apabila menukar titik baharu selepas reka letak atau penatalan berubah. Jika instans anda berada di dalam kumpulan yang ditransformasikan, tukar ke dalam sistem koordinat kumpulan induk itu. Petikan ini disemak berdasarkan dokumentasi API; ia tidak dijalankan dalam pelayar semasa penyelidikan. MDN: DOMMatrixReadOnly inverse()
Akhiri dengan memeriksa tiga sempadan secara berasingan: kotak SVG luar, viewport simbol yang dipadankan dan sempadan karya seni itu sendiri. Betulkan sempadan yang menyebabkan ruang yang tidak dikehendaki, kemudian sahkan hasilnya pada saiz halaman yang ditetapkan. Ini memberikan peletakan yang boleh dijangka tanpa mengimbangi jurang yang tidak dapat dijelaskan dengan ofset sewenang-wenangnya.
Sumber
- Sistem Koordinat, Transformasi dan Unit — SVG 2 — W3C.
- Struktur Dokumen — SVG 2 — W3C.
use— MDN Web Docs.- viewBox — MDN Web Docs.
- preserveAspectRatio — MDN Web Docs.
- SVGGraphicsElement: kaedah getBBox() — MDN Web Docs.
- Piawaian HTML — SVG — WHATWG.
- Butiran model pemformatan visual — W3C.
- Sifat CSS vertical-align — MDN Web Docs.
- Elemen: kaedah getBoundingClientRect() — MDN Web Docs.
- SVGGraphicsElement: kaedah getScreenCTM() — MDN Web Docs.
- DOMPointReadOnly: kaedah matrixTransform() — MDN Web Docs.
- DOMMatrixReadOnly: kaedah inverse() — MDN Web Docs.