line-height as a percentage not working

Css

Css Problem Overview


I am having an issue with line-height that I cannot quite get my head around.

The following code will center an image within a div:

CSS

.bar {
    height: 800px;
    width: 100%;
    line-height:800px;
    background-color: #000;
    text-align: center; 
}

.bar img {
    vertical-align: middle;   
}

HTML

<div class="bar">
    <img src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

However, if I change the line height to 100%, then the line height does not take effect (or at least does not become 100% of the div).

Example jsfiddle

Does anyone know what I am doing wrong?

Css Solutions


Solution 1 - Css

line-height: 100% means 100% of the font size for that element, not 100% of its height. In fact, the line height is always relative to the font size, not the height, unless its value uses a unit of absolute length (px, pt, etc).

Solution 2 - Css

I know this question is old, but I found what for me is the perfect workaround.

I add this css to the div that I want to center:

div:before {
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

This works every time and it is clean.

Edit: Just for completion's sake, I use scss and I have a handy mixin that I include on every parent who's direct children I want to have vertically centered:

@mixin vertical-align($align: middle) {
  &:before {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: $align;
    // you can add font-size 0 here and restore in the children to prevent
    // the inline-block white-space to mess the width of your elements
    font-size: 0;
  }
  & > * {
    vertical-align: $align;
    // although you need to know the font-size, because "inherit" is 0
    font-size: 14px;
  }
}

Full explanation: div:before will add an element inside the div, but before any of its children. When using :before or :after we must use a content: declaration otherwise nothing will happen, but for our purpose, the content can be empty. Then we tell the element to be as tall as its parent, as long as its parent's height is defined and this element is at least inline-block. vertical-align defines the vertical position of self related to parent, as opposed to text-align that works differently.

The @mixin declaration is for sass users and it would be used like this:

div {
    @include vertical-align(middle)
}

Solution 3 - Css

When you use percentage as the line-height it is not based on the div container, rather its based on the font-size.

Solution 4 - Css

line-height: 100% would be an easy way to vertically center elements, if it was calculated in relation to the container, but that would be too easy, hence it doesn't work.

So instead, it is just another way of saying line-height: 1em (right?)

Another way of vertically centering an element would be:

.container {
     position:relative;
}
.center {
     position:absolute;
     top:0; left:0; bottom:0; right:0;
     margin: auto;
     /* for horiz left-align, try "margin: auto auto auto 0" */
}

Solution 5 - Css

might not be pretty, but it's working, and its semantic;

<div class="bar" style="display: table; text-align: center;">
    <img style="display: table-cell; vertical-align: middle;" src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

display: table-cell gives an element the unique table ablillity to align verticaly (atleast i think its unique)

Solution 6 - Css

This is a very late answer, however in modern browsers, assuming that the parent element is 100% of the screen height as well, you can use the vh viewport unit. FIDDLE

line-height: 100vh;

Browser support

Solution 7 - Css

This solution works in IE9 and above. First we set the child's top position to 50% (middle of the parent). Then using translate rule, shift the child up by a half of its actual height. The main benefit is that we don't need to define child's height, it's calculated by the browser dynamically. JSFiddle

.bar {
    height: 500px;
    text-align: center;
    background: green;
}
.bar img {
    position: relative;
    top: 50%;
    transform: translate(0, -50%);
}

Solution 8 - Css

A more modern approach is to use flexbox for this, it is simpler and cleaner. However, flexbox is an entirely different paradigm from what inline-block, float or position used to be.

To align items inside .parent you do:

.parent {
  display: flex;
  align-items: center;
}

That is about it. Children of flex parents are automatically converted to flex child items.

You should read more about flexbox, a good place to start is this cheat sheet: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Solution 9 - Css

You can set line-height based on that element height. If the element height 200px means you need to set line height to 200px to center the text.

span {
  height: 200px;
  width: 200px; 
  border: 1px solid black;
  line-height: 200px; 
  display: block;
}

<span>Im vertically center</span>

Solution 10 - Css

This is the modern solution in which you need to set the following CSS in the container div or outer div.

.outer-div {
  display: flex;
  justify-content: center;
  align-items: center; 
}

Another following solution may be applied to the element which you want to make centered vertically. Note that the outer or container div should be

.inner-div {
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate(-50%,-50%);
    text-align: center;
}

Note that the outer or container div position should be relative.

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
QuestionMy Head HurtsView Question on Stackoverflow
Solution 1 - CssBoltClockView Answer on Stackoverflow
Solution 2 - Csssantiago ariztiView Answer on Stackoverflow
Solution 3 - CsslocrizakView Answer on Stackoverflow
Solution 4 - CssRolfView Answer on Stackoverflow
Solution 5 - CssJohan OlssonView Answer on Stackoverflow
Solution 6 - CssFelisPhasmaView Answer on Stackoverflow
Solution 7 - CssArsen K.View Answer on Stackoverflow
Solution 8 - Csssantiago ariztiView Answer on Stackoverflow
Solution 9 - CssShanmugaraja_KView Answer on Stackoverflow
Solution 10 - CssAsrafView Answer on Stackoverflow