Vertical-align middle with display table-cell not working on images - css

I'm trying to use the vertical-align: middle on a layout to vertically center sometimes text, sometimes images, but it's only working on text. Can anyone tell me why?
HTML:
<div>
<img src="http://jsfiddle.net/img/logo.png"/>
</div>
<div>
<span> text </span>
</div>
CSS:
div{
width:200px;
height:200px;
background-color:red;
display:table;
margin:10px;
}
img, span{
display:table-cell;
vertical-align:middle;
}
http://jsfiddle.net/9uD8M/ I created a fiddle aswell

Put border: 1px solid black on your img, span tags, then inspect both elements in the browser dev. console. You'll notice that the span defaults to 100% height of its parent, while the image has a defined height (the height of the actual image).
So you're not really vertically aligning those elements relative to the div, you're just vertically aligning the text inside the span element relative to the span :)
If you really want to use tables for vertical-centering, here's the correct code:
http://jsfiddle.net/WXLsY/
(vertical-align and display:table-cell go on the parent, and you need wrapper table on them)
But there are other ways to do this (SO has many answers to this question, just use search)

Here is one way of fixing the problem:
HTML:
<div>
<span><img src="http://jsfiddle.net/img/logo.png" /></span>
</div>
<div>
<span> text </span>
</div>
Put your img in a span, the image is a replaced element, it cannot contain children content, hence, vertical-align will not work.
CSS:
div {
width:200px;
height:200px;
background-color:red;
display:table;
margin:10px;
}
span {
display:table-cell;
vertical-align:middle;
}
See demo at: http://jsfiddle.net/audetwebdesign/Fz6Nj/
There are several ways of doing this, you could also apply display: table-cell to the parent div element, but that would be a different approach.

In order to vertically align an image inside a table cell you need to give the image a display of block.
display: block
margin: 0 auto
the margin: 0 auto is to align the image to the center. If you want the image left aligned then don't include this. If you want the image right aligned you can add:
float: right
Thanks,
G

You can try by adding -> line-height: 200px; in the span style section, I think it might work;

Related

Why does adding content inside of a layout screw up the layout?

The following layout 2 column layout will get screwed up by adding the <p>Hello</p>... Can anyone give me a clue?
<div style="width:1280px; font-size:0;">
<div style="width:640px; height:200px; background:blue; display:inline-block;">
<p>Hello</p>
</div>
<div style="width:640px; height:200px; background:yellow; display:inline-block"></div>
</div>
I could see if the height of the "p" was actually larger than 200px, but it isn't. So why doesn't it just go inside of its parent and stop messing with my layout?
To fix this, I ended up making the layout column divs relative, and using the absolute position on a child div that would be the container of the "p", but it seems like there is something obvious I am missing to make this situation simpler...
Inline-block does leave some whitespace that is undesired most of the time do to spaces in your code. The best solution I think is to float it and use 50% for the width.
div {
float: right;
width: 50%;
height: 200px;
background:blue;
}
the p tag will go in nicely.
example here on jsfiddle
other solutions and information here http://css-tricks.com/fighting-the-space-between-inline-block-elements/
Inline block items are vertically aligned as baseline by default. Add vertical-align:top
Jsfiddle Demo
div {
font-size:0; /* remove whitespace */
}
div div {
font-size:1rem; /* reset font-size*/
vertical-align: top;
}

Center aligning child divs and deal with float and fill

Consider the following: http://jsfiddle.net/Yq39W/1/
HTML:
<div class="parent">
<div class="child1">
Some text...
</div><div class="child2">
2
</div><div class="child3">
<form>
<input type="text" />
<input type="text" />
</form>
</div>
</div>
CSS:
.parent {
width:100%;
background:red;
margin:0px;
padding:0px;
}
.child1, .child2, .child3 {
display:inline-block;
border:1px solid black;
padding:10px;
}
.child1 {
background:blue;
float:left;
}
.child2 {
height:200px;
background:yellow;
}
.child3 {
background:green;
float:right;
}
How can I vertically center align the child divs, while child2 fills out the remaining space? (Meaning that the child1 and child3 will be moved down a little bit, so that the centers is aligned with center of child2)
What if height is NOT defined explicitly for any of the divs (in the example, child2 is explicitly set to 200px)? Is is still possible to align on the vertical axis?
It is important for me, that no dimensions are defined explicitly (except for parent width which would be 100% and any padding/margin on the elements).
Hope you guys can help out! :)
Assuming you mean vertical centering the child elements with child 2, then remove the floats and just add vertical-align: middle; since they are already display: inline-block. No need to declare a specific height, they'll all be vertically aligned with each other no matter what the tallest element is.
In the demo, I use <br />s to make child 2 taller without an explicit height set just to demonstrate.
Demo: http://jsfiddle.net/shshaw/jnE89/
You may want to set max-width: 33% for the children so that they won't go to multiple lines, but that just depends on the effect you're going for.
Bonus: If you want, you can use text-align: justify on the parent to ensure that your boxes cover the available space, like a grid (see Text-align: Justify and RWD or the updated demo; note that the boxes must have spaces inbetween them in the HTML for it to work)

divs of 100% width next to one another

I have up to 4 divs on the page that will have to 'sit next to' each other horizontally. Each div will have 100% width.
All, but the first one, will therefore appear off the page until I style it otherwise (ultimately using jQuery).
How can I style the divs in order to achieve this?
Markup:
<div class="wrapper">
<div class="panel">
</div>
<div class="panel">
</div>
<div class="panel">
</div>
<div class="panel">
</div>
</div>
What I've Tried
I've tried floating all of the divs left and setting the overflow of 'wrapper' to hidden. I've tried setting the display to inline-block of all the divs. I've tried position absolute on all the divs. I'm trying a combination of different things just hoping it'll work but there has to be a proper approach to this.
Tell me if some like this is what you want i use display:inline-block
http://jsfiddle.net/fdXLb/
Then i can do a better explanation.
if one div has a width of 100% there will be no space for another div to align next to this one.
so I would say to align them use only 20% width.
25% works also for 4 divs but then you can not use any borders, margin or padding.
also you can set a min-width in px.
have a look at this example: http://jsfiddle.net/3CpL8/
may it helps
.wrapper > div {
width:20%;
background-color:orange;
height:60px;
float:left;
min-width:100px;
margin:5px;
}
A nice trick is to use white-space: nowrap; to prevent divs moving to the next line. This is what your css would look like:
.wrapper {
white-space: nowrap;
overflow-x: hidden;
}
.wrapper > div {
width:100%;
background-color:red;
height:60px;
display: inline-block;
min-width:100px;
margin:5px;
}
Check out this Fiddle and use your browser's inspector it to see that the divs are still there, but off screen at the width you want. I assumed you'd want to continue using overflow-x: hidden; on the parent div so there wouldn't be an ugly scrollbar when doing the javascript side :)

Set child to content width, ignore parent width, and make parent scroll

With CSS alone, is it possible to obtain the following example, http://jsfiddle.net/LdJ7t/, without explicity knowing the child element's width before hand?
The final result desired:
parent element scrollable to child element
child element's width set to content
#Parent {
width: 100px;
height:200px;
background: #ccc;
overflow:auto;
padding: .5em;
margin: .5em;
}
#Child {
width:300px;
height:100px;
background:yellow;
}​
<div id="Parent">
<div id="Child">
This is a test. This is a test.
</div>
</div>​
It looks like display:inline-block; almost works: http://jsfiddle.net/LdJ7t/1/
I think this is possible. I just can't find a solution.
Your inline-block solution is correct - if you put longer words in or an image, the scrollbar will appear. Text is broken on white space by default.
If you don't want text breaking on white space, you can add white-space: nowrap; to the child div like here: http://jsfiddle.net/LdJ7t/2/

image not middle aligning

My image is staying at the top. Code using:
#header_div{
min-height:200px;
}
#header_div img{
display:block;
vertical-align:middle;
padding:5px 10px;
}
<div id="header_div">
<a href="#">
<img width="250" height="75" src="./images/header_logo.png" />
</a>
</div>
On a side note, should I close image tags with />?
#header_div
{
min-height:200px;
display: table-cell;
vertical-align:middle;
}
You will no longer need the vertical-align:middle; or display:block; on the img style and you probably can remove the top/bottom padding as well.
good write-up on centering an image in a box:
http://www.brunildo.org/test/img_center.html
vertical-align doesnt work like that. you can apply the image as a background-image to the parent div or to the anchor, and use background-position: center center.
if youd like an anchor's inline content to be centred vertically, one way to do it is to set the element's line-height in px to the total height required.

Resources