Why is "display: table-cell" messing up my div's? - html

I'm trying to center the strings "1","2" and "3" vertically as seen here:
But when I use display: table-cell; vertical-align: middle; for all 3 div's, but then I get his unwanted result:
HTML is
<div id='alldivs'>
<div id='red' class='each_div'>1</div>
<div id='blue' class='each_div'>2</div>
<div id='green' class='each_div'>3</div>
</div>
CSS is
.each_div {
width: 80px;
height: 50px;
text-align: center;
display: table-cell; vertical-align: middle;
}
Demo
How do I keep the 3 div's aligned vertically while keeping vertical alignment within each div?

This is a conceptual misunderstanding. Without a parent element with display:table-row the tables cell will always span over full width, because it will create anonymous table object of table-row and table.
According to W3C Specification article: Tables
Document languages other than HTML may not contain all the elements in the CSS 2.1 table model. In these cases, the "missing" elements must be assumed in order for the table model to work. Any table element will automatically generate necessary anonymous table objects around itself, consisting of at least three nested objects corresponding to a 'table'/'inline-table' element, a 'table-row' element, and a 'table-cell' element. .....
Here is a quirksmode page showing uses of display: table and so on. A image showing the same effect as on this question.
To solve this problem semantically, you have to add an extra element to display as row.
<div id='alldivs'>
<div id='red' class='each_div'>
<div class="cell">1</div>
</div>
<div id='blue' class='each_div'>
<div class="cell">2</div>
</div>
<div id='green' class='each_div'>
<div class="cell">3</div>
</div>
</div>
Then assign relative CSS to them
#alldivs { display: table; }
.each_div {
display: table-row;
}
.cell {
width: 80px;
height: 50px;
display: table-cell;
vertical-align: middle;
border: 1px #000 solid;
}
Demo

I think there's a much simpler way, using line-height:
<div id='alldivs'>
<div id='red' class='each_div'>1</div>
<div id='blue' class='each_div'>2</div>
<div id='green' class='each_div'>3</div>
</div>
.each_div {
width: 80px;
height: 50px;
line-height:50px; // set to the same height as the div
text-align: center;
clear:both;} // add clear both to skip line
See the jsfiddle here and compare with the other answers.

You can wrap each one in another <div> with display: table-row; and it will look as you wish:
HTML:
<div id='alldivs'>
<div class="row">
<div id='red' class='each_div'>1</div>
</div>
<div class="row">
<div id='blue' class='each_div'>2</div>
</div>
<div class="row">
<div id='green' class='each_div'>3</div>
</div>
</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
CSS:
.each_div {
width: 80px;
height: 50px;
display: table-cell;
vertical-align: middle;
border: 1px #000 solid;
}
.row {
display: table-row;
}​
This is because table-* is designed to emulate a table, thus one must follow table structure to get table appearance. In this case you may just want to use a table.

I have found a work-around that works the way you want. If you wish then you can use it:
Change your CSS as:
.each_div {
width: 100%;
height: 50px;
vertical-align: middle;
text-align:center;
background:red;
}
#alldivs{
width:80px;
display:block;
}
Note that I have mentioned width:80px for the parent div alldivs
It gives the output as:
​

Related

CSS vertical alignment table method has no effect

I need to vertically align a box with CSS without using display: inline-block. As I don't know the height of my elements I used the way here described (CSS Table Method).
<div style="background-color: black">
<div style="background-color: aqua; display: table; margin: auto;">
<div style="background-color: aliceblue; width: 200px; float: left; display: table-cell; vertical-align: middle;">
<p>A</p>
<p>A</p>
<p>A</p>
</div>
<div style="background-color: green; height: 20px; width: 100px; float: left; display: table-cell; vertical-align: middle;"></div>
<div style="background-color: aliceblue; width: 250px; float: left; display: table-cell; vertical-align: middle;">
<p>B</p>
<p>B</p>
<p>B</p>
<p>B</p>
</div>
</div>
</div>
However, the vertical alignment on this test page has no effect at all. According to the computed CSS of these divs the display value is set to block! How can I make these divs appear in the middle?
erase the float:left from the DIVs - display:table-cell and float:left together makes no sense
Codepen: http://codepen.io/anon/pen/ORrNdW
ADDITION AFTER COMMENT:
Like this: codepen.io/anon/pen/NRxALO ?
I inserted /nested another DIV in each table-cell that contains the smaller elements, and assigned the background-color to the table element itself.
One way, out of many ways, you can achieve this is by setting the parent to position:relative; and its child to position:absolute; top:50%; transform:translateY(-50%);. Although this question has been answered many many times before.
Ok, I finally found the answer. You have to use the flexbox styling (display: flex). Using this method, you can center elements without specifing a height. This page describes how to use it.

Center div have height limit

I have three columns, but in the center one I can display only limited number of paragraphs.
If I add, for example, 15 paragraphs, only first 11 paragraphs will be displayed. It's like the div have set height parameter. Does anyone know how to fix this?
<div id="left" style="float:left; width:250px;"></div>
<div id="right" style="float:right; width:250px;"></div>
<div id="center" style="margin:0;"></div>
Add float:left; also to your #center element
or if you don't want it floated than: overflow:auto;
An alternative approach would be to use display: table; and display: table-cell; instead:
CSS
#container {
display: table;
width: 100%;
}
.cell {
display: table-cell;
vertical-align: top;
}
.side {
width: 250px;
}
HTML
<div id="container">
<div class="cell side">Left</div>
<div class="cell">Center</div>
<div class="cell side">Right</div>
</div>
I'm assuming these are the building blocks for your layout, with a centered area and sidebars on the left and right. Using table has the benefit that all cells maintain the same height; float can be fickle.

h1 breaks the design in a grid

I have an issue that whenever I add an "H1" tag to the grid like the following:
<div class="box">
<h1>123</h1>
</div>
the grid design breaks, Please check the following example
http://jsfiddle.net/937yhqo1/
Appreciate your help.
Update
as #chipChocolate.py answerd that the vertical align solves the issue, but I want to know the reasons, why just when we add H1 tag(any tag with display block) the grid breaks? how does the display inline-block behave at that moment?
Use vertical-align: top alongwith display: inline-block in .box.
.container {
height: 200px;
background: blue
}
.box {
height: 100px;
display: inline-block;
vertical-align: top;
background-color: red;
width: 50px;
margin: 2px
}
<div class="container">
<div class="box"></div>
<div class="box">
<h1>123</h1>
</div>
</div>

Elastic div between two fixed height/width divs

There are some answers to a similar question already, but this one has a twist.
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-3 grey">
<div class="wrapper">
<div class="info">(i)</div>
<div class="text"><div class="labeled">This is a long text</div></div>
<div class="icon">[$]</div>
</div>
</div>
<div class="col-xs-12 col-sm-9 green">
Content
</div>
</div>
So I need three divs, aligned in one line at all conditions - info, text, icon - with two divs on the sides having fixed h/w, and one in the middle taking only as much space, as
either it needs, and not more
or is available for it, cutting the context with overflow:hidden
Here is the fiddle http://jsfiddle.net/L7tmt5w1/3/
Here are my mad skills in sketching ideas http://imgur.com/tF0HkD2
For those, who want to feel my pain, you may also try re-ordering the divs - text, icon, info - when the screen size goes mobile (bootstrap's col-xs-)
You can use the display: table-cell; method for this situation:
.wrapper {
display: table;
text-align: right;
width: 100%;
}
.info {
width: 20px;
height: 20px;
display: table-cell;
background-color: #005ea8;
color: #fff;
}
.icon {
width: 20px;
height: 20px;
display: table-cell;
background-color: #eb690b;
color: #fff;
}
.text {
display: table-cell;
background-color: #ccc;
width: auto;
}
This mimics the table display properties and keeps all the children of .wrapper inline and the middle one "elastic" as it has no defined width. You can also remove the floats.
http://jsfiddle.net/L7tmt5w1/7/
maybe this solution will help you DEMO
<aside class="panel">
...
</aside>
<div class="content">
...
</div>
.content {
overflow: hidden;
border: 1px solid;
}
.panel {
float: right;
width: 200px;
border: 1px solid;
}
You can try this http://jsfiddle.net/L7tmt5w1/3/
Remember: If you want to float an element to the right, it must be the first element. For example:
<div style="float:right"></div>
<div style="float:left"></div>
AND DIV's are already block elements, so you don't have to add display:block to a DIV-element
I don't know if this is what you want: jsfiddle
if not content on "text" no div... if too much content it's hidden
(but you can add
overflow:auto
to the text div for scroll bars

clear both is not working after display table

I have following html
<div id="parent">
<div id="one">one</div>
<div id="two">two</idv>
</div>
<div id="other">some</div>
And this is the css
#one, #two{
display: table-cell;
vertical-align: middle;
height: 47px;
background: red;
}
#parent
{
display:table;
border-collapse: separate;
border-spacing: 10px 0;
}
#other{
background: blue;
height: 200px;
}
As described in the question the clear both is not working but behaving like before div as if table-cell. The solution for this is to remove display: table;. But I would like to know is there any idea without removing display: table; and display: table-cell; from #one,#two divs.
demo
It's a typo.. You should've seen the red syntax on the js fiddle
<div id="parent">
<div id="one">one</div>
<div id="two">two</div>
</div>
Demo
This here
<div id="two">two</idv>
Should be
<div id="two">two</div>
Note: You've not used clear: both; in your demo, and you don't even
require it, as you are not floating the elements, display: table; just changes the
display of the elements rendered, yes it does make them inline because of table-cell
doesn't mean they need to be cleared. You need to use clear property only when you've
floating elements.
For more info on clear: both;