Is there a simple 3-column, pure CSS layout? - html

One that doesn't require the following:
Reliance on images (i.e. "faux columns")
Some kind of weirdness or "hack" put in specifically for IE
Requires IE to run in quirks mode
Doesn't have strangeness like one of the three DIVs overlapping the others (i.e. "holy grail")
Margins set to high negative numbers placing them well off the viewscreen (again "holy grail" layout)
I can't find a 3-column layout in CSS that doesn't rely on one of the above. And relying on one of the above seems to negate a lot of the advantage of using CSS over tables. I don't want to have to whip out Photoshop and resize an image every time I want to change the width of my left column. And I don't want to have to pull out the calculator to figure out how many pixels off the side of the screen my DIV has to be.
I should mention that I'm looking for an equal-height layout.
Anyone?
EDIT: I'm looking for a width of 100%, with the center column being liquid.
EDIT: I'm also hoping to specify the width of the left and right columns in pixels.
EDIT: Backgrounds can be transparent, but I would like a dividing line between the columns which runs all the way up and down.

There is no such thing as "simple" when you talk about CSS.
But there is a simple solution that is cross browser, degrades gracefully and is fully HTML and CSS compliant: use a table with three columns.
Reasoning: DIVs are not meant to have the same dynamic height. Therefore, CSS has no support for this. If you need a block element which makes sure that its children have the same height, then that's what tables are for.
[EDIT] Sorry to offend all you CSS fanatics out there but, frankly, when something is not designed to do something and you abuse it, and it doesn't work, please stop complaining, ok? A DIV is not a TABLE and can't be used as one without relying on hacks.
[EDIT2] As was said already in various places, the reason not to use tables for layout was that, in early times, tables were the only design element and that lead to HTML which had dozens of nested tables. That's bad. But that doesn't mean you must not use a single table to put everything in place and then rely on CSS to make the stuff inside look right.
A brain is like a parachute: It's nice to have but only useful when it's open.

You might be able adapt:
http://matthewjamestaylor.com/blog/perfect-3-column.htm

I agree with Robert. Due to browsers interpreting CSS rules and rendering the final page differently I doubt you'll find a perfect solution without being more flexible in your requirements.

You can achive this by using jS.
If you were to create 3 Divs one float left one flot right and the middle as margin left & right with a width to centre it.
Then with a bit of JS each div having their own ID you could calcultate their height set the 2 lowers ones to the highest value.
Pretty simple with Jquery.

http://960.gs/
This one can be used for a 3-column layout (and for various other layouts). Personally, I don't think it's a great idea to use divs for everything, but it's simple and well .. it works.
edit: For a 100% width layout http://www.alistapart.com/articles/fluidgrids/ may help, but I'm not sure if this kind of layout still qualifies as "simple".

YAML
"Yet Another Multicolumn Layout"
(YAML) is an (X)HTML/CSS framework for
creating modern and flexible floated
layouts. The structure is extremely
versatile in its programming and
absolutely accessible for end users.
It contains some IE bug fixes, but you can remove them.

divide page into three columns, same height?
<html>
<head>
<style type="text/css">
#col_wrapper{
height: 400px;
}
.col{
width: 33%;
float:left;
height: 100%;
}
</style>
</head>
<body>
<div id="col_wrapper">
<div class="col">
one
</div>
<div class="col">
two
</div>
<div class="col">
three
</div>
</div>
</body>
no quirks and pretty plain.

Related

Research on creating grids that combine percentage and static (e.g. pixel) values in CSS

I just want to make a research that concerns responsive web design. Don't treat this question like a problem that must be solved. It's just an experiment :)
Sometimes we need to combine percentage and fixed values for dimension calculation especially when it comes to create some responsive layouts. As far as I'm concerned I've found four ways to achieve the desired effect in pure CSS.
Problem
Let's have a quick look on the problem - we need to create a three column layout stretched to the entire width of page where one of the column has a constant width and each remaining column fills out half of the available space.
<main>
<section>
<article class="first">
I fill out half of the available space!
</article>
<article class="second">
I fill out half of the available space!
<strong>Be aware that contents of article and aside may be changed!</strong>
</article>
<aside>
I'm 50px width!
</aside>
</section>
</main>
We have to achieve following layout without modifying HTML structure, contents of <article> and <aside> may be changed. Only pure CSS solutions will be accepted.
Solution 1 - Cross-browser fixed layout table
Example: FIDDLE
The width of each column in default table is calculated automatically and depends on the content of cells. In order to resolve the problem we need to force the size of the column, so this solution uses table that has table-layout property set to fixed. It allows to set the width of any column.
It is probably the most supported solution (read more).
Solution 2 - Making use of calc() function
Example: FIDDLE
The calc() function enables us to combine percentage and fixed values, for example:
article {
width: calc(100% - 50px);
}
Unfortunately this is not cross browser solution (read more) and it is recommended to use fallbacks (read more).
Solution 3 - Flexible flexbox
Example: FIDDLE
This is probably the future of responsive web design. I've implemented desired layout in an instant. Flexbox offers a lot of interesting features (read more).
You can read here about the compatibility.
Solution 4 - Margin manipulation and absolute positioning
Example: FIDDLE
This is another well supported solution. Absolute position is applied to the static aside element, section has appropriate right margin, 50% width is added for both article elements.
Summary
That's a very common problem in responsive world and I am very curious if there is any other ideas how to resolve it in pure CSS. Any thoughts on that will be appreciated.
Footnotes
Try to shrink fiddle's preview pane to the minimal width - in my opinion good, worthy tables still behaves most predictably ;)
Regards.
(Edit: this one is similar (/simplified) to the OP's Solution 1 and AFAIK he covered all of the most popular solutions out in the wild. To recap, this one is a neat way to make it cross-browser compatible)
jsBin demo
...would be to simply mimic the way table does it,
and prevent stretches using table-layout: fixed;:
article, aside {
display:table-cell;
}
aside {
width: 50px;
}
section {
display:table;
table-layout: fixed;
width:100%;
}
See also: Two column template with static and responsive width
NOTE! Don't forget you can nest elements inside the two-column version or other versions to create different variants.
I broke your conditions slightly by putting the two articles into a container element '.left' but this is the technique I usually use. Give the aside a fixed width and give the responsive content a padding-right of the same amount so that they don't overlap.
http://jsfiddle.net/John_C/fhvp3pod/
.left{
padding-right:50px;
}
aside{
position:absolute;
top:0;
right:0;
width:50px;
}
The main disadvantage of this method is that the aside is outside the main rendering tree so, if the aside is longer than the main content, it won't push down the page following elements.

"Better" floating in CSS

I'm experimenting with CSS and the float property. I have this "website", with a lot of divs aligned to 80px grid and float: left:
Is there a way in CSS to make it looking like this - so the elements can use empty space above them?
Without JavaScript, if it's possible.
Thanks, Martin.
No, this can't be done in CSS. Best way is to use a javascript item called masonry I'm afraid.
http://masonry.desandro.com/
For tiling dynamic content both horizontally and vertically, the CSS options are:
float:left, as you've already seen, only offers limited horizontal tiling.
display:inline-block gives a different result than float:left, but with no tiling.
CSS multi-column layout isn't fully defined yet. It supports vertical flow into implicit columns, but probably not in a way that qualifies as tiling.
flexible box layout isn't well supported yet. It supports a type of horizontal or vertical flow that might not qualify as tiling, though it feels like a step in the right direction.
In short, even the CSS standards that aren't fully defined yet don't seem to support this; so it may be a long ways off. The simplest fallback option is to use a jQuery plug-in.
Besides Masonry (as #Billy Moat suggested), another couple jQuery plug-ins are Isotope and Tiles Gallery. Masonry seems to be mentioned the most often.
lets say that the number of px to go up to fill the space of 1 block is 50px. margin-top: -50px;
It's not magic, it's only a bit manual to do that for each ones. If your content is dynamic, this could not work, or need js to calculate if we need to go up or not, on multiple rows and everything.
this can be done, but as CHE says, if your content is dynamic, this will go wrong in the worst possible ways.
But if it is a static site, this can be done, for sure.
To solve this, think in blocks & group and align them, inside each block re-align all blocks.

CSS Equal Height Columns - Ugh! Again?

Right, worst question in the history of web design. Who cares, just choose an option. So my question is like this...
What is the best answer to be standards compliant and (backwards) browser compatible?
jQuery used for layout which is supposed to be reserved for css and html
OR
Negative margin, extra containers , or other hacks or bloat?
Already spent too much time on this but looking for the "professional" way to do it.
EDIT: Here is a code example using Alexander's method.
Usually I use pure css/html solution which works in 99% cases:
I have a parent div with background-repeat on 'Y' axe. The general structure is going to be like this :
html:
<div id="container" class="clearfix">
<div class="LeftPane"></div>
<div class="CenterPane"></div>
<div class="RightPane"></div>
</div>
css:
#container{
background:url(imagePath) 0% repeat y;
}
for background image you can apply image for the borders, or everything else what can make users to think that all 3 blocks have the same height
There are many ways of successfully doing that, I think the easiest one of them is to simply wrap them all in a common parent container, set his display to table or table-row No need for parent at all. and set the original <div>s to display: table-cell;
jsFiddle.
For compatibility I'd suggest jQuery. Hacks and extra containers make your code bloated, as you've said, and will end up making it more difficult to edit if changes need to be made. And anyways, HTML is the layout of the page.
I have come up with a revolutionary new method for equal height columns. It is a pure CSS/HTML solution, tested in the latest Chrome and Firefox, and IE7-9. It is a bit tricky to set up but once it is done it works beautifully. The problem with every previous solution I have seen is that it doesn't actually create individual, side-by-side divs that can have their own borders, margins, etc. Other solutions always have some columns overlapping which means you can only contrast the different columns by changing the background. This method allows any column to be any height unlike some methods. The secret to its success is using float: right instead of left. If it was floated left you would have issues with extra space on the right causing scroll bars. Perhaps the only down side with this method is that it can be hard to wrap your head around!
Check it out here.
http://jsfiddle.net/wRCm6/2/

3 columns layout via DIVs (middle-flexible, all flexible height, STRICT mode)

Hey guys, I've struggled with this for a bit and don't seem to find a solution. Need an advise or the simple statement saying this is impossible (so far I think it is - impossible).
Problem is:
need 3 column flixible width layout, left fixed width, right aswell, middle - takes all of the space provided by body or whatever.
Trick is that either right or left columns might be taller then middle, and we need them not to overlap the footer. Also docmode is Strict. I know that Table solves the problem in a sec, but I wonder is there a Div solution around?
This is what you're looking for I think:
http://matthewjamestaylor.com/blog/perfect-3-column.htm
or with pixel widths:
http://matthewjamestaylor.com/blog/ultimate-3-column-holy-grail-pixels.htm
It's XHTML strict, and supports all current browsers.
YUI Grid CSS is proabably what you want. I am not familiar with the CSS magic involved, but it supports multiple different layouts. It doesn't seem to support fixed left and right columns.
No tables challenges are a bit like waving a red flag to a bull for me:
http://edeverett.co.uk/experiments/noTables2.html
Tested in IE7, FF3, Chrome 2.
This should get you most of the way there, the main idea is to use negative margins on the two side columns with the main column set to 100% width. It would benefit from having a lower limit on the page width.
(I've edited the example html to show how to include content in the centre section)

CSS floats with unknown widths don't wrap whitespace with doctype

Two divs, floated left, of unknown width. One of them has more content than fits the page, so it moves below the first (except in IE):
http://corexii.com/floatproblem/float.html
Add display:inline-table; and the big one wraps its content (consistently across browsers):
http://corexii.com/floatproblem/table.html
But introduce a doctype (not just strict, ANY doctype) and it doesn't anymore in Firefox:
http://corexii.com/floatproblem/doctype.html
How do I get the right div to wrap its content while using a doctype at the same time, reliably across browsers?
How do I get the right div to wrap its
content while using a doctype at the
same time, reliably across browsers?
Without defining widths, you cannot. I'd recommend percentage widths in this case, but it's up to you.
The default width for a div is 100% of its container (in this case the page).
The first div will end up it's actual size unless you size the page to be smaller that its inherent width.
Expecting consistency accross browsers without a full and valid doctype is simply an exercise in futility.
CSS can't quite do everything that table based layouts can. For one, dynamic width layouts are much more complicated. Table-less layouts are still preferable for 98% of cases, but if you really need this kind of dynamic width layout you might have to use a table.
Inconsistent widths, if not carefully proportioned, are not very good from a aesthetic standpoint so you may be fixing the wrong problem.
You could start by including a BODY element.
Traingamer has given you an explanation of Firefox's behavior and what needs to be done to get your desired result. You might listen to him instead of going off on a tangent about CSS being impossible to create layouts with.
Don't blame CSS for problems that you are introducing by not adhering to correct web specifications.