Search for a Functional CSS Layout

JavaScript Advantages

By using absolute positioning and fixed widths it is easy to create a fluid, resizable layout. This page has a resize div between the links div and this content div. Mouse over the dark area between them and you should see the East-West mouse arrow; mouse down and drag to change the size of the elements. See the added linkHandle_div in the html below.

To get it working, a resize handle div needs to be added to the html. A style definition similar to the style definitions for the other elements then needs to be added. To initialize the handle a file with the JavaScript below needs to be included and a call to the initResize() function needs to be made, probably from the body.onload() handler. See all the code below.

I haven't tested the resize handle extensively, but so far it works well in IE6, IE7, Firefox, and Opera. It didn't work in Safari, but what does? It would probably just take a little time to figure out the proper functions to use in Safari.

HTML

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Functional CSS Layout</title> </head> <body onLoad="onLoad();" onresize="onResize();"> <div id="header_div" class="layout_div"> <h2>Search for a Functional CSS Layout</h2> </div> <script type="text/javascript">autoSize('header_div');</script> <div id="link_div" class="layout_div"> <div><? siteLinks(); ?></div> </div> <script type="text/javascript">autoSize('link_div');</script> <div id="linkHandle_div" class="resizeLR_div"></div> <script type="text/javascript">autoSize('linkHandle_div');</script> <div id="content_div" class="layout_div"> </div> <script type="text/javascript">autoSize('content_div');</script> </body> </html>

CSS

1 2 3 4 5 6 7 8 9 html, body { background-color:#EEE; width:100%; height:100%; margin:0; padding:0; overflow:hidden; } div.layout_div { position:absolute; overflow:hidden; background-color:#DDD; } div#header_div { background-color:#DDD; left:5px; right:5px; top:5px; width:auto; height:45px; } div#link_div { background-color:#DDD; left:5px; top:55px; bottom:5px; width:140px; height:auto; overflow:auto; } div#content_div { background-color:#FFF; border:solid 1px #DDD; left:150px; right:5px; top:55px; bottom:5px; width:auto; height:auto; overflow:auto; } div.resizeLR_div { position:absolute; width:1px; background-color:#AAA; border:solid 1px #999; cursor:e-resize; z-index:1; } div#linkHandle_div { left:146px; top:60px; bottom:10px; height:auto; }

Javascript Resize

1 2 3 4 5 6 7 8 function onLoad() { /* set up the resize handle */ var elements = [ {n:'linkHandle_div',a:'left'}, {n:'link_div',a:'width',p:'left'}, {n:'content_div',a:'left'}]; initResize('linkHandle_div', elements); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 function initResize(handle, elements) { var isIE = (document.all != null && document.opera == null); if(typeof(handle) == 'string') handle = document.getElementById(handle); // startResize init and elements var code = 'function startResize('+(isIE ? '' : 'e')+') {'; code += 'document.onmouseup = onMouseUp;'; code += (isIE ? 'window.event.returnValue = false' : 'e.preventDefault(true)')+';'; // startResize lefts, rights, widths, and heights var code2 = 'var offsetX = '+(isIE ? 'window.event.clientX' : 'e.pageX')+';'; code2 += 'var offsetY = '+(isIE ? 'window.event.clientY' : 'e.pageY')+';'; // onMove function var code3 = 'document.onmousemove = function('+(isIE ? '' : 'e')+'){'; code3 += (isIE ? 'window.event.returnValue = false;' : 'e.preventDefault(true)')+';'; code3 += 'var changeX = '+(isIE ? 'window.event.clientX' : 'e.pageX')+' - offsetX;'; code3 += 'var changeY = '+(isIE ? 'window.event.clientY' : 'e.pageY')+' - offsetY;'; for(var n = 0; n < elements.length; n++) { var e = elements[n]; if(e.e == null) e.e = document.getElementById(e.n); else if(typeof(e.e) == 'string') e.e = document.getElementById(e.e); var name = (e.n) ? e.n : e.id; code += 'var '+name+' = elements['+n+'].e'+';'; switch(e.a) { case 'left': code2 += 'var '+name+'Left = parseInt(getStyle(elements['+n+'].e).left);'; code3 += name+'.style.left = ('+name+'Left + changeX)+"px";'; break; case 'right': code2 += 'var '+name+'Right = parseInt(getStyle(elements['+n+'].e).right);'; code3 += name+'.style.right = ('+name+'Right - changeX)+"px";'; break; case 'top': code2 += 'var '+name+'Top = parseInt(getStyle(elements['+n+'].e).top);'; code3 += name+'.style.top = ('+name+'Top + changeY)+"px";'; break; case 'bottom': code2 += 'var '+name+'Bottom = parseInt(getStyle(elements['+n+'].e).bottom);'; code3 += name+'.style.bottom = ('+name+'Bottom - changeY)+"px";'; break; case 'width': code2 += 'var '+name+'Width = parseInt(getStyle(elements['+n+'].e).width);'; code3 += name+'.style.width = ('+name+'Width'+(e.p == 'left' ? '+' : '-')+'changeX)+"px";'; break; case 'height': code2 += 'var '+name+'Height = parseInt(getStyle(elements['+n+'].e).height);'; code3 += name+'.style.height = ('+name+'Height'+(e.p == 'above' ? '+' : '-')+'changeY)+"px";'; break; } } if(widthResizeElements.length || heightResizeElements.length) code3 += 'onResize();'; code += code2+code3+'}}'; // alert(code.replace(/;/g, ';\n')); eval(code); // alert(startResize); handle.onmousedown = startResize; function onMouseUp() { document.onmousemove = null; document.onmouseup = null; } }