How to implement a web page that scales when the browser window is resized?
I can lay out the elements of the page using either a table or CSS float sections, but i
Use percentages! Say you have a "main pane" on which all your page's content lies. You want it to be centered in the window, always, and 80% of the width of the window.
Simply do this:
#centerpane{
margin: auto;
width: 80%;
}
Tada!
After trying a solution by the book I got stuck with incompatibility's in either Firefox or IE. So I did some tinkering and came up with this CSS. As you can see, the margins are half of the desired size and negative.
<head><title>Centered</title>
<style type="text/css">
body {
background-position: center center;
border: thin solid #000000;
height: 300px;
width: 600px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -150px;
margin-right: auto;
margin-bottom: auto;
margin-left: -300px;
}
</style></head>
Hope that helps
Unless you have some specific requirement here I'm not sure why JS is needed here. Tabular layouts are the easy (and archaic) way to make fluid layouts in html, but div layouts with css allow for fluid layouts as well, see http://www.glish.com/css/2.asp
use ems. jontangerine.com and simplebits.com are both amazing examples. Further reading - The Incredible Em & Elastic Layouts with CSS by Jon Tan
The best way that I have seen to do this is to use the YUI CSS Tools and then use percentages for everything. YUI Grids allow for various fixed width or fluid layouts with column sizes specified as fractions of the available space. There is a YUI Grids Builder to help lay things out. YUI Fonts gives you good font size controls. There are some nice cheat sheets available that show you how to lay things out and useful things like what percentage to specify for a font size of so many pixels.
This gets you scaling of the positioning but scaling of the entire site, including font sizes, when the browser window resizes is a bit trickier. I'm thinking that you are going to have to write some sort of browser plugin for this which means that your solution will be non portable. If you are on an intranet this isn't too bad as you can control the browser on each client but if you are wanting a site that is available on the internet then you may need to rethink your UI.
Thanks for all of the suggestions! It looks like the ugly stuff i had to do was necessary. The following works (on my machine, anyway) in IE and FireFox. I may make an article out of this for CodeProject.com later ;-)
This javascript goes in the <head> section:
<script type="text/javascript">
var tmout = null;
var mustReload = false;
function Resizing()
{
if (tmout != null)
{
clearTimeout(tmout);
}
tmout = setTimeout(RefreshAll,300);
}
function Reload()
{
document.location.href = document.location.href;
}
//IE fires the window's onresize event when the client area
//expands or contracts, which causes an infinite loop.
//the way around this is a hidden div set to 100% of
//height and width, with a guard around the resize event
//handler to see if the _window_ size really changed
var windowHeight;
var windowWidth;
window.onresize = null;
window.onresize = function()
{
var backdropDiv = document.getElementById("divBackdrop");
if (windowHeight != backdropDiv.offsetHeight ||
windowWidth != backdropDiv.offsetWidth)
{
//if screen is shrinking, must reload to get correct sizes
if (windowHeight != backdropDiv.offsetHeight ||
windowWidth != backdropDiv.offsetWidth)
{
mustReload = true;
}
else
{
mustReload = mustReload || false;
}
windowHeight = backdropDiv.offsetHeight;
windowWidth = backdropDiv.offsetWidth;
Resizing();
}
}
</script>
the <body> starts off like this:
<body onload="RefreshAll();">
<div id="divBackdrop"
style="width:100%; clear:both; height: 100%; margin: 0;
padding: 0; position:absolute; top:0px; left:0px;
visibility:hidden; z-index:0;">
</div>
the DIVs float left for the layout. I had to set the height and width to percentages just shy of the full amount (e.g., 99.99%, 59.99%, 39.99%) to keep the floats from wrapping, probably due to the borders on the DIVs.
Finally, after the content section, another javascript block to manage the refreshing:
var isWorking = false;
var currentEntity = <%=currentEntityId %>;
//try to detect a bad back-button usage;
//if the current entity id does not match the querystring
//parameter entityid=###
if (location.search != null && location.search.indexOf("&entityid=") > 0)
{
var urlId = location.search.substring(
location.search.indexOf("&entityid=")+10);
if (urlId.indexOf("&") > 0)
{
urlId = urlId.substring(0,urlId.indexOf("&"));
}
if (currentEntity != urlId)
{
mustReload = true;
}
}
//a friendly please wait... hidden div
var pleaseWaitDiv = document.getElementById("divPleaseWait");
//an example content div being refreshed via AJAX PRO
var contentDiv = document.getElementById("contentDiv");
//synchronous refresh of content
function RefreshAll()
{
if (isWorking) { return; } //no infinite recursion please!
isWorking = true;
pleaseWaitDiv.style.visibility = "visible";
if (mustReload)
{
Reload();
}
else
{
contentDiv.innerHTML = NAMESPACE.REFRESH_METHOD(
(currentEntity, contentDiv.offsetWidth,
contentDiv.offsetHeight).value;
}
pleaseWaitDiv.style.visibility = "hidden";
isWorking = false;
if (tmout != null)
{
clearTimeout(tmout);
}
}
var tmout2 = null;
var refreshInterval = 60000;
//periodic synchronous refresh of all content
function Refreshing()
{
RefreshAll();
if (tmout2 != null)
{
clearTimeout(tmout2);
tmout2 = setTimeout(Refreshing,refreshInterval);
}
}
//start periodic refresh of content
tmout2 = setTimeout(Refreshing,refreshInterval);
//clean up
window.onunload = function()
{
isWorking = true;
if (tmout != null)
{
clearTimeout(tmout);
tmout = null;
}
if (tmout2 != null)
{
clearTimeout(tmout2);
tmout2 = null;
}
ugly, but it works - which i guess it what really matters ;-)