Текст SVG foreignObject: пропавшие подписи при экспорте
Исправьте подписи SVG, которые видны в браузере, но исчезают при экспорте. Сравните foreignObject с обычным текстом SVG, проверьте пространства имён и сохраните иллюстрацию.
На этой странице
- Почему картинка сохраняется, а подпись исчезает
- Небольшая проверка: меняем только подпись
- Если подписи нет и в браузере
- Для экспорта draw.io преобразуйте подписи в исходнике
- Выберите формат текста с учётом получателя
- Где PerfectVector пригодится для иллюстрированной карточки
- Перед отправкой исправленного SVG
- Частые вопросы
- Источники
Если фигуры SVG сохраняются при экспорте, а подписи исчезают, проверьте, использует ли пропавшая подпись <foreignObject>. В нём может находиться HTML, который браузер успешно размещает, но целевой рендерер не поддерживает. Замените проблемную подпись обычными элементами SVG <text> и <tspan> либо выберите способ экспорта, сохраняющий её внешний вид.
Сначала откройте в браузере именно экспортированный файл. Если подписи нет и там, проверьте её пространство имён, границы и стили, прежде чем обвинять импорт. Сохраните исходную иллюстрацию: трассировать всё изображение незачем, если сломался только контейнер текста.
Почему картинка сохраняется, а подпись исчезает
SVG может сочетать обычные фигуры с содержимым другого пространства имён XML. Гора, нарисованная через <path>, и солнце через <circle> — собственные элементы SVG. Абзац внутри <foreignObject> может быть HTML со своими правилами переноса и размещения. Справочник MDN по foreignObject описывает это различие.
Поэтому расширение .svg не обещает, что все части используют одни и те же возможности отрисовки. Целевое приложение может нарисовать гору и солнце, но пропустить HTML-абзац. Изменение цвета текста или увеличение разрешения экспорта не добавит этому рендереру поддержку HTML.
| Что вы видите | Что проверить дальше | Вероятное исправление |
|---|---|---|
| Фигуры видны в обоих случаях; подписи — только в браузере | Использует ли пропавшая подпись foreignObject? | Заменить эту подпись или сменить способ экспорта |
| HTML-подписи нет и в браузере | Пространство имён XHTML, явные границы, видимость и стили | Сначала исправить HTML-контейнер |
| Обычный текст SVG отображается другим шрифтом или с другой длиной строки | Доступность шрифта и выбранные положения строк | Решить проблему шрифтов или перевести окончательный текст в контуры |
| Пропала большая часть рисунка | Область просмотра, обрезка и структура документа | Выполнить более общие проверки пустого SVG |
Небольшая проверка: меняем только подпись
Мы сделали карточку SVG размером 480 × 240 с контуром, кругом и словами «Keep artwork and labels separate.». Первый файл использует HTML-подпись. Второй сохраняет те же фигуры и заменяет только подпись обычным текстом SVG с тремя явно заданными строками.
В браузерном просмотре обе подписи появились. Преобразование тех же файлов в PNG через sharp 0.34.4 с поставляемой вместе с ним librsvg 2.61.1 дало результат ниже: HTML-подпись исчезла, а обычная SVG-подпись сохранилась. Вывод с HTML-подписью также попиксельно совпал с контрольным файлом, где подпись удалена. Это проверка этих файлов и этой версии рендерера, а не заключение о совместимости всех редакторов.

Исходный файл достаточно мал, чтобы воспроизвести его. Сохраните это как html-label.svg и откройте в браузере:
<svg xmlns="http://www.w3.org/2000/svg"
width="480" height="240" viewBox="0 0 480 240">
<rect width="480" height="240" rx="20" fill="#f5f1e7"/>
<path d="M40 135Q90 15 140 135Z" fill="#087f75"/>
<circle cx="90" cy="95" r="18" fill="#f4bc45"/>
<foreignObject x="180" y="70" width="230" height="110">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font: 28px/1.25 Arial, sans-serif; color: #172b34;">
Keep artwork and labels separate
</div>
</foreignObject>
</svg>Для второго файла замените весь элемент foreignObject следующей подписью и сохраните как native-label.svg:
<text x="180" y="96" font-family="Arial, sans-serif"
font-size="28" fill="#172b34">
<tspan x="180" dy="0">Keep artwork</tspan>
<tspan x="180" dy="35">and labels</tspan>
<tspan x="180" dy="35">separate</tspan>
</text>Значение x начинает каждую строку в одном горизонтальном положении. Значения dy сдвигают последующие строки вниз. Здесь намеренно отказались от автоматического переноса HTML: автор выбирает разрывы строк и проверяет, что текст помещается. MDN описывает позиционирование tspan, а librsvg перечисляет поддерживаемые элементы SVG, включая text и tspan.
Откройте оба файла через реальный способ передачи — например, ваш конвертер изображений или генератор PDF. Сравнивайте сохранённый результат, а не только просмотр исходника. Совпадение размеров с примером не гарантирует совпадение шрифтов на другом компьютере.
Если подписи нет и в браузере
Проверяйте сохранённый файл .svg, а не только страницу, которая его создала. Встроенный SVG внутри HTML и отдельный документ SVG имеют разные контексты разбора.
Пример явно помещает div в http://www.w3.org/1999/xhtml. MDN отмечает, что это объявление пространства имён обязательно для HTML-содержимого в отдельном документе SVG, хотя встроенный HTML-пример может его опускать. Если вы создаёте элементы в JavaScript, используйте соответствующее пространство имён для дочернего HTML-элемента; div, созданный в пространстве имён SVG, не является контейнером HTML-абзаца.
Затем проверьте следующие части подписи:
- Задайте для
foreignObjectявные положительные значенияwidthиheight, соответствующие нужной области подписи. - Разместите его координаты
xиyвнутри видимого рисунка, оставив место всем строкам. - Проверьте
display,visibility, непрозрачность и цвет текста контейнера и его дочерних элементов. - Убедитесь, что экспортированный файл содержит нужные стили и не зависит от таблицы стилей окружающей веб-страницы.
В примере все стили подписи встроены, а блок имеет ширину 230 и высоту 110 единиц. Это исключает внешний CSS как переменную. Но не делает foreignObject совместимым с рендерером, у которого этой возможности нет.
Для экспорта draw.io преобразуйте подписи в исходнике
Если у вас сохранилась редактируемая схема, исправьте экспорт подписей в ней, прежде чем править XML вручную. Текущая документация draw.io об экспорте предлагает Convert Labels to SVG для поддерживаемых форматированных подписей: выберите фигуры или соединители, откройте раздел Advanced на вкладке Text и включите флажок.
У этой опции есть ограничения. Документация исключает из преобразования подписи со структурами вроде таблиц, списков, ссылок или фоновых цветов. Если опция недоступна, другой документированный путь — отключить Formatted Text и Word Wrap; возможно, потребуется вручную вставить переносы строк и заново проверить размещение.
Экспортируйте новую копию и откройте её в принимающем приложении. Скрытие предупреждения «Text is not SVG» не преобразует подпись. Встраивание шрифта решает зависимость от шрифта, но не отсутствие поддержки HTML-разметки.
В иллюстрированной схеме храните импортированную графику отдельно от подписей. Руководство по пользовательским фигурам SVG в draw.io разбирает графическую часть этого процесса.
Выберите формат текста с учётом получателя
Обычный текст SVG полезен, когда получателю нужно редактировать слова, но он всё ещё зависит от доступных шрифтов. Если подпись отображается другим шрифтом, выполните проверки шрифтов SVG, а не считайте это той же проблемой пропавшего контейнера.
| Требование к передаче | Практический выбор | Что проверить |
|---|---|---|
| Редактируемый текст | Обычный text с продуманными положениями строк | Шрифт, длины строк и принимающий редактор |
| Фиксированная форма букв | Перевести окончательный текст в контуры в исходном редакторе | Правильный вид; сохранить редактируемый оригинал |
| Сложная разметка только для браузера | Оставить foreignObject, если такой браузерный способ отвечает задаче | Реальный встроенный или отдельный файл |
| Только внешний вид | Экспортировать PNG рендерером, который показывает весь дизайн | Размеры в пикселях и самый мелкий текст при конечном размере |
Перевод в контуры работает лишь тогда, когда исходный инструмент видит буквы и может преобразовать их. Открытие уже неполного экспорта и преобразование оставшихся объектов не восстановит слова, которых нет в импортированном документе. PNG сохраняет пиксели, поэтому не подходит, если получателю нужны редактируемые слова или векторные контуры резки.
Где PerfectVector пригодится для иллюстрированной карточки
Если иллюстрация карточки есть только в PNG или JPG, процесс преобразования клипарта в SVG в PerfectVector позволяет подготовить векторный вариант этой графики. Оставляйте слова отдельным текстовым элементом в редакторе дизайна. Проверьте края иллюстрации и внутренние промежутки, добавьте подпись и протестируйте собранный файл в целевом рендерере.
Руководство по векторизации изображений объясняет превращение пикселей в контуры. PerfectVector не исправляет HTML-подписи в SVG. Если у иллюстрации уже хорошие контуры, сохраните их и измените только проблемную подпись. Скриншот с пропавшей подписью не содержит букв для восстановления, а трассировка видимых букв создаст фигуры, а не редактируемые слова.
Перед отправкой исправленного SVG
- Заново откройте экспортированную копию в браузере и целевом приложении.
- Убедитесь, что видна каждая подпись, включая последнюю строку.
- Проверьте, что иллюстрация не сдвинулась и не изменила размер.
- Проверьте шрифты или просмотрите текст в контурах при нужном размере.
- Сохраните редактируемый исходник рядом с копией для передачи.
Частые вопросы
Почему текст SVG виден в Chrome, но исчезает при экспорте PNG? Подпись может быть HTML внутри foreignObject, тогда как PNG-рендерер поддерживает другой набор возможностей SVG. Проверьте разметку пропавшей подписи и проведите версию с обычным текстом SVG через тот же способ экспорта.
Добавление пространства имён XHTML исправляет любой экспорт foreignObject? Нет. Оно исправляет пространство имён HTML-содержимого в отдельном SVG. Целевое приложение всё ещё должно поддерживать это содержимое, а подписи нужны подходящие размеры и видимые стили.
Может ли tspan переносить текст как HTML-абзац? Пример использует явные строки и вертикальные смещения. Он не воспроизводит размещение HTML-абзаца. Выберите переносы под доступное пространство и проверьте их со шрифтом целевого приложения.
Стоит ли векторизовать всю карточку для восстановления подписей? Сохраните существующие контуры и заново создайте подпись из исходного текста. Векторизуйте только графику, существующую в пикселях. Трассированные буквы — это геометрия, поэтому редактируемые слова не сохраняются.
Источники
- MDN — foreignObject — Определяет содержимое другого пространства имён, геометрические атрибуты и пространство имён XHTML в отдельном SVG.
- MDN — tspan — Объясняет позиционирование частей обычного текста SVG.
- draw.io — Exported SVG text problems — Описывает преобразование в обычные SVG-подписи, ограничения форматирования и альтернативные настройки экспорта.
- GNOME — Librsvg supported SVG and CSS features — Перечисляет поддерживаемые рендерером элементы и атрибуты.
Если ваша иллюстрация всё ещё растровая, подготовьте клипарт в SVG, проверьте его фигуры и добавьте текст отдельно. Проверьте оба компонента в экспортированном файле перед передачей.
Ещё из блога

SVG-изображения Graphviz: переносимая графика узлов
Добавьте SVG-графику в узел Graphviz, проверьте ссылку на изображение и сравните полный комплект ресурсов, перенесенную диаграмму и автономную копию для передачи.

SVG в Matplotlib: график и логотип в виде контуров
Экспортируйте график Matplotlib в SVG, добавьте отдельные контуры логотипа через svgutils и проверьте итоговый файл на встроенные пиксели, размещение и изменения шрифтов.