> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# SVG Metin Kaydırma: tspan ile Ölçülmüş Satırlar Oluşturun

> Gerçek yazı tipiyle sözcükleri ölçüp tspan oluşturarak SVG etiketlerini kaydırın. Dar etiketleri sınayın, taşan sözcükleri veya fazla satırları reddedin ve sonucu kaydedin.

Source: https://perfectvector.com/tr/blog/svg-text-wrap-tspan

Language: tr
Author: Irene Kim
Published: 2026-10-06T08:00:00+09:00
Updated: 2026-10-06T08:00:00+09:00

Değişen SVG etiketini açık satırlara kaydırmak için aday sözcük gruplarını `getComputedTextLength()` ile ölçün, ardından kabul edilen her satır için bir `<tspan>` yazın. Önce belgenin yazı tiplerini bekleyin ve tek sözcük etiketten genişse veya sonuç satır sınırını aşarsa ne olacağını seçin.

Aşağıdaki başlangıç boşlukla ayrılmış sözcükler kullanır ve iki taşmayı da kısmi etiket üretmeden reddeder. Özgün delikli eşkenar dörtgen illüstrasyonunu metinden ayrı tutar; etiket genişliğini değiştirmek çizimi yeniden çizmez.

## Satırları yerleştirmeden önce kaydırma politikasını seçin

[`tspan` öğesi](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/tspan), SVG metninin bölümlerini konumlandırmanızı sağlar. Rutinimiz her satıra aynı `x`, sonraki satırlara `dy` ofseti ayarlar. Satır kırma kararını rutin verir; öğe sonucu tutar.

Bu, açık düzen yaklaşımlarından biridir. [SVG 2 metin belirtimi](https://www.w3.org/TR/SVG2/text.html), içerik alanı ve CSS metin düzeniyle otomatik kaydırmayı da tanımlar. Bu yazı o özellikleri sınamaz veya her tarayıcıda eksik olduklarını iddia etmez.

İllüstrasyonun dışındaki HTML paragrafı için [CSS ile kayan SVG siluetinin çevresine metin sarın](https://perfectvector.com/tr/blog/css-text-around-svg-shape). Bu düzen görsel konturunu izlerken sözcükleri konumlandırılmış SVG etiket satırlarına dönüştürmek yerine normal HTML olarak tutar.

Bu küçük İngilizce etiket örneğinde politika şöyledir:

* Boşlukları birleştirin, sözcükleri özgün sırada tek boşlukla ayrılmış olarak deneyin.
* Aday satırı yalnızca ölçülen uzunluğu kullanılabilir genişliğe sığarken koruyun.
* Tek başına sığmayan sözcüğü reddedin; tireleme noktası uydurmayın.
* Sonuç `maxLines` değerinden çok satır gerektiriyorsa tamamını reddedin; son sözcükleri sessizce atmayın.

Satır sınırı düzen kararıdır. Başlangıç taban çizgisi, satır aralığı ve kullanılabilir yükseklikle birlikte seçin. Sarmalayıcı dikey içerik kutusunu sizin için hesaplamaz.

**Etiket genişliğini değiştirin, çizimi koruyun**

![Geniş etikette uzun satırlar ve dar etikette kısa satırlar yanında delikli eşkenar dörtgen illüstrasyonunun kavramsal karşılaştırması](https://perfectvector.com/blog/svg-text-wrap-tspan/measured-lines.webp)

*İllüstrasyon: dar etiket daha çok satır gerektirebilir. Soyut çubuklar ve noktalı çerçeveler kavramsal ipuçlarıdır; aşağıdaki gerçek metin, ölçümler ve reddetme durumları bağımsız tarayıcı başlangıcından gelir.*

## Etiketi çizecek yazı tipiyle ölçün

[`getComputedTextLength()`](https://developer.mozilla.org/en-US/docs/Web/API/SVGTextContentElement/getComputedTextLength), SVG metninin hesaplanan uzunluğunu ölçer. Bu başlangıç, etiketin metin öğesini aynı bağlı SVG içinde gizli ölçüm öğesi olarak klonlar, satırları planladıktan sonra kaldırır. İkisi de 22 birimde açık `Arial, sans-serif` kullanır.

Kod ölçmeden önce [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) bekler. Bu, belgenin yazı tipi yüklemesini ve ilgili düzeni bekler; dışa aktarılan SVG'ye yazı tipi gömmez. Kullanılabilir farklı yazı tipi farklı satır uzunlukları üretebilir. Metin, yazı tipi ayarları veya kullanılabilir genişlik değiştiğinde düzeni yeniden çalıştırın.

## Bağımlılıksız eksiksiz başlangıcı çalıştırın

Bunu `starter.html` olarak kaydedip tarayıcıda açın. Altı durum oluşturur, ölçümlerini yazdırır ve oluşan her SVG'yi serileştirir. İlk iki durum yalnızca etiket genişliğini, üçüncü metni değiştirir. Diğerleri reddetmeyi ve düz metni sınar.

```html
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Measured SVG label lines</title>
<style>
  body { margin: 24px; font: 16px system-ui; background: #f6f2e8; }
  #cases { display: grid; grid-template-columns: repeat(2, 360px); gap: 20px; }
  figure { margin: 0; }
  svg { display: block; background: white; }
  figcaption { margin: 6px 0; }
  pre { white-space: pre-wrap; font-size: 12px; }
</style>
<h1>Keep artwork and label layout separate</h1>
<div id="cases"></div>
<pre id="report"></pre>
<script>
  const ns = 'http://www.w3.org/2000/svg';
  const emblem = 'M60 32 L100 72 L60 112 L20 72 Z M60 54 L78 72 L60 90 L42 72 Z';
  function element(name, attributes) {
    const node = document.createElementNS(ns, name);
    for (const [key, value] of Object.entries(attributes)) node.setAttribute(key, value);
    return node;
  }
  function wrapWords(text, source, { width, maxLines, lineHeight }) {
    text.replaceChildren();
    if (!(width > 0 && lineHeight > 0 && Number.isInteger(maxLines) && maxLines > 0)) {
      return { status: 'invalid-options', lines: [] };
    }
    const words = source.trim().split(/\s+/u).filter(Boolean);
    const probe = text.cloneNode(false);
    probe.setAttribute('visibility', 'hidden');
    text.parentNode.append(probe);
    const measure = value => { probe.textContent = value; return probe.getComputedTextLength(); };
    const lines = [];
    let line = '';
    try {
      for (const word of words) {
        const wordWidth = measure(word);
        if (wordWidth > width) {
          return { status: 'overlong-word', word, measuredWidth: wordWidth, lines: [] };
        }
        const candidate = line ? line + ' ' + word : word;
        if (line && measure(candidate) > width) {
          lines.push(line);
          line = word;
        } else line = candidate;
      }
      if (line) lines.push(line);
      if (lines.length > maxLines) {
        return { status: 'too-many-lines', requiredLines: lines.length, lines: [] };
      }
      const x = text.getAttribute('x');
      lines.forEach((value, index) => {
        const span = element('tspan', { x, dy: index ? lineHeight : 0 });
        span.textContent = value;
        text.append(span);
      });
      return { status: 'ok', lines,
        lengths: [...text.children].map(span => span.getComputedTextLength()) };
    } finally { probe.remove(); }
  }
  const cases = [
    { id: 'normal', source: 'Keep artwork and labels separate', width: 200, maxLines: 4 },
    { id: 'narrow', source: 'Keep artwork and labels separate', width: 110, maxLines: 5 },
    { id: 'changed', source: 'Keep the original artwork beside every exported label', width: 200, maxLines: 4 },
    { id: 'long-word', source: 'Artwork supercalifragilisticexpialidocious', width: 110, maxLines: 5 },
    { id: 'line-limit', source: 'Keep artwork and labels separate', width: 110, maxLines: 2 },
    { id: 'literal', source: 'Cove <g> & field', width: 200, maxLines: 4 },
  ];
  const entries = cases.map(test => {
    const figure = document.createElement('figure');
    const svg = element('svg', { width: 360, height: 240, viewBox: '0 0 360 240' });
    svg.append(element('path', { d: emblem, fill: '#176b5b', 'fill-rule': 'evenodd' }));
    svg.append(element('rect', { x: 140, y: 34, width: test.width, height: 170,
      fill: 'none', stroke: '#ce7b55', 'stroke-dasharray': '4 4' }));
    const text = element('text', { x: 140, y: 60, 'font-family': 'Arial, sans-serif',
      'font-size': 22, fill: '#172b34' });
    svg.append(text);
    const caption = document.createElement('figcaption');
    figure.append(svg, caption);
    document.getElementById('cases').append(figure);
    return { test, svg, text, caption };
  });
  async function run() {
    await document.fonts.ready;
    const results = entries.map(({ test, svg, text, caption }) => {
      const result = wrapWords(text, test.source, { ...test, lineHeight: 30 });
      caption.textContent = test.id + ': ' + result.status;
      return { ...test, ...result, fontFamily: getComputedStyle(text).fontFamily,
        fontSize: getComputedStyle(text).fontSize, tspanCount: text.children.length,
        pathD: svg.querySelector('path').getAttribute('d'),
        pathCount: svg.querySelectorAll('path').length,
        imageCount: svg.querySelectorAll('image').length,
        foreignObjectCount: svg.querySelectorAll('foreignObject').length,
        serialized: new XMLSerializer().serializeToString(svg) };
    });
    document.getElementById('report').textContent = JSON.stringify({
      fontStatus: document.fonts.status, policy: 'Whitespace words; reject a long word or too many lines without partial output', results,
    }, null, 2);
  }
  run();
</script>
</html>
```

Rutin metni işaretleme olarak eklemek yerine her satırı [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) ile oluşturur. Düz metin durumunda `Cove <g> & field` normal metin olarak kalır: serileştirilmiş SVG ek grup öğesi değil, kaçış uygulanmış açılı ayraçlar ve ve işareti içerir.

Ölçüm klonu bağlı ancak gizlidir; görünür etiketle aynı yazı tipi özniteliklerine sahiptir. Reddedilme dâhil `finally` içinde kaldırılır. Satırlar ancak sözcük genişliği ve maksimum satır kontrolleri geçince eklenir. Rutin önce eski etiketi temizler; reddedilen güncelleme eski veya kısmi metin bırakmaz. Dönen durumu uygulamanızın arayüzünde işleyin.

## Altı özgün durum ne üretti?

Bu başlangıcı, belgenin yazı tipleri `loaded` bildirirken Chrome'da aynen çalıştırdık. Aşağıdaki ölçülen uzunluklar o ortamın SVG metin uzunluklarıdır; boyalı glif sınırları veya yazı tipi taşınabilirlik garantisi değildir.

| Durum                            | Genişlik / en çok satır | Sonuç                                           | Gözlenen en uzun satır |
| -------------------------------- | ----------------------- | ----------------------------------------------- | ---------------------- |
| Özgün ifade                      | 200 / 4                 | İki satır: Keep artwork and; labels separate    | 172.44                 |
| Aynı ifade, dar kutu             | 110 / 5                 | Dört satır: Keep; artwork; and labels; separate | 100.30                 |
| Daha uzun metin                  | 200 / 4                 | Üç satır                                        | 198.13                 |
| Fazla uzun sözcük                | 110 / 5                 | overlong-word; sıfır tspan                      | Sözcük ölçümü 311.82   |
| Dar ifade, iki satır sınırı      | 110 / 2                 | too-many-lines; dört gerekli; sıfır tspan       | Etiket üretilmedi      |
| Düz açılı ayraçlar ve ve işareti | 200 / 4                 | Tek düz metin satırı                            | 162.66                 |

Özgün ifade `Keep artwork and labels separate` değeridir. Uzun sürüm `Keep the original artwork beside every exported label` değeridir. Kabul edilen her satır seçilen genişliğe sığdı. Reddedilen durumlar etiketi atarken illüstrasyonu görünür tuttu; hata durumunu incelemek kolaylaştı.

Serileştirilen altı dosyanın tamamı özdeş özgün eşkenar dörtgen yolunu, bir yerel metin öğesini korudu ve image veya `foreignObject` içermedi. Kabul edilen durumlar sırasıyla iki, dört, üç ve bir tspan içerdi; iki reddedilen durumda sıfır vardı. Ayrıca altı serileştirilmiş SVG'yi aynı tarayıcıda görsel olarak yeniden açtık; hepsi 360×240'ta yüklendi. Bu, bu dosyalar ve tarayıcının kontrolüdür; her düzenleyici veya işleyicinin değil.

## Düzenlenmiş SVG'yi kaydedip teslimi sınayın

[`XMLSerializer.serializeToString()`](https://developer.mozilla.org/en-US/docs/Web/API/XMLSerializer/serializeToString), rapordaki serileştirilmiş işaretlemeyi oluşturur. Başarılı durumun `serialized` dizgesini `.svg` dosyası olarak kaydedin. Dosya zaten açık satırlar içerir; yeniden oluşturmak için bu JavaScript rutinine ihtiyaç duymaz.

Sözcükleri hâlâ canlı metindir. Kayıtlı dosya yazı tipi dosyası veya dış hatlı glifler değil, font-family isteğini korur. Başka yazı tipine sahip hedef, satır dizgeleri ve konumları kalsa bile harfleri değiştirebilir. Özgün metni ve düzen girdilerini çıktı kopyasının yanında saklayın, teslimden önce gerçek hedefi inceleyin. Sabit harf şekli için ana dosyada canlı metni korurken uygun kaynak düzenleyicide dış hatlı teslim kopyası oluşturun.

[foreignObject metin kılavuzu](https://perfectvector.com/tr/blog/svg-foreignobject-text), başka işleyicide kaybolan HTML etiketlerini ele alır. Bu başlangıç en baştan yerel metin oluşturur. [textLength kılavuzu](https://perfectvector.com/tr/blog/svg-textlength-fit), uzunluğu ayarlayarak tek satırı sığdırmayı ele alır; ölçülmüş satırlar eklemekten farklı karar sağlar. Tüm etiketi çevre çizime göre konumlandırmanız gerektiğinde [dikey hizalama kılavuzunu](https://perfectvector.com/tr/blog/svg-text-vertical-alignment) kullanın.

## Sarmalayıcının sınırlarını açık tutun

Boşluktan bölmek bilinçli olarak küçük bir politikadır. Yinelenen boşlukları, sekmeleri ve açık satır sonlarını birleştirir; dile özgü kırma kurallarını, tirelemeyi, çift yönlü paragrafları veya karışık stilli zengin metin aralıklarını işlemez. Metniniz bu özellikleri gerektiriyorsa başka düzen sistemi seçin veya politikayı genişletip sınayın.

Genişlik kontrolü, dekoratif glif taşmalarının çizili çerçevede kalacağını veya beş taban çizgisinin seçilen yüksekliğe sığacağını da garanti etmez. Görünür yazıları teslim boyutunda inceleyin. Testimiz yatay etiketler, sabit yazı tipi öznitelikleri ve 30 birim satır adımı kullanır; yeniden ölçmeden sayıları başka yazı tipine taşımayın.

İllüstrasyonunuz yalnızca PNG veya JPG ise ve düzenlenebilir çizim gerekiyorsa [PerfectVector ile küçük resim SVG'si hazırlayın](https://perfectvector.com/tr/clipart-to-svg), kenarlarını ve iç açıklıklarını inceleyin, çizimi etiketten ayrı tutun. Metni yerel metin olarak yeniden yazın, kaydırma politikasını çalıştırın ve birleştirilmiş çıktıyı inceleyin. Vektörleştirme illüstrasyon yollarını hazırlar; satır kırmalarını seçmez veya izlenmiş yazılardan düzenlenebilir sözcükleri geri getirmez. Mevcut iyi yollar olduğu gibi kalabilir. [Vektörleştirme kılavuzu](https://perfectvector.com/tr/blog/what-is-image-vectorization) bu kaynak geri kazanma adımını açıklar.

## Sık sorulan sorular

**tspan her satırın nereden kırılacağını otomatik belirler mi?**
Bu başlangıç sözcük gruplarını ölçerek karar verir, sonra kabul edilen her satır için konumlandırılmış bir tspan oluşturur. SVG 2'nin CSS tabanlı otomatik kaydırmasını sınamaz.

**Etiketten geniş sözcüğe ne olur?**
Rutin overlong-word döndürür ve etiket üretmez. Sessizce kırpmak yerine alanı genişletin, metni kısaltın veya ayrı sınanmış kırma politikası sağlayın.

**maxLines kalan sözcükleri kaldırır mı?**
Hayır. Bu politika fazla satır gerektiğinde sonucu reddeder, gereken sayıyı bildirir ve sıfır tspan bırakır. Uygulama bu durumu işlemelidir.

**Dışa aktarılan satırlar başka yazı tipiyle özdeş görünür mü?**
Açık sözcükler ve konumlar kalır, ancak dosya yazı tipi gömmez veya glifleri dış hatlara dönüştürmez. Gerçek hedefte kullanılabilir yazı tipini ve harfleri inceleyin.

## Kaynaklar

1. [MDN tspan öğesi](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/tspan) — konumlandırılmış alt metin ve satır ofseti öznitelikleri.
2. [W3C SVG 2 metni](https://www.w3.org/TR/SVG2/text.html) — açık konumlandırma ve ayrı otomatik kaydırma modeli.
3. [MDN getComputedTextLength](https://developer.mozilla.org/en-US/docs/Web/API/SVGTextContentElement/getComputedTextLength) — gerçek SVG metnini ölçme.
4. [MDN FontFaceSet.ready](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) — yazı tipi yüklemesini ve düzeni bekleme.
5. [MDN textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) — işaretleme yerine düz metin ekleme.
6. [MDN XMLSerializer](https://developer.mozilla.org/en-US/docs/Web/API/XMLSerializer/serializeToString) — düzenlenmiş SVG işaretlemesini kaydetme.

***

Kendi raster illüstrasyonunuz için [düzenlenebilir küçük resim hazırlayın](https://perfectvector.com/tr/clipart-to-svg), şekillerini inceleyin ve ana dosyayı saklayın. Metni ayrı ekleyin, ardından teslimden önce kayıtlı SVG'de kabul edilen satırları ve görünür yazıları doğrulayın.

## Explore

- [Read the HTML article](https://perfectvector.com/tr/blog/svg-text-wrap-tspan)
- [SVG.js: Çizim Alın, Yolu Düzenleyin, SVG Dışa Aktarın](https://perfectvector.com/tr/blog/svgjs-import-export-artwork.md)
- [Leaflet SVG İşaretçileri: Ucu iconAnchor ile Hizalayın](https://perfectvector.com/tr/blog/leaflet-svg-marker-anchor.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
