79

I would like to add badge with some number (5, 10, 100) on top of the Font Awesome symbol (fa-envelope). For example:

the picture

But, I can not understand how to put the badge on top of the symbol. My attempt is available here: jsFiddle.

I would like to have it support Twitter Bootstrap 2.3.2.

Kirk Beard
  • 9,569
  • 12
  • 43
  • 47
LA_
  • 19,823
  • 58
  • 172
  • 308

7 Answers7

87

This can be done with no additional mark-up, just a new class (which you would use anyway) and a pseudo element.

JSFiddle Demo

HTML

<i class="fa fa-envelope fa-5x fa-border icon-grey badge"></i>

CSS

*.icon-blue {color: #0088cc}
*.icon-grey {color: grey}
i {   
    width:100px;
    text-align:center;
    vertical-align:middle;
    position: relative;
}
.badge:after{
    content:"100";
    position: absolute;
    background: rgba(0,0,255,1);
    height:2rem;
    top:1rem;
    right:1.5rem;
    width:2rem;
    text-align: center;
    line-height: 2rem;;
    font-size: 1rem;
    border-radius: 50%;
    color:white;
    border:1px solid blue;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • 7
    Thank you! Is there any way to move `content` out of css to html? – LA_ Mar 30 '14 at 09:50
  • 26
    Not unless you go down the extra element route like a `` ALTHOUGH you could use a `data-attribute` like this: http://jsfiddle.net/zxVhL/18/ – Paulie_D Mar 30 '14 at 17:57
  • This answer doesn't really work when the count is thousand or more. – Steven Dec 30 '15 at 18:07
  • 9
    Expanding on Paulie_D's comment and jsfiddle: When passing-in an argument from html with a data attribute (e.g. data-count), you can hide the badge with .badge[data-count="0"]:after{ display : none; } – Les Nightingill Jan 18 '16 at 14:04
  • 1
    For IE 11.0.900.18097 - The number was at the top of the badge when I expected it would be in the middle. I changed line-height on the pseudo element from rem to em and it worked. There is an ie bug on the subject: https://connect.microsoft.com/IE/feedback/details/776744 – notapatch Jun 12 '17 at 09:16
  • For a bootstrap support you would have to change the class named badge because it is already used by the framework ... – hugsbrugs Jan 18 '18 at 17:39
  • 1
    It is **now** it wasn't when this answer was written. – Paulie_D Jan 18 '18 at 19:11
49

While @Paulie_D's answer is good, it doesn't work so well when you have a variable width container.

This solution works a lot better for that: http://codepen.io/johnstuif/pen/pvLgYp

HTML:

<span class="fa-stack fa-5x has-badge" data-count="8,888,888">
  <i class="fa fa-circle fa-stack-2x"></i>
  <i class="fa fa-bell fa-stack-1x fa-inverse"></i>
</span>

CSS:

.fa-stack[data-count]:after{
  position:absolute;
  right:0%;
  top:1%;
  content: attr(data-count);
  font-size:30%;
  padding:.6em;
  border-radius:999px;
  line-height:.75em;
  color: white;
  background:rgba(255,0,0,.85);
  text-align:center;
  min-width:2em;
  font-weight:bold;
}
Gerard
  • 4,818
  • 5
  • 51
  • 80
24

Wrap the fa-envelope and the span containing the number in a div and make the wrapper div position:relative and the span position:absolute.

Check this fiddle

HTML used

<div class="icon-wrapper">
   <i class="fa fa-envelope fa-5x fa-border icon-grey"></i>
   <span class="badge">100</span>
</div>

CSS

.icon-wrapper{
    position:relative;
    float:left;
}

*.icon-blue {color: #0088cc}
*.icon-grey {color: grey}
i {   
    width:100px;
    text-align:center;
    vertical-align:middle;
}
.badge{
    background: rgba(0,0,0,0.5);
    width: auto;
    height: auto;
    margin: 0;
    border-radius: 50%;
    position:absolute;
    top:-13px;
    right:-8px;
    padding:5px;
}

Hope this might help you

James
  • 4,540
  • 1
  • 18
  • 34
14

This seems to work, and it has a very minimal code to be added.

.badge{
  position: relative;
  margin-left: 60%;
  margin-top: -60%;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<span class="fa-stack fa-3x">
  <i class="fa fa-circle fa-stack-2x"></i>
  <i class="fa fa-bell fa-stack-1x fa-inverse"></i>
  <span class="badge">17</span>
</span>
<span class="fa-stack fa-2x">
  <i class="fa fa-circle fa-stack-2x"></i>
  <i class="fa fa-bell fa-stack-1x fa-inverse"></i>
  <span class="badge">17</span>
</span>
<span class="fa-stack fa-1x">
  <i class="fa fa-circle fa-stack-2x"></i>
  <i class="fa fa-bell fa-stack-1x fa-inverse"></i>
  <span class="badge">17</span>
</span>
Rafael Herscovici
  • 16,558
  • 19
  • 65
  • 93
  • Best answer for bootstrap 4 and also margin-left: -15px;margin-top: -21px; worked best for me on all sizes – Sol May 15 '19 at 05:22
10

http://jsfiddle.net/zxVhL/16/

By placing the badge inside the icon element I was able to position it relative to the bounds of the icon container. I did all the sizing using ems so that the size of the badge is relative to the size of the icon and this can be changed by simply changing the font-size in .badge

MStrutt
  • 819
  • 6
  • 7
  • Nice solution: by adding a ::before and ::after of '.\00a0' {space) and removing the 'width' attribute it also adjusts to any width badge. Thanks! – Beartums Apr 18 '15 at 15:29
1

If you're using the SVG + JS version of Font Awesome:

https://fontawesome.com/how-to-use/on-the-web/styling/layering

Layers are the new way to place icons and text visually on top of each other.

<span class="fa-layers fa-fw">
    <i class="fas fa-envelope"></i>
    <span class="fa-layers-counter" style="background:Tomato">1,419</span>
</span>
Thomas
  • 1,295
  • 14
  • 12
0

From Font Awesome documentation:

<span class="fa-layers fa-fw" style="background:MistyRose">
    <i class="fas fa-envelope"></i>
    <span class="fa-layers-counter" style="background:Tomato">1,419</span>
</span>