vertical align is not applied? - html

I have a Div which has display:table
JSBIN
<div class='wrapper'>
<input type="checkbox" class="b" />
<span class="c" >aaa bbb ccc</span>
</div>
And this css :
.wrapper
{
display: table;
border:solid 1px red;
height:40px;
width:200px;
}
.b
{
border:solid 1px green;
display: table-cell;
vertical-align: middle;
}
.c
{
display: table-cell;
vertical-align: middle;
}
As you can see - Both .b and .c has display: table-cell; vertical-align: middle;
Question
Why does the checkbox is not aligned vertically while the span is ?
NB
I know I can use padding etc to manually alignt the checkbox. But Im looking for the solution with table-cell and vertical align ( which should work)

You need to inherit the height from your table down to your table cells:
.wrapper
{
display: table;
border:solid 1px red;
height:40px;
width:200px;
}
.b
{
border:solid 1px green;
display: table-cell;
vertical-align: middle;
height: inherit;
}
.c
{
display: table-cell;
vertical-align: middle;
height: inherit;
}
See demo at http://jsbin.com/IdOFUmi/23/edit
The reason is that input elements don't quite behave the same as other inline elements. For some reason, setting a height to the table cell fixes the problem.
The best explanation that I can offer is based on my reading about the CSS Table model
and the generation of missing table elements:
http://www.w3.org/TR/CSS2/tables.html#anonymous-boxes
In this case, the input element, being a replaced element, cannot be a table cell. As a result, an anonymous table-cell wrapper is generated internally by the CSS engine.
However, the anonymous table-cell does not seem to recognize the the height of the parent table.
If there is a height specified on the element, then the anonymous table-cell applies it.
The best of evidence for this explanation is that the following CSS also gives the same result:
.b
{
border:solid 1px green;
/* display: table-cell; OMIT THIS */
vertical-align: middle;
height: inherit;
}
without the explicit display: table-cell property, the anonymous element will be drawn and the height property is needed to get the vertical alignment to work.

Try this:
.wrapper
{
display: table-cell;
border:solid 1px red;
height:40px;
width:200px;
vertical-align: middle;
}
.b
{
border:solid 1px green;
}
div span
{
border:solid 1px gray;
}
Working: http://jsbin.com/IdOFUmi/11/edit
You're actually want that .wrapper will behave as table-cell , in this case it will be possible to place its children in the center.

Related

Centre div inside div using display: table

I have the following:
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
display: inline-block;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>
I can't work out why the inner most div isn't being centred? I did look at some of the answers here regarding centring however I can't see what the problem is...
I want the hello to be centred vertically to the centre but not horizontally. All other divs are positioned how I want them. There is no error in the other divs they are positioned side by side for a reason. The only change I want is the hello div moved vertically to the centre
You are just overiding your inner div with
#outterFields div {
display: inline-block;
}
Just remove it or if you where intending a direct child do:
#outterFields > div {
display: inline-block;
}
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
/* display: inline-block; */
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>
Your outterfields display inline block is overwriting other display items. I came up with better solution for you. I haven't used table but used flex here learn about flex it's more worth.
#outterFields {
background-color:red;
width:60%;
min-width:300px;
height:300px;
}
#innerLabels, #innerFields {
display:flex;
align-items:center;
width:200px;
height:200px;
border: 1px solid #000;
}
.innerLabel {
display:flex;
align-items:center;
border: 1px solid #000;
height:100px;
width:80%;
}
.innerLabel div {
display:table-cell;
vertical-align: middle;
border: 1px solid #000;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel"><div>hello</div></div>
</div>
</div>
The necessary and most often sufficient condition where you can center a div using a display: table-cell, is as follows:
<div id="a">
<div id="b">
<div id="c">Helo</div>
</div>
</div>
CSS as follows:
body, html {
height: 100%;
}
#a {
display: table;
width: 100%;
height: 100%;
}
#b {
display: table-cell;
vertical-align: middle;
}
#c {
margin: auto;
text-align: center;
}
You need html and body elements to actually span the entire height of the document area if you want your a div to be able to make use of its 100% height. If your use case demands height that does not depend on the height of the document body, you don't have to use the body, html selector.
When you use display: table the otherwise auto-expanding width for a div element (width: auto implicit rule) does not apply the same way anymore as elements with display: table use a conservative width calculation -- they only by default take as much space as the content requires. Since I am illustrating a "100% 100%" centering to you, I have width: 100% there to have the element expand to available parent width.
height: 100% is likewise needed to have the element expand to available parent height. It does not matter if its display: block as with regular div elements, or display: table -- you need to specify height if you want computed height that goes beyond content height.
The display: table-cell rule only works if there is an ancestor element with display: table, hence you need at least two elements inside one another to apply display: table-cell to the one that is contained in the other. You don't need to specify height because elements with display: table-cell occupy available parent height automatically.
vertical-align rule for the display: table-cell elements is the only case where the alignment applies to the content inside the element, as opposed to its usual behavior where it applies with regard to how the element is positioned within the parent. Meaning that in our case, the vertical-align tells the browser that everything contained in the element with display: table-cell is to be centered vertically within its computed height.
For the c element you would need margin: auto only if you had content that did not completely fill available parent width. Since div elements normally do, it is not necessary, but is forward thinking on my part -- in case you decide to use span or something else that computes its width conservatively. The text-align speaks for itself -- The anonymous textual content and text inside descendant elements, will be centered in the middle along horizontal axis.

How to prevent nested elements from wrapping without specifying widths

I'm having trouble keeping two nested inline-blocks aligned without specifying widths. I can get the behavior I want using tables but would prefer to use simpler markup. Here's the basic markup:
<div class="error">
<i></i>
<div class="message">Ruh oh</div>
</div>
Here is the basic css:
.error {
border: 2px solid red;
padding: 8px 10px;
}
i {
display: inline-block;
width: 45px;
vertical-align: middle;
}
.message {
display: inline-block;
vertical-align: middle;
}
Here are the requirements:
.error can be any width (usually 100%)
i will be fixed width (usually 45px)
.message will fill the remaining width of the parent .error
both i and .message will be vertically aligned in the middle
.message cannot wrap under i
no javascript
Here is a fiddle showing a good line (short error), a bad line (longer error messages wrap below the i) and a working example with tables (but I don't want tables). Please enlighten me!
http://jsfiddle.net/3m2db1hw/
you need to use display:table to parent Div and display:table-cell to children i.e. <i> and <div>
.error {
border: 2px solid red;
padding: 8px 10px;
display:table;
}
i {
width: 45px;
vertical-align: middle;
display:table-cell !important;
}
.message {
display: table-cell;
vertical-align: middle;
}
here is edited jsfiddle
http://jsfiddle.net/3m2db1hw/1/

Width of the tables inside an inline-block element

I have two inline-block elements(width: 50%) inside a div(width:100%).
inside the first inline-block element i have table with many columns. This table is not rendered in its given 50% width. (It comes under the second inline-block element.)
<style>
#col1 {
display: inline-block;
background-color: red;
width:50%;
vertical-align: top;
}
#col2 {
display: inline-block;
background-color: green;
width:50%;
vertical-align: top;
}
</style>
<div>
<div id="col1"><table><tr><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td></tr><tr><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td><td>hai</td></tr></table></div><div id="col2">content</div></div>
Refer this example in: http://jsfiddle.net/6L3h8h7k/
In the above example,the first row of the table its overlapped by the second inline-block element.
How to make this table to occupy only the 50% width.
Some one kindly help me sort out this problem.
Thanks in advance.
Add this style to your table
table {
width: 100%;
table-layout: fixed;
}
JSFiddle is here
Change your css to this one
#co {
display: inline-block;
}
#col1 {
background-color: red;
width:50%;
float:left;
}
#col2 {
float:right;
background-color: green;
width:50%;
}
tr td { display:inline-block;}
Add "co" id to your first div
<div id="co">

Positioning text against the bottom of a block element

Given the following, how can I place the text foo at the bottom of the block div element?
<div style="width:100px; height:100px">foo</div>
You add display: table-cell and vertical-align: bottom:
div {
display: table-cell;
vertical-align: bottom;
background: red;
}
<div style="width:100px; height:100px">foo</div>
Add another one using pseudo-elemet :before(height must be equal of div height):
div {
background: red;
}
div:before {
content: "";
display: inline-block;
vertical-align: bottom;
position: relative;
height: 100px;
}
<div style="width:100px; height:100px">foo</div>
Put it in a separate element with:
position:absolute;
bottom:0;
And give the parent position:relative to establish a new positioning context.
Example fiddle.
Try playing with beautiful and modern flex-box:
<div style="width:100px; height:100px; display: flex; align-items: flex-end;">foo</div>
Keep in mind that it's absolutely mandatory to keep styles where their place is:
.myDiv {
width:100px;
height:100px;
display: flex;
align-items: flex-end;
}
I'm aware that this approach is not 100% supported but yet another addition to the tons of answers which are about to show up.
Moreover, I wouldn't take IE8 into account those days.

Is it possible to center text in a div both vertically and horizontally?

I mean by not using any other tags...just one tag and the CSS for it.
So
http://jsfiddle.net/EqTsu/
<style>
#test{
width: 100px;
height: 100px;
text-align: center;
border: solid 1px #ff0000;
}
</style>
<div id='test'>foo</div>
needs what to center vertically?
Per Answers Below
It needs
display: table-cell;
vertical-align: middle;
There's a sort of hack-ish work-around where you give the <div> the display: table-cell; property and then the vertical-align: middle; property, yes.
So the complete CSS would be:
#test{
display: table-cell;
vertical-align: middle;
width: 100px;
height: 100px;
text-align: center;
border: solid 1px #ff0000;
}
Also, external stylesheets are your friends.
Here's a jsFiddle using your code:
http://jsfiddle.net/EqTsu/2/
Adding display: table-cell; will cause the element to be treated like a cell in a table, which then enables you to use the table formatting CSS vertical-align: middle;.
Understanding vertical-align, or "How (Not) To Vertically Center Content"