Make two parallel `<div>` colums the same height - html

Suppose I have two columns, both represented by a <div> block. Both columns may grow larger than the other, so I want to force the smaller one to grow as big as the other.
Example of my problem: http://jsfiddle.net/TvnSJ/
As you can see, the second column is smaller.
I managed to solve this using tables, but I was unable to add margin between them. The margin is important, so I would like to know another solution.

You can use display: table and display: table-cell. Here is your fiddle updated: http://jsfiddle.net/TvnSJ/2/
This makes the divs render like tds. Basically you can get the layout of a table without using a table when it is semantically incorrect. I don't think you can float them however.
Edit: I just noticed the bit about margin. You can add padding to these, or you could wrap the content in another element and add margin to that if you need the separation to not include the background colour.

This can be achieved in CSS3 with the new box model:
.box {
width:100px;
display:box;
/* Firefox */
display:-moz-box;
-moz-box-orient:horizontal;
/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-orient:horizontal;
/* W3C */
display:box;
box-orient:horizontal;
}
.box .column1 {
-moz-box-flex:1.0; /* Firefox */
-webkit-box-flex:1.0; /* Safari and Chrome */
-ms-flex:1.0; /* Internet Explorer 10 */
box-flex:1.0;
background: yellow;
}
.box .column2 {
-moz-box-flex:1.0; /* Firefox */
-webkit-box-flex:1.0; /* Safari and Chrome */
-ms-flex:1.0; /* Internet Explorer 10 */
box-flex:1.0;
background: green;
}
And the HTML
<div class="box">
<div class="column1">
a<br>b
</div>
<div class="column2">
a
</div>
</div>
I made this with the examples from here http://www.w3schools.com
Fiddle http://jsfiddle.net/w5ELr/

Here's another approach using 2 containers that I used recently
<div class="container2">
<div class="container1">
<div class="col1">
a<br />b<br />c
</div>
<div class="col2">
a
</div>
</div>
</div>
CSS:
.container2 {
clear:left;
float:left;
width:100px;
overflow:hidden;
background:blue; /* column 2 background colour */
color: white;
}
.container1 {
float:left;
width:100px;
position:relative;
right:50%;
background:green; /* column 1 background colour */
color: white;
}
.col1 {
float:left;
width:46%;
position:relative;
left:52%;
overflow:hidden;
}
.col2 {
float:left;
width:46%;
position:relative;
left:56%;
overflow:hidden;
}
Fiddle: http://jsfiddle.net/Lunf6/1/
Inspired from: http://matthewjamestaylor.com/blog/equal-height-columns-2-column.htm

if you want the same but using table:
<table style="width: 100%;">
<tbody>
<tr>
<td style="background: #006600;">a<br/>b</td>
<td style="width: 5px;"></td>
<td style="background: #BB0000;">a</td>
</tr>
</tbody>
</table>
you can style your table and its cells as you like with paddings, margins, etc:
.TABLE-DEFAULT{
border : 0px;
border-collapse : separate;
border-spacing : 0px;
width : 100%;
background : transparent;
}
.TABLE-DEFAULT td{
padding: 4px;
}
.TABLE-DEFAULT td:FIRST-CHILD{
padding: 0px;
}
.....etc

Despite question #2 solves the question fully and satisfactorily, it has a big drawback to consider: It doesn't works in IE7 and below.
If you need too support old browsers, there's another approach based on padding, margin and overflow properties. It's a little bit tricky, but it works:
Define a container div, which works as a "colum-row", like this:
<div class="column-row"></div>
.column-row {overflow: hidden}
Then put some columns in it. And style them setting padding and margin to force a fake overflow:
<div class="column-row">
<div class="column">Column 1</div>
<div class="column">Column 2</div>
...
</div>
.column-row {overflow: hidden}
.column {float: left; padding-bottom: 99999; margin-bottom: -99999}
So, you'll get a bunch of columns which they looks equal sized, where their height value corresponds to the largest one.
I have edited the previows jsFiddle (now at http://jsfiddle.net/TvnSJ/16/) if you want to play with a working example.

To get two divs the same height automatically after adding content to one, you'll need to use javascript or jquery. Here is the below jQuery that can do this for you. Just change #column-1 to the ID of your first colum and #column-2 to the ID of your second column.
$(document).ready(function(){
x = $('#column-1').height();
y = $('#column-2').height();
if x > y {
$('#column-2').height(x);
else {
$('#column-1').height(y);
}
});

Related

How to approximate table layout with css when structure is disjointed

I have some HTML which I want to use display: table css attributes to control. Unfortunately, I cannot actually change the HTML (or JS either), only the CSS (long story). This is a problem, because the structure of the existing HTML is causing trouble for the table layout. Here is a simplified version of the HTML and CSS:
<style>
.like-table { display: table;}
.like-tr { display: table-row;}
.like-th { display: table-cell; border: 1px solid gray;}
.useless-div-1 { }
.useless-div-2 { }
.like-td { display: table-cell; border: 1px solid gray;}
</style>
<div class="like-table">
<div class="like-tr">
<div class="like-th">1</div>
<div class="like-th">22</div>
<div class="like-th">3</div>
</div>
<div class="useless-div-1"><div class="useless-div-2">
<div class="like-tr">
<div class="like-td">111</div>
<div class="like-td">2</div>
<div class="like-td">3</div>
</div>
<div class="like-tr">
<div class="like-td">11</div>
<div class="like-td">2</div>
<div class="like-td">333</div>
</div>
</div></div>
</div>
Sadly, this renders the header and body columns width different widths:
If I remove the "useless-div-*" open and closing tags:
<div class="like-table">
<div class="like-tr">
<div class="like-th">1</div>
<div class="like-th">22</div>
<div class="like-th">3</div>
</div>
<div class="like-tr">
<div class="like-td">111</div>
<div class="like-td">2</div>
<div class="like-td">3</div>
</div>
<div class="like-tr">
<div class="like-td">11</div>
<div class="like-td">2</div>
<div class="like-td">333</div>
</div>
</div>
Then it renders fine, aligning header and body column widths:
So, is there anything I can do to the CSS that will cause the first set of HTML to behave like the second? Remember I cannot modify the HTML or JavaScript -- only the CSS! Please do not ask why...
Click here to tinker with the code.
Since you're wrapping table-row elements by useless-div, you could simply set display property of useless-div to table-row-group:
.useless-div { display: table-row-group; }
In CSS table layouts, all elements should follow the same structural properties.
Here is the JSBin Demo.
Update
After scratching my head for the past 5 hours over this, I realized that it's impossible to handle this by the current way.
So, I decided to write new styles to create a flexible CSS table. But I should mention a few things at first:
To keep the columns aligned vertically, setting a specific width to cells is required.
In the following example, I set borders to display the table better. because of that, I used box-sizing property to force browser to calculate the width of each cell including its padding and border. If you don't need border, remove it and the border-box property as well.
The Approach
.like-table {
width: 400px; /* You could declare a specific width. Your choice */
margin: 0 auto;
}
.like-th, .like-td {
float: left; /* <-- Float the cells to stick together */
width: 33.33%; /* <-- I applied the same width on each cell. */
/* I've explained how to set specific width for each column in the following */
border: 1px solid gray; /* Add border around each cell */
-webkit-box-sizing: border-box; /* Force browser to calculate width+borders */
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.like-tr:after { /* Clearfix hack */
content: ' ';
font: 0/0 a;
display: block;
clear: both;
}
Note: To apply specific width on each column (left + center + right), First set a width on each cell as I did at above, then use the following selectors to override the applied width for left and right columns:
.like-table .like-td:first-child, /* Selectors for the left column */
.like-table .like-th:first-child {
width: 100px; /* <-- Override the width for the left column */
border-right: 0; /* You might also want to remove right borders */
}
.like-table .like-td:last-child, /* Selectors for the right column */
.like-table .like-th:last-child {
width: 100px; /* <-- Override the width for the right column */
border-left: 0; /* You might also want to remove left borders */
}
JSBin Demo #1. (fluid width)
JSBin Demo #2. (fixed width)

Table is mispositioned in Firefox

I have bunch of inline div's, followed by a block div. Inside block div, there should be table, something like that:
<div class="myInlineDiv"></div>
<div class="myInlineDiv"></div>
<div class="myBlockDiv">
<table>
...
</table>
</div>
Problem is: table is misaligned in FireFox. It works well in Chrome and IE.
Here is fiddle: http://jsfiddle.net/zk9eD/2/ Red block should be in yellow area.
(I can fix position problem with position: inline; but it causes another problem with table width).
Add float:left; in table class
.table1 {
background-color: red;
width: 100%;
border: 0px;
float:left;
}
Check working demo - http://jsfiddle.net/zk9eD/5/

Problem creating equal height columns in CSS

I have been using the examples here to setup a webpage that has columns with equal heights (using only HTML and CSS), and it is working relatively well. Here is the complete HTML and CSS code that I am using.
Newbie questions:
(1) As you can see, I tried to make the left column (id="column_bottom") have a white (#f5f5f5) background with black text, and the right column (id="content_bottom") with black background with white (#f5f5f5) text, but one side is always overriding the other. What can I do to make it what I want?
(2) Also, you can see in the CSS that I have defined fonts and background colors for body, but somehow that is not carrying through, what should I do?
Thanks!
P.S. I am looking for a pure HTML/CSS solution, and prefer not to use javascript.
You're close. In your code, just change your styling to the columns themselves, like so:
#content_bottom {
color: #f5f5f5;
background:#000000; /* right column background colour */
}
#column_bottom {
color: #000000;
background:#f5f5f5; /* left column background colour */
}
the code below will create two boxes side-by-side and the container will always wrap those boxes, no matter how tall they are. this should solve your issue of having columns of the same height.
html:
<div class="container">
<div class="box">blah</div>
<div class="box">blah<br/><br/>blah</div>
<div class="clear"></div>
</div>
css:
.container { position:relative; width:100px; border:1px solid red; }
.box { position:relative; float:left; width:40px; border:1px solid blue; }
.clear { clear:both }

How can I add padding to a textarea without causing the width to increase?

I've been having trouble setting a textarea element's width and using padding via CSS. The padding value seems to change the width of the textarea, which I'd rather it not do.
This is my HTML code:
<div id="body">
<textarea id="editor"></textarea>
</div>
And my CSS code:
#body {
height:100%;
width:100%;
display:block;
}
#editor {
height:100%;
width:100%;
display:block;
padding-left:350px;
padding-right:350px;
}
However, the padding values do not appear to work as one would expect. The width of the textarea is increased by 350px in both directions, rather than defining space between the borders of the element and its content.
I've considered just centering the textarea by setting the margins at "0px auto", but I would like the user to still be able to scroll through the textarea if the mouse is hovering over one of the empty margins. For the same reason I can't add another div to act as a wrapper, as the user wouldn't be able to scroll along the empty areas but only along the margin-less textarea.
Can anybody help?
The CSS box model defines "width" as the width of the content, excluding border, padding and margin.
Fortunately, CSS3 has a new box-sizing property that lets you modify this behaviour to instead include padding etc. in the specified width using:
box-sizing: border-box;
According to the link above, most modern browsers (including IE >= 8) support this property, but they have different names in each browser.
Specifying widths and margins/padding in '%' helps.
Here is one example -
Live # http://jsfiddle.net/ninadpachpute/V2aaa/embedded/result
#body {
background-color:#ccc;
height:100%;
width:100%;
display:block;
}
textarea#editor {
border:none;
width:80%;
height:100%;
margin-left:10%;
margin-right:10%;
}
The width specified by CSS does not include padding or border (in accordance with W3C specifications). I guess one way of doing it is with some JavaScript that sets the width of #editor to the width of #body minus 700px, but that's a bit messy... Not sure if there's a CSS way of doing what you want here. Of course, you could use margin then register the onMouseWheel event to the #body and work with that...
Some browsers allow you to target the placeholder for changing the color etc., so you can add padding as well:
::-webkit-input-placeholder { /* WebKit browsers */
padding: 5px 0 0 5px;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
padding: 5px 0 0 5px;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
padding: 5px 0 0 5px;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
padding: 5px 0 0 5px;
}
Just add a simple border:
border-bottom: 1em solid white;
Feel free to use the desired color and size. You could also use border-top, border-left, border-right or just use border. To make it act like padding, just make sure that you add the same color as the background-color
.parent, textarea{
width:100%;
}
.parent{
display:flex;
}
textarea{
border:1em solid black;
}
<div class='parent'>
<textarea rows="5"></textarea>
</div>

Make an element centred when it is alone, but aligned to the right when with another element

We have a page that ordinarily has two elements arranged side-by-side. Despite exploring a few angles for this, we can't seem to make it work. We're not averse to using JavaScript, it just feels that a CSS based solution ought to be possible. Is there a way of using just CSS (and possibly extra markup if necessary) to make element2 centre when it appears on its own?
Examples
Sometimes we have two elements, side by side.
<div id="container">
<div id="element1">content</div>
<div id="element2">content</div>
</div>
But in some conditions only element2 is on the page e.g.:
<div id="container">
<div id="element2">content</div>
</div>
There is a pure css solution, however it won't work in versions of IE less than 7 because it won't understand the sibling selector (+), for that you may want to consider a JavaScript solution (perhaps Dean Edwards' IE7). Anyway, some example css:
div#element2{
width:100px;
margin:0 auto;
}
div#element1{
width:50px;
float:left;
}
div#element1 + div#element2{
width:50px;
float:left;
margin:0;
}
The key is the line div#element1 + div#element2 which selects div#element2 given that it directly follows div#element1.
I think Phil was on the right track, but you should try using the CSS last-child pseudo-class. As far as I know, first-child and last-child are the only way in CSS to approximate an if construct.
div#container div#element2:last-child {
width:100px;
margin:0 auto;
}
div#element1{
width:50px;
float:left;
}
div##element2{
width:50px;
float:left;
margin:0;
}
The CSS above basically says "if element2 is the last child element of its parent use this set of styles, otherwise use these other styles.
This should even work in IE7.
A strict CSS2 solution:
#container {
text-align:center;
}
#element1, #element2 {
display:inline-block;
}
The inner elements should layout like inline text inside #container, but remain blocks inside.
This is standard CSS, but getting browser support might take some trickery.
it's not cool solution becouse tables are not "trendy" anymore but it solves the problem completly (under all ie)
<style>
#container {
margin:0 auto;
width:100px;
}
#container table{
width: 100%;
text-align:center;
}
#element1{
background-color:#0000ff;
}
#element2 {
background-color: #ff0000;
}
</style>
<div id=container>
<table cellspacing=0 cellpadding=0>
<tr>
<td id="element1">content</td>
<td id="element2">content</td>
</tr>
</table>
</div>