15 Feb

Customizable page layouts

I recently redesigned my site running on WordPress, which gave me some ideas about a bit more convenient layouts. I hope they are of some value to anyone who is designing their own layouts.

I wanted to tackle a common problem: on a modern (1280+ pixels wide) screen resolution it is often hard to read because the text rows are simply too long.

The easiest way to limit text width layout-wise would of course be to create a fixed-width layout. However, some viewers probably would like to have as wide text as the screen allows. Using some Javascript and DHTML magic, it is easy to make the fixed-width layout resizable. The site can even keep the same width across different pages if it is stored in a cookie.

In Javascript, you can easily change an element’s properties, here is how you would change the width of an element with the ID ‘resizable‘:

document.getElementById('resizable').style.width="500px";

Values can be saved in a cookie as follows (using / as the path sets the cookie for all pages under the domain, important if you want to keep the same width across different pages, cookie expires after days days):

var expire = new Date();
expire.setTime(expire.getTime() + 1000*60*60*24*days);
document.cookie = cookieName+"="+escape(cookieValue)+
  ";expires="+expire.toGMTString()+";path=/";

It is suboptimal to resize the layout after it loads, this will result in an annoying redraw of the page after a few moments. Using some server-side scripting, you can inject the width from the cookie so the page renders at the desired width from the beginning. On my page it is done like this:

<div style="width: <?php echo $_COOKIES[page_width]; ?>">

Probably the most technical thing when implementing the resizing is handling mouse drag in Javascript. On my page, I check if a mouse click happens on an element that has a class name of “drag” and if it is, the drag begins. If the mouse button is released, the drag ends and the resized width is calculated.

var dragging=false;
var start_x=0;

function mousedown(e) {
  if (e.target.className=="drag") {
    start_x=e.clientX;
    dragging=true;
  }
}

function mouseup(e) {
  if (dragging) {
    dragging=false;
    end_x=e.clientX;
    move_x=end_x-start_x;
    // drag ends, we moved move_x pixels
  }
}

After we know how much the X position changed, we can adjust the element width. The following code extracts the number part from the width, adds the X movement to it and again adds the ‘px’ unit in the end:

d=document.getElementById('postcolumn');
m=d.style.width.match(/(\d+)px$/i);
d.style.width=move_x+Math.round(m[1])+'px';

The element width should change by the same amount the user dragged the mouse. At this point you might want to set the cookie as described above.

That’s about it! I am quite sure someone who has no experience of doing things in Javascript and CSS doesn’t get much from the above. I intented this post to be a heads-up of sorts, this is quite easy to implement and in my opinion can be quite convenient. You can try it by dragging the right edge of this post.

If you really want to have that on your site but can’t figure out it by yourself, leave a comment and I’ll help as much as I can. Also, you can look at the source code of this page to see how I did it.

Links