Welcome to a tutorial on how to create responsive circles with CSS, and add text to them. Once upon a time in the Stone Age of the Internet, we literally have to use circle images and there are no alternatives. But it is a total breeze to create circles with modern CSS.
To create a responsive circle with text:
- Start with 2 containers –
<div class="circle"><div class="txt">TEXT</div></div>
. - Create the responsive circle:
.circle { with: 20%; border-radius: 50%; background: red; }
.circle::after { content: ""; display: block; padding-bottom: 100%; }
- Center the text in the circle.
.circle { position: relative; line-height: 0; }
.circle .txt { position: absolute; bottom: 50%; width: 100%; text-align: center; }
Yep, that’s all. But how does it work? Let us walk through a few of those tricks and examples in this guide – Read on!
ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TLDR – QUICK SLIDES
Fullscreen Mode – Click Here
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
RESPONSIVE CSS CIRCLES WITH TEXT
So, just what kind of sorcery is going on behind a CSS responsive circle? Let us walk through it step-by-step.
PART 1) BASIC FIXED CIRCLE
<style>
.circle {
/* (A) SQUARE - SAME WIDTH & HEIGHT */
width: 200px; height: 200px;
/* (B) CIRCLE - 50% RADIUS */
border-radius: 50%;
/* (C) COSMETIC - BACKGROUND COLOR */
background: #bcd6ff;
}
</style>
<div class="circle"></div>
- It is no secret, we define the same
width
andheight
to create a square. - Then, just add
border-radius: 50%
. This effectively turns the square into a circle.
PART 2) RESPONSIVE CIRCLE
<style>
/* (A) PERCENTAGE WIDTH & BORDER RADIUS */
.rcircle {
width: 20%; border-radius: 50%;
background: #bcd6ff;
}
/* (B) USE ::AFTER TO CREATE MATCHING HEIGHT */
/* credit - https://spin.atomicobject.com/2015/07/14/css-responsive-square/ */
.rcircle::after {
content: "";
display: block;
padding-bottom: 100%;
}
</style>
<div class="rcircle"></div>
- To create a responsive circle, we use the same
border-radius: 50%
trick, but set a percentagewidth
instead. - Now, we need to set a matching
height
, butheight: 20%
will not matchwidth: 20%
– It will be20%
height of<body>
instead. Thankfully, all it takes is a simple trick. Use::after
to add an empty block withpadding-bottom: 100%
.
P.S. You can use max-width
and/or max-height
to limit how much the circle can “grow”.
PART 3) RESPONSIVE CIRCLE WITH TEXT
<style>
.rcircle {
/* (A) PERCENTAGE WIDTH & BORDER RADIUS */
width: 20%; border-radius: 50%;
background: #bcd6ff;
/* (B) NECESSARY TO POSITION TEXT BLOCK */
line-height: 0;
position: relative;
}
/* (C) MATCH HEIGHT */
.rcircle::after {
content: "";
display: block;
padding-bottom: 100%;
}
/* (D) TEXT BLOCK */
.rcircle .txt {
/* (D1) CENTER TEXT IN CIRCLE */
position: absolute; bottom: 50%;
width: 100%; text-align: center;
/* (D2) COSMETICS */
font-family: Arial, Helvetica, sans-serif;
font-weight: 700;
}
</style>
<div class="rcircle">
<div class="txt">Foo Bar!</div>
</div>
- Take note, we now add a block of text
<div class="txt">TEXT</div>
inside the circle. - (A & C) You already know these, create a responsive circle.
- (B) The text will add some height to the circle, turning it into an oval. We “remove it” with
line-height: 0
. - Lastly, center the text in the circle.
- (B & D1) Set the container to
position: relative
, set the text toposition: absolute
. - (D1)
bottom: 50%
will vertically center the text block inside the circle,width: 100%
andtext-align: center
will center it horizontally.
- (B & D1) Set the container to
EXTRA BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
EXTRA) “3D SPHERE” WITH GRADIENT & SHADOW
<style>
.rsphere {
/* (A) PERCENTAGE WIDTH & BORDER RADIUS */
width: 20%; border-radius: 50%;
/* (B) FAKE 3D SPHERE */
/* http://www.colorzilla.com/gradient-editor/ */
background: linear-gradient(135deg, #a7cfdf 0%,#23538a 100%);
/* https://html-css-js.com/css/generator/box-shadow/ */
box-shadow: inset -8px -7px 4px 0px rgba(0,0,0,0.3);
}
/* (C) MATCH HEIGHT */
.rsphere:after {
content: "";
display: block;
padding-bottom: 100%;
}
</style>
<div class="rsphere"></div>
Well, this is the same responsive circle, but with a gradient background and box shadow – This is a nice trick for you guys who want to create “fake 3D spheres”.
REFERENCES & LINKS
- CSS Border Radius on MDN
- CSS Gradient on MDN
- Gradient generator – Generate your CSS gradients here quickly.
TUTORIAL VIDEO
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!
Hey there..
Thanks for giving me a head start. To keep larger texts in shape i used a disabled textarea. To make the text fit to the circle i used size and padding.
EDIT: HTML TAGS STRIPPED BY SPAM FILTER, I AM GUESSING YOUR HTML LOOKS LIKE THIS
Thanks for sharing. The simpler way is to just give the text a relative unit.
But this may still run into a clipped text problem and legibility issues.
Thanks, helped a lot.