Untuk menghilangkan spasi tak terduga di sekitar instans SVG use, identifikasi apakah penyebabnya adalah viewBox sumber, penyesuaian rasio aspek, atau kotak baris CSS di sekitarnya. Panduan ini menunjukkan cara mendiagnosis dan memperbaiki tiap penyebab sambil menjaga koordinat penempatan tetap dapat diprediksi.
Tugas ini adalah penyuntingan halaman web desktop sederhana: menempatkan bentuk yang dapat digunakan kembali secara presisi di dalam SVG, lalu menyesuaikan tata letak HTML di sekitarnya sesuai keinginan. Anda dapat mengikuti contoh di editor teks biasa pada Mac Anda, lalu membuka file HTML yang disimpan di peramban desktop terkini.
Sistem koordinat mana yang mengendalikan spasi?
Ada tiga batas yang perlu diperiksa: kotak CSS elemen SVG terluar, viewport yang digunakan untuk simbol yang dirujuk, dan bentuk sebenarnya di dalam simbol tersebut. W3C secara eksplisit membedakan viewport SVG dari viewport CSS peramban. viewBox memetakan koordinat pengguna SVG ke viewport SVG; atribut ini tidak menjelaskan jendela peramban. Sistem Koordinat, Transformasi, dan Satuan — SVG 2
Sebagai contoh, x="20" pada elemen use memberikan offset dalam sistem koordinat SVG-nya. Nilai ini bukan berarti 20 piksel CSS dari tepi kiri jendela peramban. Penskalaan dan transformasi leluhur dapat mengubah lokasi offset tersebut pada halaman. Spesifikasi SVG menjelaskan penempatan use sebagai translasi tambahan, dengan perilaku yang berbeda dari tata letak kotak CSS. Struktur Dokumen — SVG 2
Mulailah dengan tabel keputusan ini. Ini adalah urutan diagnostik yang disusun berdasarkan mekanisme tata letak terdokumentasi, bukan daftar perbaikan yang dapat saling dipertukarkan.
| Yang Anda amati | Yang perlu diperiksa terlebih dahulu | Perbaikan yang mungkin |
|---|---|---|
| Jalur sempit di bawah seluruh SVG | Pemformatan inline dan tinggi baris induk | Jadikan SVG mandiri sebagai elemen blok, atau sesuaikan perataan inline-nya |
| Ruang kosong di dalam setiap grafik berulang | Koordinat bentuk dibandingkan dengan viewBox simbol |
Persempit batas sumber jika inset tidak disengaja |
| Ruang tambahan di dua sisi instans simbol | Dimensi instans dibandingkan dengan rasio viewBox |
Samakan rasionya atau pilih kebijakan penyesuaian yang disengaja |
| Penempatan lokal benar, tetapi posisi halaman salah | Unit pengguna SVG dibandingkan dengan koordinat viewport peramban | Konversikan koordinat sebelum menetapkan x dan y |
| Perubahan dimensi instans tidak berpengaruh | Elemen yang ditargetkan oleh href |
Gunakan simbol yang mendefinisikan viewport untuk penyesuaian, atau transformasikan geometrinya |
Buat ulang celah dengan contoh lokal yang lengkap
Simpan dokumen lengkap berikut sebagai svg-spacing.html di editor teks biasa, lalu buka di peramban Anda. Dokumen ini hanya menggunakan label dan persegi panjang sintetis, tanpa pustaka atau file eksternal. Persegi panjang berwarna pucat menandai viewport instans yang diinginkan; persegi panjang yang lebih gelap adalah karya seni yang digunakan kembali.
<!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 instans secara eksplisit menetapkan dimensinya. Ini menghindari ketergantungan pada ukuran implisit saat menyelidiki celah. MDN mendokumentasikan use sebagai elemen yang menggunakan kembali konten SVG yang dirujuk dan menyebutkan bahwa width serta height memengaruhi penyesuaian ketika targetnya adalah SVG atau simbol dengan viewBox. Contoh ini menggunakan atribut href saat ini. MDN: use
Hitung posisi awal persegi panjang pertama yang sebenarnya
Sumber pertama memiliki viewBox berukuran 100 kali 100, tetapi persegi panjangnya hanya menempati koordinat 20 sampai 80 di masing-masing arah. Viewport instans yang diminta berukuran 120 kali 60. Dengan penyesuaian bawaan xMidYMid meet, skalanya adalah nilai terkecil antara 120 / 100 dan 60 / 100: 0.6. viewBox yang telah diskalakan menempati area 60 kali 60, sehingga tersisa 30 unit di setiap sisi horizontal. Ini mengikuti algoritma transformasi viewport W3C. SVG 2: Menghitung transformasi ekuivalen dari viewport SVG
Untuk masukan ilustratif ini, persegi panjang yang digambar dimulai pada 20 + 30 + 20 × 0.6 = 62 secara horizontal dan 20 + 20 × 0.6 = 32 secara vertikal. Ukurannya adalah 60 × 0.6 = 36 di tiap arah. Perhitungannya diperiksa dengan kalkulasi deterministik sederhana; nilai ini merupakan hasil kalkulasi, bukan pengukuran dari pengujian peramban.
Instans kedua mengubah dua masukan yang terpisah: batas sumbernya menjadi 20 20 60 60, dan viewport instansnya menjadi 60 kali 60. Karena itu, persegi panjang memenuhi viewport tersebut dan dimulai pada koordinat SVG (20, 110). Untuk mengisolasi penyebabnya sendiri, ubah hanya satu masukan pada satu waktu.
Bagaimana cara menghilangkan spasi di dalam instans?
Perbaiki spasi yang tidak disengaja pada batas sumber
viewBox berisi empat angka: x minimum, y minimum, lebar, dan tinggi. Titik asalnya tidak harus nol. Dalam contoh, viewBox="20 20 60 60" menjelaskan batas yang sudah ada pada persegi panjang tanpa menulis ulang geometrinya. MDN: viewBox
Sebelum mempersempit grafik nyata, tentukan apakah inset-nya memang disengaja. Sekumpulan bentuk yang dapat digunakan kembali mungkin memakai kerangka koordinat bersama agar ukuran dan posisi visualnya tetap konsisten. Mempersempit tiap simbol secara terpisah dapat mengubah hubungan tersebut. Pertahankan batas bersama jika konsistensi itu merupakan bagian dari desain.
Untuk pemeriksaan geometri, getBBox() melaporkan batas dalam koordinat pengguna SVG. Secara bawaan, metode ini tidak menyertakan stroke dan penanda, serta tidak memperhitungkan transformasi yang diterapkan pada elemen target atau induknya. Karena itu, kotak pembatas yang hanya mencakup isian tidak cukup untuk memastikan pemotongan karya seni yang memiliki stroke atau transformasi. MDN: getBBox() milik SVGGraphicsElement
Pilih cara menyesuaikan rasio aspek yang tidak sama
Karya seni yang batasnya sudah rapat pun dapat memiliki ruang di sekitarnya ketika sumber persegi disesuaikan ke viewport lebar. Pilih kebijakannya sesuai hasil yang diinginkan. Terapkan preserveAspectRatio pada simbol yang dirujuk untuk penyesuaian internalnya, atau pada SVG terluar saat mendiagnosis pemetaan koordinat terluar. MDN: preserveAspectRatio
| Pilihan | Hasil dan kondisi |
|---|---|
| Rasio sumber dan viewport sama | Menghindari ruang akibat penyesuaian rasio aspek sambil mempertahankan proporsi |
xMidYMid meet |
Menampilkan seluruh viewBox, di tengah; rasio yang tidak sama menyisakan ruang |
xMinYMin meet |
Menggeser viewBox yang disesuaikan ke arah kiri atas; ruang yang tersisa tetap ada |
none |
Memungkinkan penskalaan nonseragam; persegi dapat menjadi persegi panjang |
xMidYMid slice |
Memenuhi viewport, tetapi sebagian konten sumber melampauinya; pemotongan menentukan bagian yang terlihat |
Mengubah perataan hanya memindahkan ruang akibat penyesuaian; cara ini tidak menghilangkan inset yang sudah tercantum dalam geometri sumber. Demikian pula, slice tidak cocok jika seluruh konten sumber harus tetap berada di dalam viewport. Perbedaan ini mengikuti definisi MDN tentang perataan, meet, slice, dan penyesuaian nonseragam. MDN: preserveAspectRatio
Periksa target referensi jika dimensi tampak tidak berpengaruh
Grup atau jalur biasa tidak otomatis memiliki viewport penyesuaian hanya karena elemen use merujuk padanya. W3C menyatakan bahwa width dan height instans tidak berpengaruh jika elemen yang dirujuk tidak membuat viewport baru. Agar penyesuaian per instans dapat diprediksi, tempatkan geometri yang dapat digunakan kembali di dalam simbol dengan batas eksplisit, seperti di atas. Untuk penskalaan geometris langsung, gunakan transformasi dan perhitungkan dampaknya terhadap penempatan. SVG 2: Tata letak grafik yang digunakan kembali
Bagaimana cara menghilangkan jalur di bawah SVG terluar?
Celah di luar SVG dapat berasal dari pemformatan inline HTML. WHATWG mengizinkan SVG berada dalam konten frasa; karena itu, halaman di sekitarnya dapat menempatkannya berdampingan dengan teks. Kotak baris CSS mencakup metrik font di atas dan di bawah garis dasar, sehingga grafik inline dapat menyisakan ruang yang terlihat di bawah kotaknya. Standar HTML: SVG, CSS 2: Perhitungan tinggi baris
Contoh lengkap ini sudah menetapkan display: block pada #canvas, sehingga SVG tidak ikut serta dalam kotak baris inline. Pertahankan aturan itu untuk gambar mandiri. Untuk menyelidiki mekanismenya, ubah sementara menjadi display: inline dan periksa baris di sekitarnya.
Untuk SVG yang harus tetap berada di samping teks, coba vertical-align: bottom pada SVG terluar dan periksa perataan teks yang dihasilkan. Properti ini meratakan kotak tingkat inline di dalam baris; properti ini tidak mengubah batas simbol atau penyesuaian internal. Konten lain dan tinggi baris induk masih dapat menentukan tinggi keseluruhan baris. MDN: vertical-align
Anggap deklarasi CSS ini sebagai alternatif untuk SVG terluar, bukan perbaikan kumulatif yang ditempelkan ke setiap instans:
/* Standalone drawing */
#canvas {
display: block;
}
/* Alternative when the drawing must stay inline */
/*
#canvas {
display: inline;
vertical-align: bottom;
}
*/
Bagaimana jika koordinat Anda berasal dari viewport peramban?
getBoundingClientRect() melaporkan posisi elemen relatif terhadap viewport peramban dalam piksel CSS. Posisinya berubah saat halaman digulir. Nilai tersebut berada dalam ruang yang berbeda dari koordinat pengguna SVG, sehingga menyalin langsung left dan top ke x dan y suatu instans umumnya keliru. MDN: getBoundingClientRect() milik Element
Gunakan transformasi koordinat jika masukannya berupa titik pada viewport peramban. getScreenCTM() menyediakan matriks transformasi SVG, dan penerapan inversnya mengonversi titik kembali ke koordinat lokal elemen yang dipilih. Metode matrixTransform() pada suatu titik melakukan konversi tersebut. MDN: getScreenCTM(), MDN: matrixTransform()
Cuplikan konsol berikut adalah perluasan opsional dari dokumen lengkap di atas. Cuplikan ini mengonversi titik viewport peramban (100, 150) ke koordinat pengguna SVG terluar dan memindahkan instans yang batasnya rapat ke sana. Cuplikan ini mengasumsikan instans yang belum ditransformasi dalam contoh tetap menjadi 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));
})();
Pemeriksaan angka hingga penting karena matriks yang tidak dapat diinvers menghasilkan komponen NaN. Hitung ulang matriks saat mengonversi titik baru setelah tata letak atau pengguliran berubah. Jika instans berada di dalam grup yang ditransformasi, konversikan ke sistem koordinat grup induk tersebut. Cuplikan ini diperiksa berdasarkan dokumentasi API; cuplikan ini tidak dijalankan di peramban selama riset. MDN: inverse() milik DOMMatrixReadOnly
Akhiri dengan memeriksa ketiga batas secara terpisah: kotak SVG terluar, viewport simbol yang telah disesuaikan, dan batas karya seni itu sendiri. Perbaiki batas yang menyebabkan ruang tak diinginkan, lalu pastikan hasilnya pada ukuran halaman yang diinginkan. Dengan demikian, penempatan tetap dapat diprediksi tanpa mengompensasi celah yang tak terjelaskan dengan offset sembarang.
Sumber
- Sistem Koordinat, Transformasi, dan Satuan — SVG 2 — W3C.
- Struktur Dokumen — SVG 2 — W3C.
use— MDN Web Docs.- viewBox — MDN Web Docs.
- preserveAspectRatio — MDN Web Docs.
- SVGGraphicsElement: metode getBBox() — MDN Web Docs.
- Standar HTML — SVG — WHATWG.
- Detail model pemformatan visual — W3C.
- Properti CSS vertical-align — MDN Web Docs.
- Element: metode getBoundingClientRect() — MDN Web Docs.
- SVGGraphicsElement: metode getScreenCTM() — MDN Web Docs.
- DOMPointReadOnly: metode matrixTransform() — MDN Web Docs.
- DOMMatrixReadOnly: metode inverse() — MDN Web Docs.