Как сделать текст по кругу

Как сделать текст по кругу

Проблема

Хотя это не самый распространенный эффект, иногда возникает необходимость вывести короткую строку текста вдоль дуги окружности. Но, сталкиваясь с таким требованием, мы осознаем, что помощи от CSS ждать не приходится.

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

как сделать текст по кругу

 

Решение

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

Но это не только ужасно грязный трюк, он вдобавок непомерно раздувает код и добавляет на страницу десятки DOM-элементов, не имеющих практической ценности. Идеального способа достичь желаемого результата с помощью чистого CSS не существует, но мы можем с легкостью создавать подобные дизайны, используя немного  строкового SVG.

Формат SVG всегда поддерживал отображение текста вдоль любого пути, а дуги окружности — это всего лишь один из вариантов формы пути. Почему бы не попробовать? Простейший способ нарисовать текст по кругу с помощью SVG — поместить его в элемент  <textPath> внутри элемента  <text> . Элемент  <textPath> также ссылается на элемент  <path> , определяя форму пути по его идентификатору.

Текст внутри строкового SVG также наследует большую часть стилизации шрифтов (за исключением  line-height , так как это в SVG задается вручную), поэтому, в отличие от решений, включающих внешние изображения в формате SVG, в данном случае о стилях можно не беспокоиться. Предположим, мы хотим вывести фразу circular reasoning works because по кругу, чтобы она формировала замкнутую окружность, как на рисунке.

Читайте также  Как настроить подчеркивание


Начнем с добавления строкового SVG внутри на шего элемента HTML, а также с определения пути, описывающего окружность: к сожалению, <textPath> работает только с элементами <path>, поэтому для создания нашей окружности у нас не получится использовать гораздо более понятные элемент <circle>.
SVG
<div class=»circular»>
<svg viewBox=»0 0 100 100″>
<path d=»M 0,50 a 50,50 0 1,1 0,1 z»
id=»circle» />
</svg>
</div>
Обратите внимание, что мы определили габариты посредством  viewBox , а не с помощью атрибутов  width и  height . Это позволяет настраивать систему координат и соотношение сторон рисунка, вместо того чтобы всегда использовать четко определенный размер.

Так не только намного компактнее; это экономит несколько строк CSS-кода, поскольку нам больше не приходится определять равную 100% ширину и высоту для элемента  <svg> — он сам подстраивается под размер своего контейнера.

Если вы не понимаете синтаксис пути, не беспокойтесь. Его вообще мало кто понимает, и даже те, кто был посвящен в таинство синтаксиса пути в SVG, чаще всего забывают о нем в течение нескольких минут. Если вам интересно, то вот три команды, которые включает этот невероятно загадочный синтаксис:
M 0,50 : перейти в точку (0,50);
a 50,50 0 1,1 0,1 : нарисовать дугу из точки, в которой вы находитесь в данный момент, в точку, которая находится на  0 единиц правее и на  1 единицу ниже вашей текущей позиции. Радиус этой дуги равен  50 , как по горизонтали, так и по вертикали. Из двух возможных углов выбрать  наибольший и из двух возможных дуг выбрать ту, что находится справа от двух точек, а не слева;
z : закрыть путь прямым отрезком.
Пока что наш путь представляет собой всего лишь черную окружность.

Читайте также  Полосатая заливка строк текста

 

Мы добавляем текст с помощью элементов  <text> и  <textPath> и связываем его с нашей окружностью посредством свойства  xlink:href , как в следующем фрагменте кода:
SVG
<div class=»circular»>
<svg viewBox=»0 0 100 100″>
<path d=»M 0,50 a 50,50 0 1,1 0,1 z»
id=»circle» />
<text><textPath xlink:href=»#circle»>
circular reasoning works because
</textPath></text>
</svg>
</div>
Как видно на рисунке, хотя нам предстоит еще немало потрудиться, чтобы сделать этот текст привлекательным и читабельным, мы уже достигли результата, которого с помощью чистого CSS не сумели бы добиться и за миллион лет!

 

Следующим шагом будет удаление черной заливки из нашего кругового пути. Мы вообще не хотим, чтобы какая-либо часть нашей окружности была видна; ее единственное предназначение — служить направляющей для нашего текста. Этого можно добиться несколькими разными способами: например, поместив наш контур в элемент  <defs> (придуманный как раз для этой цели).

Однако при создании нашего эффекта мы хотим минимизировать объем SVG-разметки, поэтому применим решение из CSS, а именно  fill: none: .circular path { fill: none; } Теперь, когда черный круг исчез, мы можем внимательнее изучить остальные недостатки. Самая большая проблема заключается в том, что большая часть текста находится за пределами SVG-элемента и обрезается им.

Чтобы исправить этот дефект, нужно сделать контейнер меньше и применить к SVG-элементу  overflow: visible, чтобы он не обрезал никакое содержимое за пределами своего окна просмотра:
.circular {
width: 30em;
height: 30em;
}
.circular svg {
display: block;
overflow: visible;
}
Результат вы видите на рисунке. Это почти то, что нам нужно, но часть текста все равно обрезается.

 

Причина в том, что на обтекание влияют только габаритные размеры SVG-элемента, но не то, насколько содержимое выходит за пределы окна просмотра. Следовательно, тот факт, что какой-то текст переливается через края контейнера, создаваемого элементом  <svg> , не заставляет этот SVG-элемент сдвинуться вниз. Нам придется сделать это вручную, с помощью поля:
.circular {
width: 30em;
height: 30em;
margin: 3em auto 0;
}
.circular svg {
display: block;
overflow: visible;
}
Вот и все! Результат выглядит в точности как на рисунке выше, и распознавание текста программами чтения экрана проходит без сложностей. Если у нас только один фрагмент текста, нарисованного вдоль дуги окружности (скажем, на логотипе веб-сайта), то работа закончена.

Читайте также  Лигатуры в CSS

Но если нужно  применить подобную стилизацию к нескольким элементам на странице, то хотелось бы избежать повторения всей этой разметки SVG. Для чего можно написать короткий сценарий, который будет автоматически генерировать необходимые SVG-элементы, встречая в разметке нечто подобное:
HTML
<div class=»circular»>
circular reasoning works because
</div>

Наш код будет проходить по всем элементам с классом  circular , удаляя их текст и сохраняя его в переменной, а также добавляя необходимые SVG-элементы:

 

JS
$$(‘.circular’).forEach(function(el) {
var NS = «http://www.w3.org/2000/svg»;
var xlinkNS = «http://www.w3.org/1999/xlink»;
var svg = document.createElementNS(NS, «svg»);
var circle = document.createElementNS(NS, «path»);
var text = document.createElementNS(NS, «text»);
var textPath = document.createElementNS(NS, «textPath»);
svg.setAttribute(«viewBox», «0 0 100 100»);
circle.setAttribute(«d», «M0,50 a50,50 0 1,1 0,1z»);
circle.setAttribute(«id», «circle»);
textPath.textContent = el.textContent;
textPath.setAttributeNS(xlinkNS, «xlink:href», «#circle»);
text.appendChild(textPath);
svg.appendChild(circle);
svg.appendChild(text);
el.textContent = »;
el.appendChild(svg);
});

ПОПРОБУЙТЕ САМИ!
http://play.csssecrets.io/circular-text

 

 

 

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Плюсануть
Поделиться

Об авторе

admin administrator

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: