How to center text vertically with a large font-awesome icon? - html

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/

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

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.

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;
}

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.

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/

The simplest way is to set the vertical-align css property to middle
i.fa {
vertical-align: middle;
}

This worked well for me.
i.fa {
line-height: 100%;
}

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

For those using Bootstrap 4 is simple:
<span class="align-middle"><i class="fas fa-camera"></i></span>

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
}

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;
}

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.

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

Simply define vertical-align property for the icon element:
div .icon {
vertical-align: middle;
}

for me, just making the element display gird, and aligning content works perfectly. simply solution.
.yourfontawesome<i>Element{
display: grid;
align-content: center;
}

Related

Aligning text with floated :before icon

I am working on a button style for Azure Active Directory B2C. Azure automatically provides the following content
<div class="options">
<div>
<button class="accountButton firstButton" id="AmazonExchange" tabindex="1">Amazon</button>
</div>
<div>
<button class="accountButton" id="LinkedInExchange" tabindex="1">LinkedIn</button>
</div>
<div>
<button class="accountButton" id="FacebookExchange" tabindex="1">Facebook</button>
</div>
<div>
<button class="accountButton" id="GoogleExchange" tabindex="1">Google+</button>
</div>
<div>
<button class="accountButton" id="MicrosoftAccountExchange" tabindex="1">Microsoft</button>
</div>
</div>
Using FontAwesome and :before css magic, I am able to add an icon, and fix width the button
.accountButton {
border: 1px solid #FFF;
color: #FFF;
margin-left: 0;
margin-right: 2px;
padding-right: 15px;
transition: background-color 1s ease 0s;
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
text-align: center;
word-wrap: break-word;
width: 120px;
background-color: #5x05050;
opacity: 0.7;
}
#AmazonExchange:before {
font-family: fontAwesome;
content: "\f270";
//font-size: large;
float:left;
width:32px;
text-align: center;
}
This is nice, but I would like the icons to be just a bit bigger. However, increasing the size of the FontAwesome item to large causes the primary text to go up, as it is aligned to the top of the float:left.
I've tried a variety of valign combinations with no luck. I cannot change the html (as it is dynamically generated). How can I center the "Amazon" with the larger icon? (Notice that the Amazon text is now higher than the LinkedIn and other text.)
Attempted jsfiddle, doesn't look quite the same, but should show the issue.
https://jsfiddle.net/tofutim/0637yknj/9/
There isn't a dynamic way to adjust valign with floating elements. You can either use display: inline-block; + vertical-align: middle;
.accountButton {
vertical-align: middle;
line-height: 1.5;
}
.accountButton:before {
vertical-align: middle;
margin-right: 8px;
}
jsFiddle
Or, use display: flex; + align-items: center;
.accountButton {
display: flex;
align-items: center;
line-height: 1.5;
}
.accountButton:before {
margin-right: 8px;
}
jsFiddle
The line-height part is just to make the buttons a bit taller, you can also use padding-top + padding-bottom instead.
Giving a line-height to .accountButton might correct this issue for you. This will vertically centre text within the given vertical space, and in your example should be equal to the desired height of the button.
Try something like: line-height: 30px;.

White space after centering inline-block elements

.calloutWrapper
{
background: green;
height: 50%;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
}
.callout {
width: 24%;
min-height: 100%;
vertical-align: top;
display: inline-block;
*display: inline;
zoom: 1;
background-color: blue; }
.stretch {
content: '';
width: 100%;
display: inline-block;
font-size: 0;
vertical-align: top;
}
http://jsfiddle.net/yux07nom/
There is white space after the "callouts" seen with the blue backgrounds. This extends beyond the green background of "calloutWrapper" I believe its caused by the .stretch applied to the span.
First off you close out the body twice which doesn't cause your problem but should be resolved
</body>
<script>
</script>
</body>
Then the white space is caused by your .stretch span
display: inline-block; is the culprit
Remove that and your good to go.
A bit more info about what you're trying to achieve with that span could help provide a better answer.
If you are trying to achieve responsive boxes you could use a css responsive grid template like bootstrap or foundation.
Alternatively you could just float left and add margin right to the first 3 elements.
eg
http://jsfiddle.net/yux07nom/5/
<div class="calloutWrapper">
<div class="callout">Callout</div>
<div class="callout">Callout</div>
<div class="callout">Callout</div>
<div class="callout last">Callout</div>
</div>
And the CSS
.callout {
width: 24%;
min-height: 100%;
background-color: blue;
float:left;
margin-right:1.3333333333%;
}
.callout.last{
margin-right:0;
}
I'm not sure there's an ideal solution to this. Your best bet is to set the font size of the .calloutWrapper div to zero and then reapply a useful font-size value to the .callout divs, like this : http://jsfiddle.net/2dgx98ye/
Note however, that some older browsers, particularly some used on mobiles, try to apply a minimum font-size which breaks this. In modern browsers, even when the have a minimum font-size configured, do not enforce it on elements where the font-size is 0.
Inline-block elements will preserve one space in the HTML. Two choices:
Have no space between those inline-block elements in the HTML.
Float:left those inline-block elements

Vertically Center a divider line to the Left of Styled Link Image

Alright, this one should be pretty easy for you front-end guys out there. I have the styled purple link all set to go. I'm just having trouble getting the vertical line to look OK. Assume the line is 1px #000 solid
I kind-of got it working making a div w/ a bottom-border and floating the styled link to the right. If I do that, I can't seem to get there to be space between the divider line and the link.
The following involves some extra markup and uses table-cells.
HTML:
<div class="wrapper">
<span class="leader">
<b></b>
</span>
<span class="cell">
<button>Sample Button</button>
</span>
</div>
CSS:
.wrapper {
border: 1px dotted gray;
display: table;
width: 100%;
}
.wrapper .leader, .wrapper .cell {
display: table-cell;
vertical-align: middle;
}
.wrapper .leader {
width: 100%;
padding: 0 10px;
}
.wrapper .leader b {
display: block;
border-bottom: 1px solid red;
}
.wrapper button {
white-space: nowrap;
}
Demo at: http://jsfiddle.net/audetwebdesign/8aSBA/
There are a few advantages to this approach:
You can control the spacing to the left and right of the horizontal line
Vertical alignment is independent of font-size, line-height
You don't need to specify the width of the button
You can use a :before selector in css, though im not sure is compatable in < ie7
.button:before {
background: none repeat scroll 0 0 #000000;
content: "";
float: left;
height: 1px;
margin-top: 12px;
width: 59%;
}

How to have a horizontal line at the middle of a html heading with CSS?

Ok I now use an image to do it, but I want to do it via CSS(no absolut or relative positioning, I'm looking to make it responsive).
Example here: http://teothemes.com/wp/services/. The heading is 'Services', right above the 3 content areas...I'd like to achieve the same effect with only CSS. I tried some things but it didn't work.
Thank you.
Here's how I'd do it -> http://tinkerbin.com/QN9efWHd
CSS3 background-image
span with background covering the background image.
the HTML...
<p>
<span>Services or Something</span>
</p>
... for the CSS...
p {
background: linear-gradient (to bottom, rgba(145,37,37,0) 49%,
rgba(145,37,37,1) 51%, rgba(145,37,37,1) 52%,
rgba(145,37,37,0) 54%);
text-align: center;
}
span {
display: inline-block;
padding: 0 10px;
background: #fff;
}
Here's my go at it... Only thing is the spans have a set width.
HTML
​<div id="hr">
<span></span>
asdf
<span></span>
</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
CSS
#hr span {
width:200px;
border-bottom:1px solid #ccc;
display: inline-block;
margin-bottom:5px;
}
DEMO
Using one floated span with a border:
<div class="heading">
<span></span>
<h3>Heading<h3>
</div>
.heading {
width: 100%;
text-align: center;
line-height: 100%;
}
.heading span {
float: left;
margin: 20px 0 -8px;
border: 1px solid;
width: 100%;
}
.heading h3 {
display: inline;
padding: 0px 0px 0 20px;
width: auto;
margin: auto;
}
The negative base margin on the span may need to be adjusted for different heading sizes. , The background colour of the heading should match the background of the overall container.
JS Fiddle demo
I was looking at a bunch of solutions to this issue, and I really wanted something simple. Why not just use the :before and :after to embed some content into the heading you want to have a horizontal-rule/line in. In my CSS below I chose an EM DASH (unicode \2014) for the heading's horizontal line. When making a larger horizontal line, and depending on your font, you need to take away letter spacing from multiple EM DASHes. Lastly you can add some padding to the head & tail of the EM DASH so that it doesn't press up against your heading text.
Here's some CSS, heading-1 is very simple, heading-2 has a longer line (see in action https://jsfiddle.net/pyxkh3jz/):
h1:before, h1:after {
content:"\2014";
}
h2:before, h2:after {
/* two dashes */
content:"\2014\2014";
/* depending on your font adjust this */
letter-spacing: -6px;
}
/* add some padding so heading text isn't touching lines */
h2:before {
padding-right: 15px;
}
h2:after {
padding-left: 15px;
}
Haven't checked browser compatibility here; but this isn't radical CSS so it should work for some or most of you. The lines and their length fit my use case.
This idea can probably be improved upon by other keeners...have at it!

How to vertically center the text without using display: table-cell?

I'm trying to make the menu appear at the middle of 30px line but the problem is that I cannot move it from the top unless I use display: table-cell.
What is wrong here?
Style sheet file:
div.menu
{
width: 600;
height: 30px;
border: 1px solid black;
margin: 0px auto;
text-align: center;
vertical-align: bottom
}
The menu code in my html file:
<div class="space"></div>
<div class="menu">
Home
Home
Home
Home
Home
</div>
<div class="space"></div>
line-height: 100px; set the height of your menu line. But keep enough space in horizontal dimension, otherwize you will get crazy view. Look forward to min-width, width or overflow-x rules.
div.menu
{
width: 600px;
/* Use line-height instead of height */
line-height: 30px;
border: 1px solid black;
margin: 0px auto;
text-align: center;
}
div.menu a {
vertical-align: middle;
}
setting the line-height to the desired value fixes the issue but it is not a correct way to do it. It is just a hack. The correct way is to use vertical-align property (for all the anchors inside the menu div)
.menu a {
vertical-align: middle;
}
Check this fiddle. http://jsfiddle.net/sfz7d/
Tell me if it works for you.