95

I have a div (#wrapper) containing 2 divs standing side by side.

I would like the right-div to be vertically aligned. I tried vertical-align:middle on my main wrapper but it is not working. It is driving me crazy!

Hope someone can help.

http://cssdesk.com/LWFhW

HTML:

<div id="wrapper">
  <div id="left-div">
    <ul>
      <li>One</li>
      <li>Two</li>
    </ul>
  </div>  
  <div id="right-div">
    Here some text...
  </div>
</div>

CSS:

#wrapper{
  width:400px;
  float:left;
  height:auto;
  border:1px solid purple;}

#left-div{
  width:40px;
  border:1px solid blue;
  float:left;}

#right-div{
  width:350px;
  border:1px solid red;
  float:left;}

ul{
  list-style-type: none;
  padding:0;
  margin:0;}
Djensen
  • 1,337
  • 1
  • 22
  • 32
Marc
  • 9,217
  • 21
  • 67
  • 90

6 Answers6

69

You'll have no luck with floated elements. They don't obey vertical-align.

You need display:inline-block instead.

http://cssdesk.com/2VMg8


Beware!

Be careful with display: inline-block; as it interprets the white-space between the elements as real white-space. It does not ignores it like display: block does.

I recommend this:

Set the font-size of the containing element to 0 (zero) and reset the font-size to your needed value in the elements like so

ul {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0;
}
ul > li {
    font-size: 12px;
}

See a demonstration here: http://codepen.io/HerrSerker/pen/mslay


CSS

#wrapper{
  width:400px;
  height:auto;
  border:1px solid green;
  vertical-align: middle;
  font-size: 0;
}

#left-div{
  width:40px;
  border:1px solid blue;
  display: inline-block;
  font-size: initial;
  /* IE 7 hack */
  *zoom:1;
  *display: inline;
  vertical-align: middle;
}

#right-div{
  width:336px;
  border:1px solid red;
  display: inline-block;  
  font-size: initial;
  /* IE 7 hack */
  *zoom:1;
  *display: inline;
  vertical-align: middle;
}
  
ashleedawg
  • 20,365
  • 9
  • 72
  • 105
yunzen
  • 32,854
  • 11
  • 73
  • 106
  • This won't work if the #wrapper height is fixed. The #right-div is centered **relative to the #left-div**, not relative to the wrapper element. (`inline-block` makes it behave like an inline `img` that has the `align` attribute set) – Costa Nov 27 '12 at 04:13
  • @Costa That's the way it should be, I think. – yunzen Aug 20 '13 at 15:55
  • it doesn't matter in what way it should be, there are many cases where you MUST use a floating element, and there IS always a way to do stuff in CSS. always. in the most simple case, a vertical-align of floated text: http://jsbin.com/UWeB/1/edit – vsync Aug 20 '13 at 20:15
  • @vsync In your case, the vertical alignment only works because of the equal height of the two floated elements. If you make the heights distinct, it won't work. http://jsbin.com/UWeB/2/ – yunzen Aug 21 '13 at 07:06
  • 13
    but your solution won't work also, because you can't just decide to NOT use floats..the whole point is to somehow vertical-align while using floats. – vsync Aug 21 '13 at 09:46
  • There are different situations. If you want to vertically align something inside a box you may use floats with the line-height. But only if you just got one line. If you want to align things vertically to each other that don't share the same heights, floating will not work. period. – yunzen Aug 21 '13 at 11:04
  • @vsync By the way. It says nothing in the OP's questions, that is has to be done with floats. – yunzen Aug 21 '13 at 11:59
  • 1
    but people all over the internet finds this question because of the title and your answer did not help them in any way...in and it's possible to vertical align floats, if you do a trick inside them, I'll post a test page soon – vsync Aug 21 '13 at 13:44
  • As @vsync has suggested, this does not answer the problem for everyone and less so particularly now responsive designs are more prominent. If you use percentage widths and tell them to be `display:inline-block;`, it won't work as expected. Then you need to follow the answer below which IMO is the best way of doing it. See this [example](http://jsfiddle.net/2T62G/1/) for an explanation – Jamie Barker May 20 '14 at 08:24
  • @JamieBarker Yes, there are *caveat*s with `incline-block`. But if you have full control over the HTML source, you can use `inline-block` `div`s without any white-space in the HTML source, there is no spacing issue. Despite what you say the `width` values is obeyed with no flaw. See [this fiddle](http://jsfiddle.net/HerrSerker/P5Puy/) or zoltan's [answer](http://stackoverflow.com/questions/12183341/how-to-remove-invisible-space-from-html#answer-12183374). The OP was about the vertical-alignment, which is not possible with `float`. One has to use `inline-block` – yunzen May 20 '14 at 08:54
  • The last resort would be ugly table-layout. – yunzen May 20 '14 at 08:56
  • 2
    All my point was that sometimes inline-block wasn't an option and gave a use-case to help others who might end up on this page from Google. There was no need to be rude. – Jamie Barker May 20 '14 at 10:31
  • @JamieBarker I didn't meant to be rude. You must excuse me, for my being too straight-in-the-face. Sorry, but I'm a German person. – yunzen May 20 '14 at 15:05
22

You can do this quite easily with display table and display table-cell.

#wrapper {
    width: 400px;
    float: left;
    height: auto;
    display: table;
    border: 1px solid green;
}

#right-div {
    width: 356px;
    border: 1px solid red;
    display: table-cell;
    vertical-align: middle;
}

EDIT: Actually quickly messed around on CSS Desk for you - http://cssdesk.com/RXghg

ANOTHER EDIT: Use Flexbox. This will work but it's pretty outdated - http://www.cssdesk.com/davf5

#wrapper {
    display: flex;
    align-items: center;
    border:1px solid green;
}

#left-div {
    border:1px solid blue;
}

#right-div {
    border:1px solid red;
}
1stthomas
  • 731
  • 2
  • 15
  • 22
SpaceBeers
  • 13,617
  • 6
  • 47
  • 61
  • 1
    Hello SpaceBeers. Your suggestion is not working for me as I am hiding the overflow of right-div (I just added the code into css desk). With your solution the overflow is not hidden, the div expands its width... – Marc Feb 24 '12 at 12:55
11

I realize this is an ancient question however I thought it would be useful to post a solution to the float vertical alignment issue.

By creating a wrapper around the content you want floated, you can then use the ::after or ::before pseudo selectors to vertically align your content within the wrapper. You can adjust the size of that content all you want without it affecting the alignment. The only catch is that the wrapper must fill 100% height of its container.

http://jsfiddle.net/jmdrury/J53SJ/

HTML

<div class="container">
    <span class="floater">
        <span class="centered">floated</span>
    </span>
    <h1>some text</h1>
</div>

CSS

div {
    border:1px solid red;
    height:100px;
    width:100%;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
.floater {
    float:right;
    display:inline-block;
    height:100%;
    box-sizing: border-box;
}
.centered {
    border:1px solid blue;
    height: 30px;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
h1 {
    margin:0;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
.container:after, .floater:after, .centered:after, h1:after {
    height:100%;
    content:'';
    font-size:0;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
Justin Drury
  • 748
  • 11
  • 19
  • I'm not sure what you are up to, but after deleting the `centered` class and cleaning up lots of redundant stuff from that CSS it still does the vertical alignment fine, with just (sorry about the loss of formatting!...): `div { border:1px solid red; height:100px; } .floater { float:right; height:100%; } h1 { vertical-align:middle; } .container:after, .floater:after, .centered:after { height:100%; content:''; font-size:0; vertical-align:middle; display:inline-block; }` – Sz. Feb 02 '17 at 17:19
7

I do my best to avoid using floats... but - when needed, I vertically align to the middle using the following lines:

position: relative;
top: 50%;
transform: translateY(-50%);
Lorelorelore
  • 3,335
  • 8
  • 29
  • 40
Maoritzio
  • 387
  • 1
  • 6
  • 8
4

A possible solution is to make wrapper div flex with items aligned on center as specified by https://spin.atomicobject.com/2016/06/18/vertically-center-floated-elements-flexbox/.

Vilson Vieira
  • 717
  • 8
  • 7
-1

The only downfall of my modifications is you have a set div height...I don't know if that's a problem for you or not.

http://cssdesk.com/kyPhC

Sean Carruthers
  • 414
  • 2
  • 10
  • 1
    Hello Sean. Thanks but I am trying to use a flexible solution and thus hoping to avoid this kind of solution... – Marc Feb 24 '12 at 12:50