Vertically and horizontally centering text in circle in CSS (like iphone notification badge)

CssCross BrowserGeometryCss Shapes

Css Problem Overview


I'm looking for a way of to do a cross-browser iphone-like badge in CSS3. I'd obviously like to use one div for this, but alternative solutions would be fine. The important factor is that it needs to be horizontally and vertically centered in all browsers.

An interesting design issue about these notifications is that they cannot have a specified width (height is fixed) - they should be able to handle [in ascii drawing] (1) and (1000), where (1000) is not a perfectly rounded circle, but instead looks more like a capsule.

EDIT: Additional constraints (from Steven):

  • No JavaScript
  • No mangling of the display property to table-cell, which is of questionable support status

Css Solutions


Solution 1 - Css

Horizontal centering is easy: text-align: center;. Vertical centering of text inside an element can be done by setting line-height equal to the container height, but this has subtle differences between browsers. On small elements, like a notification badge, these are more pronounced.

Better is to set line-height equal to font-size (or slightly smaller) and use padding. You'll have to adjust your height to accomodate.

Here's a CSS-only, single <div> solution that looks pretty iPhone-like. They expand with content.

Demo: http://jsfiddle.net/ThinkingStiff/mLW47/

Output:

enter image description here

CSS:

.badge {
    background: radial-gradient( 5px -9px, circle, white 8%, red 26px );
    background-color: red;
    border: 2px solid white;
    border-radius: 12px; /* one half of ( (border * 2) + height + padding ) */
    box-shadow: 1px 1px 1px black;
    color: white;
    font: bold 15px/13px Helvetica, Verdana, Tahoma;
    height: 16px; 
    min-width: 14px;
    padding: 4px 3px 0 3px;
    text-align: center;
}

HTML:

<div class="badge">1</div>
<div class="badge">2</div>
<div class="badge">3</div>
<div class="badge">44</div>
<div class="badge">55</div>
<div class="badge">666</div>
<div class="badge">777</div>
<div class="badge">8888</div>
<div class="badge">9999</div>

Solution 2 - Css

Modern Solution

The result is that the circle never gets distorted and the text stays exactly in the middle of the circle - vertically and horizontally.

.circle {
  background: gold;
  width: 40px; 
  height: 40px;
  border-radius: 50%;
  display: flex; /* or inline-flex */
  align-items: center; 
  justify-content: center;
}

<div class="circle">text</div>

Tailwind CSS

If you'd like to achieve the same using a modern framework - TailwindCSS. This is as simple as...

<div class="w-12 h-12 flex items-center justify-center bg-yellow-400 rounded-full">text</div>

Solution 3 - Css

If you have content with height unknown but you know the height the of container. The following solution works extremely well.

HTML

<div class="center-test">
    <span></span><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
    Nesciunt obcaecati maiores nulla praesentium amet explicabo ex iste asperiores 
    nisi porro sequi eaque rerum necessitatibus molestias architecto eum velit 
    recusandae ratione.</p>
</div>

CSS

.center-test { 
   width: 300px; 
   height: 300px; 
   text-align: 
   center; 
   background-color: #333; 
}
.center-test span { 
   height: 300px; 
   display: inline-block; 
   zoom: 1; 
   *display: inline; 
   vertical-align: middle; 
 }
.center-test p { 
   display: inline-block; 
   zoom: 1; 
   *display: inline; 
   vertical-align: middle; 
   color: #fff; 
 }

EXAMPLE http://jsfiddle.net/thenewconfection/eYtVN/

One gotcha for newby's to display: inline-block; [span] and [p] have no html white space so that the span then doesn't take up any space. Also I've added in the CSS hack for display inline-block for IE. Hope this helps someone!

Solution 4 - Css

Interesting question! While there are plenty of guides on horizontally and vertically centering a div, an authoritative treatment of the subject where the centered div is of an unpredetermined width is conspicuously absent.

Let's apply some basic constraints:

  • No Javascript
  • No mangling of the display property to table-cell, which is of questionable support status

Given this, my entry into the fray is the use of the inline-block display property to horizontally center the span within an absolutely positioned div of predetermined height, vertically centered within the parent container in the traditional top: 50%; margin-top: -123px fashion.

Markup: div > div > span

CSS:

body > div { position: relative; height: XYZ; width: XYZ; }
div > div { 
  position: absolute;
  top: 50%;
  height: 30px;
  margin-top: -15px; 
  text-align: center;}
div > span { display: inline-block; }

Source: http://jsfiddle.net/38EFb/


An alternate solution that doesn't require extraneous markups but that very likely produces more problems than it solves is to use the line-height property. Don't do this. But it is included here as an academic note: http://jsfiddle.net/gucwW/

Solution 5 - Css

Here is an example of flat badges that play well with zurb foundation css framework
Note: you might have to adjust the height for different fonts.

http://jsfiddle.net/jamesharrington/xqr5nx1o/

The Magic sauce!

.label {
  background:#EA2626;
  display:inline-block;
  border-radius: 12px;
  color: white;
  font-weight: bold;
  height: 17px; 
  padding: 2px 3px 2px 3px;
  text-align: center;
  min-width: 16px;
}

Solution 6 - Css

Here's the code I used that ACTUALLY created a circle around my text

HTML

<!DOCTYPE html>
<html>
<head>
    <br></br><br></br><br></br><br></br><br></br>
    <title>Introducing CSS</title>
    <link href="CSS.css" type="text/css" rel="stylesheet" />
</head>
<body>
	<h1>
        <span class="three">Garden</span>
    </h1>
</body>
</html>

CSS

body {
    font-family: Arial, Verdana, sans-serif;
}
h1, h2 {
    color: #ee3e80;
}
p {
    color: #665544;
}

span {
    padding: 80px;
    background: gold;
    width: 40px; 
    height: 40px;
    border-radius: 100px;
    -moz-border-radius: 100px;
    -webkit-border-radius: 100px;
    display: flex;
    align-items: center; 
    justify-content: center;
    font-size: 1em
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - CssThinkingStiffView Answer on Stackoverflow
Solution 2 - CssArmandView Answer on Stackoverflow
Solution 3 - CssRichard HerriesView Answer on Stackoverflow
Solution 4 - CssStevenView Answer on Stackoverflow
Solution 5 - CssJames HarringtonView Answer on Stackoverflow
Solution 6 - CssVictorView Answer on Stackoverflow