Variable Fixed-Width Layout

Dec 21, 2006 in PHP, JavaScript, and CSS

After messing with script.aculo.us's JS for a while I got the idea to create a variable fixed-width layout. The specifications included

  • A handle on a track which could be dragged by the user to shrink or expand the layout width.
  • A minimum and maximum layout width.
  • A way to remember the user's settings last time they were here so they didn't have to keep on changing the width.
  • A non-breaking layout.

The Method

With a combination of PHP, JS and CSS, the desired effect can be created.

First, the CSS for the slider and track.

#slider {
	position: absolute;
	top: 23px;
	left: 15px;}
* html #slider {
 	display: none;
}
#track {
	height:75px;
	background-color:#999;
	width:1px;
	position: relative;}
#handle {
	height: 5px;
	width: 20px;
	background-color: #CC3300;
	position: absolute;
	left: -8px;
	margin: 0;
	padding: 0;}

Here the #track and #handle div's are styled appropriately. Then an absolute positioning is applied to the #slider to locate it on the upper-left corner of the page. Using the * selector ensures IE hides this whole feature because of how jumpy the expansion is, along with the fact that it has to reload every image on the slightest change in width. Below is the corresponding XHTML for the styling above.

<div id="slider"><div id="track"><div id="handle"></div></div></div>

Next, the JS for the handle and layout using the script.aculo.us library.

if(readCookie('d4_w') != null){
	w = readCookie('d4_w');
}else{
	w = 0;
}
var s = new Control.Slider('handle','track', {axis:'vertical'});
s.options.onSlide = function(value){
	w = (Math.ceil(value*150)+755).toString();
        $("master_wrap").style.width = w+"px";
};
s.setValue(w);
s.options.onChange = function(value){
	createCookie("d4_w",value,14);
};

This simply checks whether the layout cookie d4_w has been set yet (from some previous visit). I store this value in w. Event fucntions are then attached to the slider handle for when it is dragged and released. When the handle is released after being dragged, a cookie is updated with the last set width value. This sets he memory system in place. While being dragged, the width of the master_width div (the main layout wrapper) has its width CSS attribute continuously updated, giving the smooth expanding and shrinking effect I am looking for. The line above that says

     w = (Math.ceil(value*150)+755).toString();

is responsible for the minimum and maximum layout widths. The minimum width is 755, since when value = 0 w will be 755. Since the script.aculo.us slider and track works on a 0 to 1 scale, the value variable will cause Math.ceil(value*150) to be between 0 and 150, causing the maximum layout width to be 150 + 755, or 905px.

Finally, some PHP and CSS is needed for the pages themselves in the <head> to ensure that the page won't load at 755px and jump to some other value as the JS ran once the entire page loaded. This code is shown below.

<style type="text/css">#master_wrap{width:<?php if(isset($_COOKIE['d4_w'])) echo ceil($_COOKIE['d4_w']*150)+755; else echo 755; ?>px;}</style>

This code simply conditionally checks if the layout cookie is present and sets the width of the #master_wrap div according to the result. Nice and easy, and prevents some ugly jump in the layout width when loading every page.

Thats it! Make sure to make the header image nice and big (950px) which gives a neat effect revealing more of the image smoothly as the site layout is expanded.

D4Ly..com ©2006

Get in Touch

If you have any questions or comments, contacting me is simple.

  • AIM: jaSOn 7485
  • Xfire: d4ly
  • Gmail: jasondaly

Additionally, contact via email is always welcome.