Text In A Circle

Text In A Circle Using CSS & JavaScript

In this article I will share the CSS & JS code to generate circle text from a HTML text element. This technique makes a span element for each letter and rotates it slightly. You can generate a circle text by adjusting the font site and circle radius.

Text In A Circle

Similar techniques have been implemented in online web applications like in the circle text generator in MockoFun.

So, let’s see how to write text in a circle using CSS and JavaScript.

CIRCLE TEXT CODE

In the circle text you can also use glyphs. Check out this emoji copy paste collection where you can copy/paste star symbol characters into your text. You can also use any text symbol (eg. a heart text symbol or arrow symbol)

CIRCLE TEXT CSS & JS

Let’s break down the steps to creating curved text or circle text using a little JS and CSS.

CIRCLE TEXT HTML CODE

HTML

<div>
  <fieldset>
    <label>Text:</label>
 <input type="text" class="text" value="CIRCLE TEXT">
    <label>Radius:</label>
 <input class="radius" type="range" min="100" max="1000" value="500">
  </fieldset>
</div><div class="curved-text">CIRCLE TEXT</div>

The HTML code is pretty straight forwards. The div.curved-text element is actually the only important one, because that’s where we will write our circle text.

The other div element simply contains the configuration options for the curved text:

  • input text for inputting the curved text content
  • radius slider for adjusting the radius of the circle text

CIRCLE TEXT CSS CODE

.curved-text{
 position:relative;
 display:inline-block;
 margin:0 auto;
 font-size:32px;
}.curved-text span{
 min-width:0.5em;
 text-align:center;
 padding:30px;
 margin:0px;
}

For creating the circle text effect, we will only use 2 CSS classes:

  • .curved-text CSS class used for the wrapper element where the curved circle text will reside
  • .curved-text span CSS class used for each individual letters that make up the circle text

CIRCLE TEXT JS CODE

import jquery from "https://cdn.skypack.dev/jquery@~3.5.1";
function updateCurvedText($curvedText, radius) {
  $curvedText.css("min-width", "initial");
  $curvedText.css("min-height", "initial");
  var w = $curvedText.width(),
    h = $curvedText.height();
  $curvedText.css("min-width", w + "px");
  $curvedText.css("min-height", h + "px");
  var text = $curvedText.text();
  var html = "";Array.from(text).forEach(function (letter) {
    html += `<span>${letter}</span>`;
  });
  $curvedText.html(html);var $letters = $curvedText.find("span");
  $letters.css({
    position: "absolute",
    height:`${radius}px`,
    // backgroundColor:"orange",
    transformOrigin:"bottom center"
  });
  
  var circleLength = 2 * Math.PI * radius;
  var angleRad = w/(2*radius);
  var angle = 2 * angleRad * 180/Math.PI/text.length;
  
  $letters.each(function(idx,el){
    $(el).css({
        transform:`translate(${w/2}px,0px) rotate(${idx * angle - text.length*angle/2}deg)`
    })
  });
}var $curvedText = $(".curved-text");
updateCurvedText($curvedText,500);function settingsChanged(){
  $curvedText.text($(".text").val());
  updateCurvedText($curvedText,$(".radius").val());
}$(".radius").on("input change",settingsChanged);
$(".text").on("input change",settingsChanged);

The JavaScript is where the actual magic of the circle text happens.

First we import the jQuery library. You could probably get away without using jQuery, but I just find it convenient in this case for manipulating the HTML elements of the circle text setup.

The updateCurvedText() function takes in two parameters:

  • $curvedText which is a reference to the curved text wrapper element
  • radius the radius for our curved/circle text

Let’s see how this function works and how it creates our circle text:

...
  $curvedText.css("min-width", "initial");
  $curvedText.css("min-height", "initial");
  var w = $curvedText.width(),
    h = $curvedText.height();
  $curvedText.css("min-width", w + "px");
  $curvedText.css("min-height", h + "px");
  var text = $curvedText.text();
...

First, we re-set the min-width and min-height properties of our wrapper. This will allow us to actually measure the dimensions of our text in its normal straight form.

We do this because when we curve the text, we will end up with an element that we don’t want to be smaller than the original text. Otherwise, the element will jump all over the place when adjusting it’s radius.

We store the width (w), height (h) and also the text for later use.

...
  var html = "";Array.from(text).forEach(function (letter) {
    html += `<span>${letter}</span>`;
  });
  $curvedText.html(html);
...

Next, we need to wrap each letter of the text we want to curve into span elements. We simply go over each character of the text and add a span element around it. Then we replace the content of our wrapper with the new HTML code.

Please notice that the span elements will use the CSS code we defined earlier.

Just a few more steps and we are done!

...
  var $letters = $curvedText.find("span");
  $letters.css({
    position: "absolute",
    height:`${radius}px`,
    transformOrigin:"bottom center"
  });
...

Curved Text Elements

Imagine that each letter of our curved text becomes a rectangle element with the height set to the radius value of our desired circle text. We also need to set the transformOrigin to the bottom center of the rectangle, because we will want to rotate each letter by a certain angle to distribute the letters on a circle.

The image above is just to give you an idea of how the elements are transformed. We add the position:absolute CSS style, because we want all the letters to initially overlap. We want this because we want to rotate those rectangles around the same origin point.

And now, the last step — the actual rotation for writing text in a circle:

...
  var circleLength = 2 * Math.PI * radius;
  var angleRad = w/(2*radius);
  var angle = 2 * angleRad * 180/Math.PI/text.length;
  
  $letters.each(function(idx,el){
    $(el).css({
        transform:`translate(${w/2}px,0px) rotate(${idx * angle - text.length*angle/2}deg)`
    })
  });
...

Let me explain the code:

The circleLength variable is not actually used. It’s just a reminder of how to calculate the length of the circle.

This helps us determine the angle of a circle slice, when we have the length of the slice edge. We simply divide this length by 2 times the radius of the whole circle.

The length or the circle slice in our case is the width of the original text. The idea here is that no matter how you bend text, the letters combined width will always be the same.

Using the formula mentioned angleRad = w/(2*radius) gives us an angle in radians. CSS likes working with degrees though.

So, we simply need to transform the radians to degrees. We then divide this by the number of letters in the text. This will give us the angle step we need to rotate each letter.

With the angle calculated, we apply the CSS to translate each letter to the center of the word, and then rotate each letter with the same angle multiplied by the letter’s index in the word.

When we rotate each letter, because we start at the angle value 0, we will end up with a curved text that starts on top.

That’s fine, but it looks a lot better if the text in a circle is centered and balanced to the left and right.

So, we simply need to subtract text.length*angle/2 each time we rotate a letter.

Circle Text / Curved Text CSS & JS

In Conclusion

Now you know how to make curved text or circle text in CSS and JS.

If you don’t want to start coding this yourself, you can use the Codepen snippet, or even better, you can use the MockoFun circle text generator. It’s FREE and it gives you lots of flexibility, over 1500 different fonts, changing colors and sizes with just a few clicks.

FOLLOW ME ON TWITTER: https://twitter.com/codingdudecom

John Negoita

View posts by John Negoita
I'm a Java programmer, been into programming since 1999 and having tons of fun with it.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top