What is the best approach to make 3 column fixed width cross browser compatible, accessible, semantically correct layout? - css

What is the best approach to make 3 column fixed width cross browser compatible, accessible, semantically correct layout ?
<div id="wrapper">
<div id="header">
This is the Header
</div>
<div id="top-nav">
Top Navigation
</div>
<div id="leftcolumn">
Left Column
</div>
<div id="content">
content column
</div>
<div id="rightcolumn">
Right Column
</div>
<div id="footer">
This is the Footer
</div>
</div>
#wrapper {width:970px;margin:0 auto }
#header {height:100px }
#top-nav {height:30px}
#leftcolumn { }
#content { }
#rightcolumn { }
#footer {height:100px}
With this XHTML code what css should be written to make this 3 col layout.
cross browser compatible including
IE6 (without CSS hack or extra
conditional css for IE)
Width in Px
Centered
Font-sizing in em
Number of column can be extended or
removed 1-4,5 etc
SEO Enabled

Um, this is pretty darn easy with floats and faux columns.
Why do you have so many containers around the columns? You only need one. To clear the floats, do
#container {
width:960px; /* or 100%, or whatever. It needs to be set for it to work in IE tho */
overflow:auto; /* hidden works too */
background:url(./img/faux-columns.gif) repeat-y; /* google faux columns for A List Apart article */
}
and for the columns themselves
#col1 { width:520px; float:left; margin-right:20px; }
#col2 { width:200px; float:left; margin-right:20px; }
#col3 { width:200px; float:left; }

Use jQuery + its layout plug-in. Keep your full head of hair.

Related

Centered DIV w/ width dependant on text, buffered by two divs that should fill the containing DIV

Thank you all for your help so far. I updated the description, concept image, and JSFiddle link to make things a little clearer.
I have been wracking my brains on this seemingly small issue the whole day. My web dev friends are baffled and I could not find a suitable answer in my search of this site and others (though, I could have missed it somewhere along the way).
Here's what I am trying to achieve:
3 non-fixed-width DIVs within one fixed-width container DIV
The center DIV needs to be centered, and no larger than the text it contains.
The left and right DIVs need to fill the remaining space in the container DIV.
Here are some links to help communicate this concept:
This is what I'd like to end up with
Check out this JSFiddle Link
The basic HTML:
<div id="container" >
<div id="left" ></div>
<div id="center" >Text inside center should resize this block</div>
<div id="right" ></div>
</div>
Below, I removed most of the styles I have tried. This CSS currently centers the DIV (if I set it as an inline block), but I need the other divs to fill the left and right space remaining:
#container {
width:750px;
text-align:center;
border:3px solid #E85355;
}
#left {
background-color:#A3CB46;
}
#center {
background-color:#6D6E71;
display:inline-block;
color:#FFFFFF;
}
#right {
background-color:#1DB0CE;
}
I've tried floating, no-wrap, overflow, etc. Thanks a million to whomever can offer some help!
Try the following CSS. It fills the width of the container...
#container {
width:764px;
text-align:center;
}
#container > div {
display: table-cell;
}
#center {
background-color:#CDD7D7;
}
#right, #left {
background-color:#E85355;
width:200px;
}
EDIT: display:table on container, not needed...
Do you need this ?
CSS
#container {
width:764px;
text-align:center;}
#left {
background-color:#E85355;
width:20px;
height:20px;
float:left;
}
#center {
background-color:#CDD7D7;
display:inline-block;}
#right {
background-color:#65A8A6;
width:20px;
height:20px;
float:right;
}
DEMO
Try this:
jsfiddle.net/SHnc9/36/
You can do it with flexbox! Demo: http://dabblet.com/gist/7187048
Markup
<div class='container'>
<div class='box left'></div>
<div class='box center'>enter text here to see this box grow!</div>
<div class='box right'></div>
</div>
CSS
.container {
display: flex;
}
.box {
flex-grow: 1;
}
.center {
flex-grow: 0; /* to get the box to wrap closely around the text */
}
According to caniuse.com http://caniuse.com/#search=flexbox, it's supported in all the major desktop browsers with firefox having partial support which probably means it uses the old syntax / doesn't support some new properties but the demo worked fine when I checked.
Just be sure to use prefixes(or use a prefixfree / unprefix plugin), add the old syntax for old browser versions (add old syntax below the new ones).
Also, use display: inline-block as a fallback.
You may also want to check out flexie.js http://flexiejs.com/.
Essential reading:
http://css-tricks.com/snippets/css/a-guide-to-flexbox/

How to bump footer down when there is floating in div above?

I need to bump my footer down to the bottom of the page, regardless how much content is on the page above it. So I did some search on the internet and found one solution according to this site:
http://matthewjamestaylor.com/blog/keeping-footers-at-the-bottom-of-the-page
However, everything works OK until I applied "float:left" to the content div. The footer is no longer on the bottom and got bumped up half way. My question is, How to keep the footer down when there is floating in the div above?
Please see this jsfiddle here for my example:
http://jsfiddle.net/mEuke/5/
or code here:
<style type="text/css">
html,
body {
margin:0;
padding:0;
height:100%;
}
#container {
min-height:100%;
position:relative;
}
#header {
background:#ff0;
padding:10px;
}
#body {
padding:10px;
padding-bottom:60px; /* Height of the footer */
}
#footer {
position:absolute;
bottom:0;
width:100%;
height:60px; /* Height of the footer */
background:#6cf;
}
</style>
<div id="container">
<div id="header"></div>
<div id="body">
<div id="test" style="float:left">
blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
</div>
</div>
<div id="footer"></div>
</div>
You need to use a clearfix on the the container of the floated children
Here is a modern clearfix that works in modern browsers.
#body:after { /* #body is your container */
content: "";
display: table;
clear: both;
}
This will solve your problem
Demo: http://jsfiddle.net/mEuke/7/
For a cross browser clearfix read this Article: http://css-tricks.com/snippets/css/clear-fix/
What is a clearfix?
A clearfix is a way for an element to automatically clear after itself, so that you don't need to add additional markup. It's generally used in float layouts where elements are floated to be stacked horizontally.
The clearfix is a way to combat the zero-height container problem for floated elements.
Source: What is a clearfix?

3 column CSS liquid layout, with left and right edges flush with edges of parent element?

How can I create a 3 column CSS layout, with the left and right edges flush with edges of parent element? I want to be able to do this within a liquid layout, so no fixed widths.
This sounds like it should be easy, but the best thing I can come up with is quite a hack.
<style>
.c3 { display:block; text-align:center; }
.c3 span { display: inline-block; width:20%; text-align:left; vertical-align:top; }
.c3 .left { float:left; }
.c3 .right { float:right; }
</style>
...
<span class="c3">
<span class="left"> ...
</span>
<span class="center"> ...
</span>
<span class="right"> ...
</span>
</span>
You can see it here, this works okay (in my browser at least) but it just feels wrong. Is there a better way to do this?
Since there seems to be some confusion about what I'm trying to do, here it is in context. I run into this fairly often, where I already have a page layout and I want three columns within that layout. I want the three columns to be "fully justified," and I want things to be liquid, because even thought the page has a fixed layout, there's usually a facebook app or something also and I like to reuse as much as possible. Here's the latest example of where I've run into this (bottom of the page).
I'm not worried about SEO, the content is usually in 1-2-3 order of importance. I don't really care if they're all the same length. I'd like to not use a ton of markup if possible. My main goal is to have the left and right edges flush with the parent element, and and equal amount of space between each column.
I could try to write a new layout for you or fix the one you started, but I feel like I should just point you to a good source for the layout you're after:
The Perfect 3 Column Liquid Layout (Percentage widths)
No CSS hacks. SEO friendly. No Images. No JavaScript. Cross-browser & iPhone compatible.
http://matthewjamestaylor.com/blog/perfect-3-column.htm
I have used this resource for many years and it's rock solid, even in IE6. Make sure to click around to see all the examples, and read the article so you understand how it works.
This is an image of the basic layout structure (not the actual output):
It uses some crafty relative positioning and SEO-friendly 2-1-3 source order. Full height faux columns, fixed-width or fluid columns...
I cannot recommend this resource enough, I hope you enjoy it.
OK, sounds like you just want a lightweight alternative to your already-working solution.
Per our discussion in chat, I'm posting the mini-template I created:
<div class="wrapper">
<div>1</div>
<div>2</div>
<div class="last">3</div> <!-- or use CSS3 :last selector -->
</div>
.wrapper {
width:500px; /* any width OK */
float:left;
}
.wrapper div {
width:30.65%; /* not perfect, but close */
padding:1%;
margin:0 0 0 1%;
float:left;
}
.wrapper div:first-child { margin:0; }
/* make up for imperfect 1/3 width rounding */
.last { float:right;margin:0 }
Demo: http://jsfiddle.net/bH8vY/2/
Best of luck.
As far as I can tell, the solution I gave in the question is the best answer for this. I haven't found any other suggestions since posting this that would achieve what I want.
I'll reiterate it here so the question can be closed.
<style>
.c3 { display:block; text-align:center; }
.c3 span { display: inline-block; width:20%; text-align:left; vertical-align:top; }
.c3 .left { float:left; }
.c3 .right { float:right; }
</style>
...
<span class="c3">
<span class="left"> ...
</span>
<span class="center"> ...
</span>
<span class="right"> ...
</span>
</span>
This might be what you want/help you; I've made a layout that uses css to emulate dynamic table behaviour [using divs]. It works in Chrome, Firefox and IE>7.
DEMO, have a go at resizing the window. That middle bit is what you want, I think.
Have a fiddle with it. Uncomment the border css line to see whats going on.
Code:
<div class="view" style="height:100%; width:100%">
<div class="north">
n
</div>
<div class="middle">
<div class="west">
w
</div>
<div class="centre">
c
</div>
<div class="east">
e
</div>
</div>
<div class="south">
s
</div>
</div>
html, body {
height : 100%;
margin : 0;
}
.view,
.view > .middle {
display : table;
}
.view > .north,
.view > .south {
height : 1px;
display : table-row;
}
.view > .north { vertical-align : top; }
.view > .south { vertical-align : bottom; }
.view > .middle > div {
display : table-cell;
}
.view > .west,
.view > .east {
width : 1px;
}
/*div { border : 1px solid black; }*/
Simple markup, no JS, and dynamic layout.

Multiple ID whith one rule

I typed this
#center-1, #center-2, #center-2, #center-3, #center-4,
#center-5, #center-6, #center-7, #center-8 { float: left; width:360px; }
HTML:
<div id="centerColumn">
<div id="center-1"></div>
<div id="center-2"></div>
<div id="center-3"></div>
<div id="center-4"></div>
<div id="center-5"></div>
<div id="center-6"></div>
<div id="center-7"></div>
<div id="center-8"></div>
</div>
and it doesn't work, why?
Guessing from your report that it "doesn't work", you're probably just not seeing the divs because there is no content, height, or padding. Add height:10px; or something, and some background - they will show up.
By the way, there's a slightly easier way to write this selector in your case:
/* Select all <div>s in the #centerColumn */
#centerColumn div {
float: left;
width:360px;
/* Test to make divs appear */
background:#f00;
height:10px;
margin:1px;
}
your divs do not have any content, that's why they are not visible. to make them visible add at least a into them, or add height/min-height to the css rule

Large header in jqGrid

I've been fiddling with asp.net mvc 3 with the new razor view engine.
My goal is to have a fixed-fluid 2 column layout with a jqGrid in each column. I'm having no luck though! As soon as I add a grid to the right column its header goes huge. I don't think its jqGrids fault because if i remove the styles both grids display as expected.
I see that the css for the jqGrid applies display: block to the header as part of the ui-helper-clearfix class.
Anyone have any suggestions to get this to work or other fixed-fluid css i could experiment with (I've tried a bunch of templates from online with no luck)?
Code from the template file:
... <style type="text/css">
#left { float: left; width: 400px;}
#content { margin-left: 400px;}
</style>
</head>
<body>
<div>
<div id="left">
#RenderSection("SPTreeGrid")
</div>
<div id="content">
#RenderSection("ClientPickerGrid")
</div>
</div>
</body>
Update:
My page actually needed to display 2 grids in fixed width on the left and a fluid one on the right.
It was an issue with my css (I still dont know why) but I ended up using the following layout which works (rail is the left column):
#container{
overflow:hidden;
padding-left:400px; /* The width of the rail */
}
* html #container{
height:1%; /* So IE plays nice */
}
#content
{
width:100%;
border-left:400px; /* The width and color of the rail */
margin-left:-400px;
float:right;
}
#rail{
width:400px;
float:left;
margin-left:-400px;
display:inline; /* So IE plays nice */
}
cshtml:
<div id="container">
<div id="content">
#RenderSection("ReportGrid")
</div>
<div id="rail">
#RenderSection("SPTreeGrid")
#RenderSection("ClientPickerGrid")
</div>
</div>
Although Oleg's suggestion does fix the height of the title, it does not constitute a solution -- at least not if you want the right div to be liquid and expand to the width of the browser window. The problem is that in order to use float:left on the right grid container, you must specify a width. Floated elements must have explicit widths associated with them (if not, they take on the width of the widest element inside them).
One work-around that worked for me is to set a height of the floated to something small (1px) and set an explicit height for the content of that div.
I have created a jsFiddle example that illustrates the problem and the work-around.
You should use
<div style="float:left">
<table id="list1"><tr><td/></tr></table>
<div id="pager1"></div>
</div>
<div style="float:left">
<table id="list2"><tr><td/></tr></table>
<div id="pager2"></div>
</div>
as the template for the grids. If you case it should be
<style type="text/css">
#left { float: left; }
#content { float: left; }
</style>
You should not forget to include "clear:left" in the style of the next div which should be after the grid if you want to brake the floating.
See demo with two grids here

Resources