269

Lets say I have a bootstrap button with a font-awesome icon and some text:

<div>
    <i class='icon icon-2x icon-camera'></i>
    hello world
</div>

How do I make text appear vertically centered? Text is aligned with the bottom edge of the icon now: http://jsfiddle.net/V7DLm/1/

isherwood
  • 58,414
  • 16
  • 114
  • 157
Boycott Russia
  • 11,818
  • 5
  • 28
  • 29
  • 2
    Add a new class to use on the icon itself:`.fa-center { line-height: inherit!important; vertical-align: middle; }` – rinogo Sep 03 '21 at 16:50

15 Answers15

350

I just had to do this myself, you need to do it the other way around.

  • do not play with the vertical-align of your text
  • play with the vertical align of the font-awesome icon
<div>
  <span class="icon icon-2x icon-camera" style=" vertical-align: middle;"></span>
  <span class="my-text">hello world</span>
</div>

Of course you could not use inline styles and target it with your own css class. But this works in a copy paste fashion.

See here: Vertical alignment of text and icon in button

If it were up to me however, I would not use the icon-2x. And simply specify the font-size myself, as in the following

<div class='my-fancy-container'>
    <span class='my-icon icon-file-text'></span>
    <span class='my-text'>Hello World</span>
</div>
.my-icon {
    vertical-align: middle;
    font-size: 40px;
}

.my-text {
    font-family: "Courier-new";
}

.my-fancy-container {
    border: 1px solid #ccc;
    border-radius: 6px;
    display: inline-block;
    margin: 60px;
    padding: 10px;
}

for a working example, please see JsFiddle

MrMaavin
  • 1,611
  • 2
  • 19
  • 30
andxyz
  • 3,848
  • 2
  • 18
  • 18
  • 1
    yes, this is a better solution, thanks. Still seems to require line-height though http://jsfiddle.net/paulftw/F3KyK/41/ – Boycott Russia Sep 03 '13 at 01:26
  • 1
    I updated your jsfiddle for how I would do it. I used font-size for the icon instead of using the 2x. http://jsfiddle.net/3GMjp/1/ – andxyz Sep 05 '13 at 15:57
  • In your first piece of code the start tag does not correspond with the ending tag. – jzacharuk May 25 '15 at 21:56
  • Does not work with some of the icons. [fa-angle-left example](http://jsfiddle.net/wfx23dkz/) – steakchaser Mar 04 '17 at 00:23
  • important to realize that including the fontawesome js files can also modify the looks. My icon was too far to the top, I deleted the js inclusion to see what would happen and now it's too far to the bottom -.- – lucidbrot Jul 29 '18 at 08:54
  • TDDR; *play with the vertical align of the font-awesome icon* fine be me. – Antoniossss Jan 07 '19 at 08:27
  • First line really helped me out. I do not really understand why though. +1 – m_h Oct 07 '20 at 18:17
60

I use icons next to text 99% of the time so I made the change globally:

.fa-2x {
  vertical-align: middle;
}

Add 3x, 4x, etc to the same definition as needed.

Rush Frisby
  • 11,388
  • 19
  • 63
  • 83
  • 9
    In my opinion this should be the accepted answer, as it is by far the simplest solution, unless I am missing something in the original question. Thanks @rushonerok! I'm not sure why some people say not to use `vertical-align: middle;` - I might be missing something here. Please explain if so. – Kendall Feb 11 '16 at 00:22
  • 2
    @Kendall Roth I think when people say to not use `vertical-align: middle`, they mean *if you are using `block` elements*. If you're using `inline`, `inline-block`, or `table-cell`, you should be good. MDN: [`vertical-align`](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align) – rinogo Oct 30 '17 at 18:58
  • Works like charm! Thank you :D – Mohammed A. Fadil Oct 10 '19 at 10:57
  • I find that on Bootstrap 5 icons, setting the vertical align of the :before element to 'baseline' does the trick: i.bi:before { vertical-align: baseline; } – Ryan Griggs May 19 '21 at 15:40
42

After considering all suggested options, the cleanest solution seems to be setting line-height and vertical-align everything:

See Jsfiddle Demo

CSS:

div {
    border: 1px solid #ccc;
    display: inline-block;
    height: 50px;
    margin: 60px;
    padding: 10px;
}
#text, #ico {
    line-height: 50px;
}

#ico {
    vertical-align: middle;
}
Boycott Russia
  • 11,818
  • 5
  • 28
  • 29
  • 2
    What if your container is bigger than 50px? Then it won't work...I have content that changes size and it should have centered icon inside...any idea about that? – Slaven Tomac Mar 17 '16 at 10:02
  • line-height is necessary if line height is not aligning with the parent box height. But this would not be responsive. This answer should help for responsiveness, https://stackoverflow.com/questions/19124255/center-icon-in-a-div-horizontally-and-vertically – F.G Jul 06 '21 at 00:37
28

if things aren't lining up, a simple line-height: inherit; via CSS on specific i.fa elements that are having alignment issues could do the trick simply enough.

You could also feasibly use a global solution, which due to a slightly higher CSS specificity will override FontAwesome's .fa rule which specifies line-height: 1 without requiring !important on the property:

i.fa {
  line-height: inherit;
}

Just make sure that the above global solution doesn't cause any other issues in places where you might also use FontAwesome icons.

purefusion
  • 943
  • 1
  • 15
  • 23
20

a flexbox option - font awesome 4.7 and below

FA 4.x Hosted URL - https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css

div {
  display: inline-flex; /* make element size relative to content */
  align-items: center; /* vertical alignment of items */
  line-height: 40px; /* vertically size by height, line-height or padding */
  padding: 0px 10px; /* horizontal with padding-l/r */
  border: 1px solid #ccc;
}

/* unnecessary styling below, ignore */
body {display: flex;justify-content: center;align-items: center;height: 100vh;}div i {margin-right: 10px;}div {background-color: hsla(0, 0%, 87%, 0.5);}div:hover {background-color: hsla(34, 100%, 52%, 0.5);cursor: pointer;}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div>
    <i class='fa fa-2x fa-camera'></i>
    hello world
</div>

fiddle

http://jsfiddle.net/Hastig/V7DLm/180/


using flex and font awesome 5

FA 5.x Hosted URL - https://use.fontawesome.com/releases/v5.0.8/js/all.js

div {
  display: inline-flex; /* make element size relative to content */
  align-items: center; /* vertical alignment of items */
  padding: 3px 10px; /* horizontal vertical position with padding */
  border: 1px solid #ccc;
}
.svg-inline--fa { /* target all FA icons */
  padding-right: 10px;
}
.icon-camera .svg-inline--fa { /* target specific icon */
  font-size: 50px;
}
/* unnecessary styling below, ignore */
body {display: flex;justify-content: center;align-items: center;height: 100vh; flex-direction: column;}div{margin: 10px 0;}div {background-color: hsla(0, 0%, 87%, 0.5);}div:hover {background-color: hsla(212, 100%, 63%, 1);cursor: pointer;}
<script src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
<div class="icon-camera">
    <i class='fas fa-camera'></i>
    hello world
</div>
<div class="icon-clock">
    <i class='fas fa-clock'></i>
    hello world
</div>

fiddle

https://jsfiddle.net/3bpjvof2/

Hastig Zusammenstellen
  • 4,286
  • 3
  • 32
  • 45
12

The simplest way is to set the vertical-align css property to middle

i.fa {
    vertical-align: middle;
}
ajaali
  • 860
  • 12
  • 16
6

This worked well for me.

i.fa {
  line-height: 100%;
}
Tom
  • 739
  • 7
  • 7
3

Try set your icon as height: 100%

You don't need to do anything with the wrapper (say, your button).

This requires Font Awesome 5. Not sure if it works for older FA versions.

.wrap svg {
    height: 100%;
}

Note that the icon is actually a svg graphic.

Demo

mriiiron
  • 117
  • 4
3

For those using Bootstrap 4 is simple:

<span class="align-middle"><i class="fas fa-camera"></i></span>
nscherzer
  • 53
  • 5
2

Another option to fine-tune the line height of an icon is by using a percentage of the vertical-align property. Usually, 0% is a the bottom, and 100% at the top, but one could use negative values or more than a hundred to create interesting effects.

.my-element i.fa {
    vertical-align: 100%; // top
    vertical-align: 50%; // middle
    vertical-align: 0%; // bottom
}
Arian Acosta
  • 6,491
  • 1
  • 35
  • 32
1

I would wrap the text in a so you can target it separately. Now if you float both and left, you can use line-height to control the vertical spacing of the . Setting it to the same height as the (30px) will middle align it. See here.

New Markup:

 <div>
    <i class='icon icon-2x icon-camera'></i>
    <span id="text">hello world</span>
</div>

New CSS:

div {
    border: 1px solid #ccc;
    height: 30px;
    margin: 60px;
    padding: 4px;
    vertical-align: middle;
}
i{
    float: left;
}
#text{
    line-height: 30px;
    float: left;
}
Rarblack
  • 4,559
  • 4
  • 22
  • 33
Webster Gordon
  • 300
  • 1
  • 5
  • 13
  • 4
    Vertical-align doesn't do *anything* on block elements, it only works on inline or table-cell elements. – cimmanon Jun 26 '13 at 01:30
  • I see, setting line-height = container's height and floating things left works and needs less typing. Here's an updated fiddle with noise reduced: http://jsfiddle.net/F3KyK/7/ – Boycott Russia Jun 26 '13 at 03:01
  • It's better to just set `vertical-align: middle` on the icon and text. That way you're not making assumptions about the icon height and there's less CSS. – Maros Aug 14 '13 at 16:54
1

Well, this question was asked years ago. I think technology has changed quite a bit and browser compatibility is much better. You could use vertical-align but I would consider that some what less scaleable and less reusable. I would recommend a flexbox approach.

Here is the same example the original poster used but with flexbox. It styles a single element. If a button size changes for whatever reason, it will continue to be vertically and horizontally centered.

.button {
    border: 1px solid #ccc;
    height: 40px;
    margin: 60px;
    padding: 4px;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

Example: JsFiddle

MrMaavin
  • 1,611
  • 2
  • 19
  • 30
0

When using a flexbox, vertical alignment of font awesome icons next to text can be very difficult. I tried margins and padding, but that moved all items. I tried different flex alignments like center, start, baseline, etc, to no avail. The easiest and cleanest way to adjust only the icon was to set it's containing div to position: relative; top: XX; This did the job perfectly.

ADP
  • 95
  • 1
  • 6
0

Simply define vertical-align property for the icon element:

div .icon {
   vertical-align: middle;
}
ali6p
  • 1,683
  • 13
  • 17
0

for me, just making the element display gird, and aligning content works perfectly. simply solution.

.yourfontawesome<i>Element{
display: grid;
align-content: center;
}
robskaar
  • 412
  • 4
  • 14