I have the following code. It is set up so that the images are responsive (scale with the window size) and positioned centrally, both horizontally and vertically. It was working fine until I wanted to add several images stacked on top of each other to play as a slideshow (fade-in, fade-out). I had to position the img tags "absolute". And it obviously collapsed the parent divs. Basically I want an alternative method to stack images on top of each other without using absolute positioning.
<div class="container">
<div class="main-picture-wrapper">
<div class="main-picture">
<img id="front" src="img/VR-front.png" class="">
<img id="side" src="img/VR-side.png" class="">
</div>
</div>
</div>
.container {
height:100%;
text-align: center;
font:0/0 a;
}
.container:before {
content: ' ';
display: inline-block;
vertical-align: middle;
height: 100%;
}
.main-picture-wrapper {
margin-top: 70px;
display: inline-block;
vertical-align: middle;
font-size: 16px/1;
width:70%;
left:0;
}
.main-picture {
width:100%;
position: relative;
text-align: center;
}
.main-picture img {
position: absolute;
width:100%;
top: 0;
left: 0;
}
As k185 suggested, flexbox is the way, along with absolute positioning. As today it's compatible with most of browsers.
Keeping your markup and style, a good starting point could be something like this:
html, body {
height: 100%;
}
.main-picture {
...
display: flex;
align-items: center;
justify-content: center;
}
.main-picture img {
position: absolute;
}
https://jsbin.com/sinayiloge/edit?html,css,output
If you don't have compatibility problem, you can always use flexbox solutions. You can check this website, it has some good examples
http://www.sketchingwithcss.com/samplechapter/cheatsheet.html
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
While creating a HTML layout, I noticed some strange positioning issue I was unable to solve.
Take the following HTML:
<div class="outer-wrap">
<div class="header">
I am a Header
</div>
<div class="element">
Hello world
</div>
And combine with this CSS code:
#import "https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css";
html, body { height: 100%; }
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
}
.header {
position: absolute;
background: red;
}
Fiddle
As you can see, I've set the wrapper to display: table, which enables me to vertically center any child element with setting display: table-cell and vertical-align: middle.
Now when I try to add a header, strange things start to happen.
First, I have to declare position: absolute on the header, otherwise the header horizontally pushes away .element. I don't know why this happens, but I understand why this fix works: Because position: absolute takes things 'out of the flow'.
But if I take a look at the Fiddle, you'll notice a small gap on the left side which exposes the grey background color defined on .outer-wrap:
What is causing this gap & how to fix this?
Why do I have to use absolute positioning on the header to make it expand to the full container width?
The key reason causing that is you're not defining the table-cell div and would not be 100% wide and you see its shifting towards right seeing the gray border color which is the background of outer-wrap div. So, you need to define the width:100%; when you use display:table-cell; to make it display correctly.
Changed css:
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
width: 100%;/*explicitly define width to be 100%*/
}
.header {
position: absolute;
background: red;
z-index: 1;/*to make it display in front*/
}
Fixed fiddle
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;
}
<div class="main">
<div class="inner">
This box should be centered in the larger box
<div class="second">Another box in here</div>
</div>
</div>
Here is a jsfiddle of the implementation showing that it doesn't work: http://jsfiddle.net/gZXWC/
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
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;
}
<div class="main">
<div class="inner"> This </div>
</div>
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;
Setting the line-height to the same height as it's containing div will align content in the middle vertically;
DEMO http://jsfiddle.net/kevinPHPkevin/gZXWC/7/
.inner {
line-height:72px;
border: 1px solid #000000;
}
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%);
}
<div class="parent" style="background:lightyellow; padding:6em">
<div class="child" style="background:gold; padding:1em">—</div>
</div>
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;
}
<div class="main">
<div class="inner">Vertically centered text</div>
</div>
Fiddle
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;
}
<div class="wrapper">
<div class="inner">
</div>
</div>
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!
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 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.
Vertical Align Example
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.
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.
So you need to correct this translating the content half its size to the left and top.
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;
}
<div class="main">
<div class="inner">This box should be centered in the larger box
<div class="second">Another box in here</div>
</div>
<div class="inner">This box should be centered in the larger box
<div class="second">Another box in here</div>
</div>
</div>
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.
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.
Just put the content inside a table with height 100%, and set the height for the main div
<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
This paragraph should be centered in the larger box
</td></tr>
</table>
</div>
To vertically center a span or div element within another div, add position relative to parent div and position absolute to the child div.Now the child div can be positioned anywhere inside the div.Example below centers both horizontally and vertically.
<div class="parent">
<div class="child">Vertically and horizontally centered child div</div>
</div>
css:
.parent{
position: relative;
}
.child{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
set below CSS
/*Parent*/
display: table;
/*immediate child*/
display: table-cell;
vertical-align: middle;
~Rahul Daksh
THIS IS THE ANSWER:
vertical-align aligns elements relative to the dimensions of the line the element appears in.
reference: https://christopheraue.net/design/why-vertical-align-is-not-working
The question was "WHY?".
The answer: vertical-align only works in certain conditions
in the "display: table-cell;"
What would be the correct method to vertically center any content in a defined width/height div.
In the example there are two contents with different heights, what is the best way to center vertically both using the class .content . (and it works for every browser and without the solution of table-cell)
Have some solutions on mind, but would like to know other ideas, one is using position:absolute; top:0; bottom: 0; and margin auto.
I have researched this a little and from what I have found you have four options:
Version 1: Parent div with display as table-cell
If you do not mind using the display:table-cell on your parent div, you can use of the following options:
.area{
height: 100px;
width: 100px;
background: red;
margin:10px;
text-align: center;
display:table-cell;
vertical-align:middle;
}
Live DEMO
Version 2: Parent div with display block and content display table-cell
.area{
height: 100px;
width: 100px;
background: red;
margin:10px;
text-align: center;
display:block;
}
.content {
height: 100px;
width: 100px;
display:table-cell;
vertical-align:middle;
}
Live DEMO
Version 3: Parent div floating and content div as display table-cell
.area{
background: red;
margin:10px;
text-align: center;
display:block;
float: left;
}
.content {
display:table-cell;
vertical-align:middle;
height: 100px;
width: 100px;
}
Live DEMO
Version 4: Parent div position relative with content position absolute
The only problem that I have had with this version is that it seems you will have to create the css for every specific implementation. The reason for this is the content div needs to have the set height that your text will fill and the margin-top will be figured off of that. This issue can be seen in the demo. You can get it to work for every scenario manually by changing the height % of your content div and multiplying it by -.5 to get your margin-top value.
.area{
position:relative;
display:block;
height:100px;
width:100px;
border:1px solid black;
background:red;
margin:10px;
}
.content {
position:absolute;
top:50%;
height:50%;
width:100px;
margin-top:-25%;
text-align:center;
}
Live DEMO
This could also be done using display: flex with only a few lines of code. Here is an example:
.container {
width: 100px;
height: 100px;
display: flex;
align-items: center;
}
Live Demo
I found this solution in this article
.parent-element {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
It work like a charm if the height of element is not fixed.
Simple trick to vertically center the content of the div is to set the line height to the same as height:
<div>this is some line of text!</div>
div {
width: 400px
height: 50px;
line-height: 50px;
}
but this is works only for one line of text!
Best approach is with div as container and a span with the value in it:
.cont {
width: 100px;
height: 30px;
display: table;
}
.val {
display: table-cell;
vertical-align: middle;
}
<div class="cont">
<span class="val">CZECH REPUBLIC, 24532 PRAGUE, Sesame Street 123</span>
</div>
I would say to add a paragraph with a period in it
and style it like so:
<p class="center">.</p>
<style>
.center {font-size: 0px; margin-bottom: anyPercentage%;}
</style>
You may need to toy around with the percentages to get it right
margin: all_four_margin
by providing 50% to all_four_margin will place the element at the center
style="margin: 50%"
you can apply it for following too
margin: top right bottom left
margin: top right&left bottom
margin: top&bottom right&left
by giving appropriate % we get the element wherever we want.
I have a div that I want to center horizontally and vertically.
For the horizontal issue everything is great, but I have a problem with the vertical alignment.
I tried this:
#parent {
display: table;
}
#child {
display: table-row;
vertical-align: middle;
}
but this doesn't work.
If you only have to support browsers that support transform (or its vendor prefixed versions), use this one weird old trick to vertically align elements.
#child {
position: relative;
top: 50%;
transform: translateY(-50%);
}
If you have to support older browsers, you can use a combination of these, but they can be a pain due to the differences in rendering block vs table.
#parent {
display: table;
}
#child {
display: table-cell;
vertical-align: middle;
}
If your height is fixed and you need to support those really old, pesky browsers...
#parent {
position: relative;
}
#child {
height: 100px;
position: absolute;
top: 50%;
margin-top: -50px;
}
If your height is not fixed, there is a workaround.
See it on jsFiddle.
Having the parent property as, display:table and child property as display: table-cell and vertical-align: middle worked for me.
You can use flexbox to center horizontally or vertically your child div inside a parent div:
This should be your html:
<div id="parent">
<div id="child">
info
</div>
</div>
And this is the css with flexbox:
#parent{
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 100%;
height: 100vh;
background: lightgray;
}
#child{
position: relative;
background: black;
padding: 2rem;
color: white;
box-shadow: 5px 5px 20px rgba(0,0,0,.4);
border-radius: 5px;
}
Here is de codepen: https://codepen.io/bongardabo/pen/YzZQgaJ
First off, treating non-table markup as tables (with display:table and friends) isn't cross-browser. I don't know which browsers you need to support but certainly IE6 won't do this. But, if your targeted browser do all support display:table I can give you some tips.
The vertical centering approach you're looking for (using table layout) depends on having a TD with vertical-align:middle, then inside of that a single block element will vertically center. So I think what you want is:
#parent { display:table-cell; vertical-align:middle; }
#child { /* nothing necessary, assuming it's a DIV it's already display:block */ }
It's ok to use table-cell with no surrounding table-row and table, the browser infers the needed table wrapping elements for you.
here is another way when you don't know the inner div size or whatever, you may use % here and there to fix the "centering" ....
the idea is that your top value is half the height of your child element as to create the centering illusion
Here's the code:
<div id="parent">
<div id="child">
hello
</div>
</div>
and for the styling:
#parent {
position: relative;
height: 300px;
width:200px;
background-color:green;
}
#child {
height: 50%;
width: 50%;
position:relative;
top:25%;
left:25%;
background-color:red;
}
Here you can see it in action
http://jsfiddle.net/Wabxv/