How do I span columns with a div-based table? - html

I would like to have a cell go across two columns with two cells below it. How do I do this in CSS with <div> elements? It should be equivalent to:
<table>
<tr>
<td colspan="2">Major column</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
Please note that C1 and C2 are not necessarily going to be 50% each. The value may change depending on their contents. I also need all items in those cells no matter how many rows there are to line up just like they would in a table.

You would want markup like:
<div class="main">
<div class="topRow">Major column</div>
<div class="leftCol">C1</div>
<div class="rightCol">C2</div>
<div>
And then some css to position them:
div.topRow {
width:100%;
clear:both;
}
div.leftCol {
width:50%;
float:left;
}
div.rightCol {
width:50%;
float:right;
}

I would recommend putting them in a container div if being used for layout.
HTML:
<div> full width </div>
<div class="column50"> left </div>
<div class="column50"> right </div>
CSS:
div.column50 {
float: left;
width: 50%;
}
In case it's unclear, there's no need to create two separate CSS classes for this case. Both of the last two divs have a 50% width, no margin, and no padding. Setting them both to 50% width and left float has the same effect as setting the right one with a right float instead.

"Please note that C1 and C2 are not
necessarily going to be 50% each. The
value may change depending on their
contents. I also need all items in
those cells no matter how many rows
there are to line up just like they
would in a table."
The above is not possible in a cross browser way, without using a table (You can simulate table layout with CSS: "display: table", but that doesn't work in IE6 or IE7).
I would suggest you think a bit differently when designing with CSS instead of tables, it's not possible to just replace "tr" and "td" with "div" and make things magically work like they used to. I suggest you set the widths of the bottom "cells", and use one of the options people have given you above.
Hope that helps!

All of the above will work, but keep in mind that elements will "escape" from their parent div in IE6. This is a pain, but IE6 support is still something most people need to think about.
The solution to escaping is to give the containing element a height or width (any will do, it will stretch to fit so usually 1% is what I use.).
Also, if setting widths, keep in mind that any borders or margin you set are in addition to the width of the elements, so if you set two divs at 50% with a border or margin, you will get a line break.

Related

Does a float need a width?

After a lot of research about floats i am confused why there is so much information on the web that a float should always have a width defined. It is often said, that the float will take the whole space and therefore behave like a normal block element. but with regard to the information here http://www.w3.org/TR/CSS21/visudet.html#shrink-to-fit-float the float will always shrink-to-fit. as i understand the float will never take the whole space unless it needs to.
when thinking about navigation items, is there a need to specify a width? i don't think in this case. maybe when content inside the float is too large?
it was also discussed here Do you really need a width on floated element? but there is no clear statement, that this is not necessary.
I don't think all floated elements require fixed widths, but perhaps any positional CSS that includes dividing your page into 3 columns, you may want to consider fixing the widths on the columns floated to left/right. One reason for this is because navigation bars or forum posts or some sort of list of hyper links is often aligned on the sides of the pages, and if these 2 columns are not fixed, the character limit of your anchor links will be limited as the screen size decreases. You may not want your inline anchor tags wrapping across multiple lines when the screen shrinks. Fixed Widths would eliminate this.
Floats dont need a width. The advantage and disadvantage as well is a collapsing container, if there is no content in it.
Have a look at: Expand div to max width when float:left is set
Deleting all p-tags in the div-tag (class right) shows the effect: no more red background
.content .left{
float:left;
width:100px;
background-color:green;
}
.content .right{
margin-left:100px;
background-color:red;
}
<div class="content">
<div class="left">
<p>Hi # all</p>
</div>
<div class="right">
<!-- no content no backgroundcolor -->
</div>
</div>

How two create a two-column dynamic layout from varied-width content with CSS?

I am trying to create a CSS for a product information page, and am having some issues with setting the width dynamically based on the content.
We want to display a product image next to a product description. The image HEIGHTS are all consistent; the image WIDTHS vary. We want the text column width to size dynamically based on what's left over after the images are placed.
Where it gets trickier is that we want the flexibility to use an image in EITHER the right or left column.
<div id="leftcolumn"><img src="yellowscraper"></div>
<did id="rightcolumn"><p>[yellowscraper text]</p></div>
<div id="leftcolumn"><p>[brown scraper text]</p></div>
<div id="rightcolumn"><img src="brownscraper"></div>
<div id="leftcolumn"><img src="marmite"></div>
<did id="rightcolumn"><p>[marmite text]</p></div>
<div id="leftcolumn"><p>[yellowscraper text]</p></div>
<div id="rightcolumn"><img src="yellowscraper"></div>
Consider:
#leftcolumn {float: left}
#rightcolumn {float: right}
.clear { clear: both;}
But I have no idea how to define the width parameter. The column that contains an image would be the width of the image. The OTHER column would be what remains...basically the container width minus the image width.
Is there some cool CSS trick to accomplish this? I suspect I may just be aligning text to the right or left of images, but I'd love to know if there's a CSS way to make this happen.
Using floats should work fine - it's not quite a columnar layout, stuff just... hangs where it wants to hang.
http://jsfiddle.net/FD5Uy/
Is that what you're asking for? Notice I only put the float on the div containing the image, instead of left on the image and right on the text:
<div class="float-left"><img></div>
<p>
The image will be to the left of this paragraph,
I don't need to float this tag to the right...
</p>
<div class="float-right"><img></div>
<p>
Same same...
</p>
You can apply the float class directly to your images if you don't need the div for anything else, it'll still work fine.
Honestly, the best way to do this is tables. Just make the borders invisible when you do it, and float the images inside the table, with the following CSS:
#left {
float:left;
}
#right {
float:right;
}
Next up, set up your table like this.
<table>
<tr>
<td><div id="left"><img src="yellowscraper"></div></td>
<td><div id="right"><p>[yellowscraper text]</p></div></td>
</tr>
<tr>
<td><div id="left"><p>[brownscraper text]</p></div></td>
<td><div id="right"><img src="brownscraper"></div></td>
</tr>
</table>
Comment if you have any questions.

Two columns layout with same height, table or div?

I need a layout with two columns where each column expand to the height of the taller column.
With table I would simply do:
<table class="parent">
<tr>
<td class="columnLeft">Column 1</td>
<td class="columnRight">Column 2</td>
</tr>
</table>
And column 1 & 2 will keep the same variable height.
With div there are some solution (involving use of overflow:hidden and more) that needs many hacks to work well cross-browser.
(jsFiddle here: http://jsfiddle.net/rJjJa/1/)
In this case I would simply use table, without needing the extra effort of CSS hacks (or lots of extra markup). Do you think table is fine for this?
If you want divs to behave just like a table, you could use display: table-cell; for each div. They should behave just like a td; both should be the same height. This should work in all modern browsers and ie8 and above.
The tag <table> is outdated for layouts! Do not use it.
Instead, there are many Cross Browser CSS Compatible 2 Column Layouts, without using any hacks. One such is, Equal height columns.
Equal height columns
It does not matter how much content is in each column, the background colours will always stretch down to the height of the tallest column.
An article, explained in detail here: Equal Height Columns with Cross-Browser CSS.

Fixing the width on multiple tables on one line

I have multiple tables displayed as inline-block elements. However, I want to fix the widths so that they will out the horizontal space, giving each table a 33% width (3 tables per row). Example code is as follows:
<table>
<thead>
<tr><th></th><th></th><th></th><th></th></tr>
</thead>
<tbody>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</tbody>
</table>
...repeat the above code 2 more times.
Now I can't seem to get it right. All the tables have the class attribute and are set to 33% width, but nothing seems to change.
Other possibility is
'float: left'
So you don't have to set width to almost 33.3%.
Just make sure you have a Clearfix on the table's parent element.
Fiddle
try this
table
{
float:left;
width:33%;
}
In the percent you have to cater for padding, margin and border issue and reduce it as necessary. You might need to add display:inline-block to the container of the 3 tables

How to make div boxes with floats have the same height with dynamic content

In tables, if you have a row, that row is the same height and all cells in the row grow and shrink with dynamic content. (If one cell has a ton of text and the other cells not much they are all the same height, letting you make columns and rows).
With the popularity of div float layouts using tables is often frowned upon. However how do I duplicate this and other functionality and benefits of a table while still keeping the display set to block for the benefits of a block, cross browser?
I've seen many hacks but they always seem to be too complicated, interfere with each other, or take tweaking. I am looking for a standard reliable method for the following:
Make div boxes the same height across a row with a wrapping container
<style>
.cell { float:left; }
</style>
<div class="row">
<div class="cell">Content 1 with more width</div>
<div class="cell">Content 2<br>with<br>more<br>height<br>Content 2<br>Content 2<br></div>
<div class="cell">Content 3</div>
</div>
In this case all div's of class "cell" will have the same height, and not be fixed height at all and be floated and will stay that way for dynamic content of any size.
Vertically center content
In this case using the example above, all content would be vertically aligned to the middle, for dynamic content of any size.
Make div's of class "cell" share a common width that is based on the wrapper "row"
In a table when you specify width as 100% or fixed width the cells will automatically try to all be the same width, unless an image or block like item prohibits this. How can this be achieved with floating divs? As if you say, float all "cell" to the left, you can specify a min width or a fixed width, but I know of no way to make them share a common width that is dynamic, like a table. In floated divs by themselves they shrink to the size of the content.
How to avoid content pushing against the container/wrapper "row" and treat it as if it were just a block
For whatever reason when a floating div is inside a wrapper you can get odd behavior where content will "stick" to the wrapper as if were floating too. Even sometimes when using a <br style="clear:both"> at the end I had this happen.
If you could answer all these questions about floating divs for me it is most appreciated. Please don't tell me to break this into separate questions as they are all related to the same thing. Please don't tell me this would be better asked somewhere else. If however you wish to be helpful great :)
If the solution is using display:table-cell alone, I've tried this, it makes the divs not behave as a block, shrinking it, the background shrinks to the content too, and in other ways it does not behave as a block. Also some versions of IE do not support this and I am looking for a cross browser solution. Thank you.
If you want your div elements to behave like table cells, you can style them that way:
.row {
display: table;
width: 100%;
}
.cell {
display: table-cell;
width: 33.33%;
vertical-align: middle;
text-align: center;
}​
This does not rely on setting a height or min-height on the .cell elements, so the height will remain flexible.
--- jsFiddle DEMO ---
You may apply the CSS like this;
.row{
height: 200px;
}
.cell{
display:block;
float:left;
height:100%;
}
Here is a working Live Demo.
and Here is a workaround to distribute the columns also.
Hope this helps
Note: DO NOT add percentage attribute to child divs to fill parent div (for example 50% each for 2 child divs, 25% for 4 child divs etc) since these vary according to number of divs and cannot be calculated accurately sometimes
Well, I went the jQuery route...
http://jsfiddle.net/dtgEt/1/
I would like to point out that while yes, some people will just use a table, a table is for displaying tabular data, not layout. A div has no semantic meaning and therefor is a better choice, in my opinion (unless it is actually tabular data that your are publishing to the web).
My solution works in IE 7 and probably would in IE 6. If you want to align your content in the center of the container there are many good ways to do that others have suggested (beat me to it).
If you need the formatting of a table, but you have to support older browsers that don't have support for display:table, then use a table. It's pretty much that simple.
Sometimes a table is the appropriate option, and sometimes it's the only option that will work without adding some moderately-risky JS or jQuery to simulate the formatting of a table.
For instance, a table (or display:table, which amounts to the same thing) is the only natural way to have true vertical centering of dynamic content. It's also the only natural way to enforce equal-height columns for dynamic content. And in general, a table is appropriate anytime you need to display a data grid of some sort.