Vertically and horizontally centering text in circle in CSS (like iphone notification badge)
-
22-10-2019 - |
Question
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
Solution
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:
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>
OTHER TIPS
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!
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/
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;
}