I'm trying to vertically center a span
or div
element within another div
element. However when I put vertical-align: middle
, nothing happens. I've tried changing the display
properties of both elements, and nothing seems to work.
This is what I'm currently doing in my webpage:
.main { height: 72px; vertical-align: middle; border: 1px solid black; padding: 2px; } .inner { vertical-align: middle; border: 1px solid red; } .second { border: 1px solid blue; }
Here is a jsfiddle of the implementation showing that it doesn't work: http://jsfiddle.net/gZXWC/
This seems to be the best way - some time has passed since my original post and this is what should be done now:
.main { display: table; /* optional css start */ height: 90px; width: 90px; /* optional css end */ } .inner { border: 1px solid #000000; display: table-cell; vertical-align: middle; }
Using CSS3:
<div class="outer">
<div class="inner"/>
</div>
Css:
.outer {
display : flex;
align-items : center;
}
use "justify-content: center;" to align elements horizontally
Note: This might not work in old IE's
inline-flex
to have multiple elements in a row inside the inner element.
.inner { width: 100%; }
. This way, it seems to work like .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }
but without forcing a minimum width.
justify-content: center;
to align horizontally which worked great
Try this, works for me very well:
/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;
/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;
/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;
/* W3C */
display:box;
box-pack:center;
box-align:center;
#element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}
- note the height is important to ensure the span inherits the full height of its container (probably a div) otherwise you still won't get vertical centering!
box
in display
Setting the line-height to the same height as it's containing div will also work
DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/
.inner {
line-height:72px;
border: 1px solid #000000;
}
line-height
will also change the height of the inner element. b) The inner element is still not accurately vertically centered. c) It does not work on elements that do not contain text, for ex: <img>
, or elements with fixed height.
In case you cannot rely on flexbox... Place .child
into .parent
's center. Works when pixel sizes are unknown (in other words, always) and no problems with IE9+ too.
.parent { position: relative; } .child { position: absolute; top : 50%; left: 50%; -ms-transform: translate(-50%, -50%); transform : translate(-50%, -50%); }
width: 80%
to fit my image content into the container.
You should put vertical-align: middle
on the inner element, not the outer element. Set the line-height
property on the outer element to match the height
of the outer element. Then set display: inline-block
and line-height: normal
on the inner element. By doing this, the text on the inner element will wrap with a normal line-height. Works in Chrome, Firefox, Safari, and IE 8+
.main { height: 72px; line-height:72px; border: 1px solid black; } .inner { display: inline-block; vertical-align: middle; line-height: normal; }
line-height: normal;
and display:inline;
works too. The bonus of this method is it doesn't interfere with text-align:center;
, which using display: table-cell;
can create issues with. Quite often we want to align horizontally as well as vertically. See this edited fiddle: jsfiddle.net/br090prs/36
line-height: normal
and display: inline-block
is so that the inner text will wrap properly. If you're sure that the text in the inner div will never wrap then these properties won't be necessary.
vertical-align: middle
has (almost) no effect here. It is the line-height that positions the .inner
in the middle.
I used this to align everything in the center of the wrapper div in case it helps anyone - I found it simplest:
div.wrapper { /* --- This works --- */ display: flex; /* Align Vertically */ align-items: center; /* Align Horizontally */ justify-content: center; /* --- ---------- ----- */ width: 100%; height:100px; background-color: blue; } div.inner { width: 50px; height: 50px; background-color: orange; }
This is a modern approach and it utilizes the CSS Flexbox functionality. You can now vertically align the content within your parent container by just adding these styles to the .main
container
.main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center; // To center align it horizontally as well
}
You can also use CSS Grids ( a two-dimensional grid-based layout system).
.main {
display: grid;
justify-content: center;
align-content: center;
}
Below is a Shorthand approach but browser support is still low - https://caniuse.com/?search=place-items.
.main {
display: grid; // flex - works for both
place-items: center;
}
And you are good to go!
Here you have an example of two ways of doing a vertical alignment. I use them and they work pretty well. One is using absolute positioning and the other using flexbox.
Using flexbox, you can align an element by itself inside another element with display: flex;
using align-self
. If you need to align it also horizontally, you can use align-items
and justify-content
in the container.
If you don't want to use flexbox, you can use the position property. If you make the container relative and the content absolute, the content will be able to move freely inside the container. So if you use top: 0;
and left: 0;
in the content, it will be positioned at the top left corner of the container.
https://i.stack.imgur.com/y9A5I.png
Then, to align it, you just need to change the top and left references to 50%. This will position the content at the container center from the top left corner of the content.
https://i.stack.imgur.com/hjAXM.png
So you need to correct this translating the content half its size to the left and top.
https://i.stack.imgur.com/p63HE.png
HTML
<div id="myparent">
<div id="mychild">Test Content here</div>
</div>
CSS
#myparent {
display: table;
}
#mychild {
display: table-cell;
vertical-align: middle;
}
We set the parent div to display as a table and the child div to display as a table-cell. We can then use vertical-align on the child div and set its value to middle. Anything inside this child div will be vertically centered.
here is a great article of how to vetical align.. I like the float way.
http://www.vanseodesign.com/css/vertical-centering/
The HTML:
<div id="main">
<div id="floater"></div>
<div id="inner">Content here</div>
</div>
And the corresponding style:
#main {
height: 250px;
}
#floater {
float: left;
height: 50%;
width: 100%;
margin-bottom: -50px;
}
#inner {
clear: both;
height: 100px;
}
It's simple. Just add display:table-cell
in your main class.
.main {
height: 72px;
vertical-align: middle;
display:table-cell;
border: 1px solid #000000;
}
Check out this jsfiddle!
Here is the latest simplest solution - no need to change anything, just add three lines of CSS rules to your container of the div where you wish to center at. I love Flex Box
#LoveFlexBox
.main { /* I changed height to 200px to make it easy to see the alignment. */ height: 200px; vertical-align: middle; border: 1px solid #000000; padding: 2px; /* Just add the following three rules to the container of which you want to center at. */ display: flex; flex-direction: column; justify-content: center; /* This is true vertical center, no math needed. */ } .inner { border: 1px solid #000000; } .second { border: 1px solid #000000; }
Bonus
the justify-content
value can be set to the following few options:
flex-start, which will align the child div to where the flex flow starts in its parent container. In this case, it will stay on top.
center, which will align the child div to the center of its parent container. This is really neat, because you don't need to add an additional div to wrap around all children to put the wrapper in a parent container to center the children. Because of that, this is the true vertical center (in the column flex-direction. similarly, if you change the flow-direction to row, it will become horizontally centered.
flex-end, which will align the child div to where the flex flow ends in its parent container. In this case, it will move to bottom.
space-between, which will spread all children from the beginning of the flow to the end of the flow. If the demo, I added another child div, to show they are spread out.
space-around, similar to space-between, but with half of the space in the beginning and end of the flow.
set below CSS
/*Parent*/
display: table;
/*immediate child*/
display: table-cell;
vertical-align: middle;
~Rahul Daksh
Since vertical-align
works as expected on a td
, you could put a single celled table
in the div
to align its content.
<div>
<table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
Aligned content here...
</td></tr></table>
</div>
Clunky, but works as far as I can tell. It might not have the drawbacks of the other workarounds.