PerfectVector
Автор: Irene Kim

Обтекание SVG текстом HTML с помощью CSS float

Расположите абзац HTML вокруг прозрачного SVG с CSS shape-outside. Повторите пример float и проверьте две ширины, альфа-канал и порядок текста.

9 мин чтения
На этой странице

Чтобы текст HTML обтекал силуэт SVG, задайте изображению float, явные размеры и shape-outside с URL прозрачного SVG. Добавьте shape-margin для отступа от контура. Абзац остаётся обычным HTML; SVG предоставляет изображение для расчёта границы обтекания.

Это работает снаружи SVG. Способ не переносит строки элемента SVG text и не изгибает буквы вдоль контура. В примере ниже используются собственный прозрачный силуэт и полный абзац без ручной расстановки слов и вставленных переносов строк.

Выберите нужную задачу размещения текста

Желаемый результатПодходящая отправная точка
Абзац страницы обтекает иллюстрацию неправильной формыИзображение float с CSS shape-outside, как здесь
Многострочная подпись укладывается в ширину SVGПеренос текста SVG с tspan
Форматированное содержимое HTML находится внутри SVGHTML внутри SVG с foreignObject
Буквы следуют изогнутой базовой линииТекст SVG вдоль контура

Файл SVG не содержит компоновку окружающего абзаца. Копирование изображения в другой документ не перенесёт эту связь HTML/CSS.

1. Задайте float размер и прозрачное изображение

Справочник MDN по shape-outside описывает свойство как способ изменить область float, которую обтекает соседнее строчное содержимое. При значении по умолчанию область следует внешней рамке отступов float. URL изображения вместо этого выводит форму из альфа-канала, то есть прозрачности.

Видимый цвет не задаёт границу. Непрозрачный белый фон тоже имеет альфа-значение и может превратить иллюстрацию в прямоугольник для обтекания. Проверяйте сам файл, а не только белый рисунок на белой странице. Сохраняйте прозрачность за пределами силуэта.

Сохраните этот собственный рисунок как silhouette.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="180" viewBox="0 0 150 180">
  <path fill="#2f6977" d="M30 20 C80 5 135 35 138 75 C140 110 105 140 65 150 L45 170 L37 142 C8 125 8 85 22 62 C10 47 16 31 30 20 Z"/>
</svg>

Его собственный размер — 150 × 180, и CSS использует те же ширину и высоту. Одинаковое соотношение сторон упрощает проверку связи между отображаемым рисунком и изображением для расчёта формы.

В этом примере изображение декоративное, поэтому атрибут alt пустой. Для значимого изображения задайте подходящую текстовую альтернативу на своей странице: само обтекание не передаёт его смысл.

2. Запустите полный пример HTML

Сохраните этот код как index.html рядом с silhouette.svg:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>HTML text around an SVG silhouette</title>
<style>
* { box-sizing: border-box; }
.sample {
  display: flow-root;
  color: #183a42;
  font: 16px/24px Arial, sans-serif;
}
.sample p { margin: 0; }
.sample img { float: left; width: 150px; height: 180px; margin: 0; }
.sample.narrow { width: 360px; }
.sample.wide { width: 520px; }
.sample.contour img {
  shape-outside: url("silhouette.svg");
  shape-image-threshold: 0.5;
  shape-margin: 10px;
}
</style>
<div class="sample narrow contour">
  <img src="silhouette.svg" alt="">
  <p>The neighborhood library keeps a small garden beside its reading room. Volunteers label the seedlings, share spare pots, and record which plants attract insects. A curved illustration can sit beside this paragraph while the browser keeps the words in their original order. As the column becomes narrower, the same sentence needs different line breaks. The artwork remains the same size in this example, so the available room beside it changes. After the illustration ends, the paragraph can use the full column again. Editors can revise this text without moving individual words or drawing separate text lines. The layout belongs to the web page, while the SVG supplies the visible silhouette.</p>
</div>
</html>

Раздавайте папку через HTTP, например командой python -m http.server 8000, и откройте http://localhost:8000/index.html. Тогда у двух файлов будет один источник. Локальный файловый URL — не тот способ загрузки, который проверялся здесь.

Замените class="sample narrow contour" на class="sample narrow" для сравнения с обычным прямоугольным обтеканием. Замените narrow на wide, чтобы проверить колонку 520 пикселей. Абзац и изображение не меняются.

Справочник по display объясняет, что flow-root создаёт блочный контекст форматирования. Здесь он удерживает изображение float внутри образца. Он не размещает слова: это делает строчная компоновка браузера.

Реальное обтекание в браузере вокруг прямоугольного float и альфа-контура SVG в колонках 360 и 520 пикселей
Четыре реальные компоновки HTML используют одинаковые исходные SVG и абзац. Контурные варианты добавляют shape-outside и отступ формы 10px; слова не расставлены вручную.

3. Проверьте отрисованные строки при нескольких ширинах

Мы запустили четыре видимых образца в Chromium 155 с Arial 16px и высотой строки 24px. Изображение оставалось 150 × 180px, а фиксированная ширина содержимого колонок была 360px и 520px. Оба контурных образца использовали shape-margin: 10px и shape-image-threshold: 0.5.

Фактический образецОтрисованные строки текстаНачало первой строкиВысота текста
rectangle-narrow18150px432px
rectangle-wide13150px312px
contour-narrow18115.5px432px
contour-wide12115.5px288px

Узкий контур изменил переносы, не сократив общее число строк. В широкой колонке контурный вариант использовал на одну строку меньше прямоугольного контрольного.

Мы измерили нативные прямоугольники DOM Range для каждого слова и сгруппировали их по вертикальному положению. Это измерения отрисованных строк текста, а не доступ к внутренним объектам строк браузера. Мы также проверили вычисленные настройки float и формы, размеры загруженного изображения и альфа-значения в настоящем SVG.

При обеих ширинах некоторые контурные строки начинались левее границы исключения 150px прямоугольного float. После изображения текст снова занимал всю колонку. Эти наблюдения показывают, что проверенный контур влиял на реальную компоновку, а не только на вид снимка.

Точные строки и координаты зависят от шрифта, браузера, абзаца, изображения и ширины. Замена предложения или загрузка другого шрифта может их изменить. Проверяйте своё содержимое при узкой и широкой колонке, а не фиксируйте эти числа как константы дизайна.

4. Разделяйте отступ формы, альфа-канал и загрузку

shape-margin расширяет форму обтекания, оставляя место между ней и текстом. Значение 10px здесь — выбор компоновки, а не измеренный минимальный зазор от каждого видимого символа до каждой точки иллюстрации.

Спецификация CSS Shapes сохраняет обычную блочную модель и обрезает действие формы по рамке внешних отступов float. Большой отступ формы не увеличивает CSS-блок изображения. Если дизайну нужно больше места, проверяйте также размеры float и обычные отступы.

shape-image-threshold выбирает порог альфа-канала для извлечения формы изображения. Исходный образец имеет полностью прозрачную внешнюю область и непрозрачный рисунок в центре. Мягкие тени и полупрозрачные края требуют осознанного порога и визуальной проверки; изменение порога не делает непрозрачный фон прозрачным.

URL изображения также должен подходить для загрузки формы. CSS Shapes задаёт запрос CORS для URL изображений и отказывается от пользовательской формы при ошибке загрузки. Размещение SVG рядом со страницей устраняет зависимость от другого источника в этом примере. Если файл хранится на CDN, настройте ответ CORS того сервера и проверьте запрос и компоновку. Видимость изображения в элементе img сама по себе не доказывает успех запроса формы.

5. Сохраните порядок текста и проверьте готовую страницу

Все четыре проверенных абзаца содержали совершенно одинаковый текст в одном текстовом узле, без элементов br и позиционирования отдельных слов. CSS менял визуальные переносы, не переписывая порядок DOM абзаца. Мы не проводили сеанс с программой экранного доступа и не заявляем аудит доступности на основе этой проверки исходника.

Сохраняйте читаемость абзаца при отсутствии изображения или изменении компоновки. В очень узкой колонке простой вариант с изображением над текстом может читаться легче, чем тонкая полоска текста сбоку. Проверяйте собственные точки перестроения и содержимое вместо уменьшения текста ради эффекта контура.

Float по-прежнему резервирует CSS-блок. Обтекание по форме не превращает его в универсальное препятствие, которое текст огибает со всех сторон. В этом примере с левым float соседний текст идёт справа, затем продолжается снизу.

Исправляйте симптом в его источнике

СимптомПроверка и восстановление
Текст следует прямоугольникуПодтвердите активный float, заданные размеры, загрузку URL формы и прозрачное окружение в источнике.
Текст перекрывает видимую иллюстрациюСравните отображаемый SVG и URL формы, размеры и соотношения сторон. Проверьте порог альфа-канала и отступ формы.
Изображение видно, а контура нетПроверяйте запрос изображения формы и CORS отдельно от запроса img. До подключения CDN проверьте пример с одним источником.
Дочерний элемент flex или grid не работает как floatОставьте float и абзац в контейнере обычного потока, как в примере, а не делайте само изображение элементом flex или grid.
Узкий абзац трудно читатьУменьшите изображение или перенесите его над текстом на подходящей точке перестроения, затем повторно проверьте настоящий абзац.
Подписи SVG всё ещё не переносятсяИспользуйте процесс текста внутри SVG из таблицы выше. Shape-outside меняет соседний поток HTML, а не компоновку текста SVG.

Если подходящая плоская иллюстрация осталась только в растре и нужен редактируемый силуэт, процесс преобразования клипарта в SVG PerfectVector поможет получить кандидат. Сравните очертание и прозрачное окружение с источником, затем проверьте настоящий URL SVG на странице. Прозрачный растр тоже может задавать CSS-форму по изображению; SVG не обязателен лишь для включения обтекания по альфа-каналу.

Сохраняйте чистый существующий SVG, если он есть. Векторизация не строит окружающую компоновку HTML, не сохраняет за вас семантику абзаца и не гарантирует определённый результат обтекания в конкретном браузере.

Частые вопросы

Переносит ли shape-outside текст внутри SVG? Нет. Этот пример меняет строчный поток HTML рядом с изображением float. Подписи SVG, встроенный в SVG HTML и текст вдоль контура — другие задачи компоновки.

Почему внешне прозрачный SVG всё ещё обтекается как прямоугольник? Проверьте непрозрачный фон файла, ошибку запроса изображения формы, отсутствие размеров float или контекст, в котором float не действует. Белые пиксели не равны прозрачным.

Нужно ли сначала преобразовать PNG в SVG? Не ради одного обтекания по альфа-каналу. Подходящий прозрачный растр тоже задаёт форму. Используйте SVG, когда нужны редактируемый рисунок или другие свойства вектора.

Останутся ли переносы одинаковыми при любом размере экрана? Нет. На строки влияют доступная ширина, метрики шрифта, текст, размеры изображения и компоновка браузера. Проверяйте настоящее содержимое при нескольких ширинах.

Источники

  1. MDN shape-outside — Описывает области float и формы изображения по альфа-каналу.
  2. MDN shape-margin — Определяет добавочное пространство вокруг формы обтекания.
  3. MDN shape-image-threshold — Определяет порог альфа-канала для форм изображения.
  4. CSS Shapes Module Level 1 — Задаёт ограничения блока float, загрузку изображений и поведение CORS.
  5. MDN display и flow-root — Объясняет контекст форматирования для удержания float.

Если редактируемого рисунка нет, подготовьте кандидат SVG из клипарта, проверьте силуэт и прозрачность и убедитесь в правильной компоновке настоящего абзаца на странице при поддерживаемых ширинах.

Ещё из блога

PerfectVector

Начните с более чистого SVG,
который проще редактировать

Без банковской карты