Forum Moderators: not2easy

Message Too Old, No Replies

How do I emulate "frames" using CSS?

         

Peter72

5:37 pm on Mar 27, 2004 (gmt 0)

10+ Year Member



Does anyone have links to good tutorials on how to emulate "frames" using CSS (and preferrably in strict XHTML)?
I need to create a site that has a more "application-like" look to it than normal websites. This involves rectangular areas fitted in the browser window, which scale along with browser scaling. I know I can use overflow:auto to make DIV's scrolling, but I don't know how to split up the browser window in several area's. (Note: I don't want to scroll the browser window itself, like common in websites, but I want scrollable sections like in complex applications, e.g. Outlook)
I know this is not what XHTML was intended for, but I want to investigate this approach further and see what the possibilities and problems are.
I prefer not to use real frames, since they require different documents for frame-building and contents.

Hope anybody can help!
Best regards, Peter

isitreal

5:51 pm on Mar 27, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Here's a recent thread on that subject:
[webmasterworld.com...]

Here's an older thread:
[webmasterworld.com...]
that one has some bugs in it though.

Notice however that you can't actually emulate either frame or applications like outlook behavior except for Internet Explorer 5.5-6. (and Firebird 0.7 but not Firefox 0.8). Those browsers are the only ones that actually support the full functionality of overflow:auto, in terms of it actually scrolling the way a user would expect it to.

If you don't mind forcing the user to manually scroll the overflow block, which I consider unacceptable in terms of user friendliness, there is no problem implementing these techniques.

If however what you really want is iframe functionality, why not use Iframes? Trying to emulate complex tag behaviors with CSS is generally an exercise in futility from my experience. Declare the document xhtml 1 transitional and it validates fine.

Since you specified that you don't want the entire browser window scrolling, which is the fix for the non-scrolling of non-MSIE windows browsers, there's not much you can do.

As to positioning your divs, that's simple, just make them relatively sized, like:

#overflowDiv1 {
position:absolute;
left:5%;
top:10%;
height:60%;
width:30%;
overflow:auto;
}

and so on. If you mix relative, percent based sizing with absolute, pixel based sizing, you will run into trouble.

Peter72

10:41 pm on Mar 27, 2004 (gmt 0)

10+ Year Member



Thanks! I am now trying a solution using JavaScript to set the style attributes, and the function being executed on load and resize. Having some problems with executing the script however, I am not the best at JavaScript...

isitreal

3:28 am on Mar 28, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If you use percent based positioning and sizing, you don't need the javascript, that is hard to do, and will never work quite right. I used to try that, finally gave up and moved to fully liquid design, the page flows on resize since it's been told everything in it is a percent of the browser window width and height, not absolute. That works much better.

Peter72

9:51 am on Mar 28, 2004 (gmt 0)

10+ Year Member



Yeah, but the problem with all relative sizes starts when using images in the layout. Scaled images don't look right, non-scaled images have a chance of being trimmed, and background images can't be scaled even. My layout often require pixel-perfect sizing.
But the good thing is I've got a working proof of concept using javascript, which works on IE6 and Firefox 0.8:


<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN'
'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>

<html>
<head>
<title>Windowed layout in XHTML Strict</title>
<meta http-equiv='Content-Type' content='text/html;charset=ISO-8859-1'/>

<script type='text/javascript'>
//<![CDATA[

window.onload = applyLayout;
window.onresize = updateLayout;

function applyLayout() {

with (document.getElementsByTagName('html').item(0).style) {
height = '100%';
width = '100%';
overflow = 'hidden';
}

with (document.getElementsByTagName('body').item(0).style) {
margin = '0px';
height = '100%';
width = '100%';
}

with (document.getElementById('header').style) {
position = 'absolute';
left = '0px';
top = '0px';
height = '50px';
width = '100%';
overflow = 'hidden';
background = 'blue';
}

with (document.getElementById('left').style) {
position = 'absolute';
left = '0px';
top = '50px';
width = '200px';
overflow = 'auto';
background = 'green';
}

with (document.getElementById('right').style) {
position = 'absolute';
left = '200px';
top = '50px';
overflow = 'auto';
background = 'yellow';
}

with (document.getElementById('footer').style) {
position = 'absolute';
left = '0px';
height = '20px';
width = '100%';
overflow = 'hidden';
background = 'red';
}

updateLayout();

}

function updateLayout() {
var vpWidth, vpHeight

if (self.innerHeight) { // all except Explorer
vpWidth = self.innerWidth;
vpHeight = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight) { // IE6 Strict
vpWidth = document.documentElement.clientWidth;
vpHeight = document.documentElement.clientHeight;
}
else if (document.body) { // other Explorers
vpWidth = document.body.clientWidth;
vpHeight = document.body.clientHeight;
}

document.getElementById('left' ).style.height = ((vpHeight < 50+20)? 0 : vpHeight - 50 - 20) + 'px';
document.getElementById('right' ).style.width = ((vpWidth < 200)? 0 : vpWidth - 200) + 'px';
document.getElementById('right' ).style.height = ((vpHeight < 50+20)? 0 : vpHeight - 50 - 20) + 'px';
document.getElementById('footer').style.top = ((vpHeight < 20)? 0 : vpHeight - 20) + 'px';

}

//]]>
</script>

</head>

<body>
<div id='header'>header -- fixed height, full width</div>
<div id='left'>left content -- fixed width, scrolling height</div>
<div id='right'>right content -- full width, scrolling height</div>
<div id='footer'>footer -- fixed height, full width</div>
</body>
</html>


(Hmmm... neither PRE nor CODE seem to work for properly displaying code...)

isitreal

4:28 pm on Mar 28, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



that's an interesting solution, I assume you have default css for if javascript is disabled, I've completely given up on using javascript for page rendering, I used to do it but the results were so annoyingly unreliable cross os/browser (for example, that won't work at all on Safari, at least last time I checked, since it has major problems with heights in this kind of script).

the page doesn't work quite right on opera, or mozilla when it gets smaller, the browser window starts scrolling, in opera it scrolls always, haven't checked on Mac but I would expect similar problems there.

You're right about the image problem (and object sizing), anytime you mix absolute and relative sizing you run into real problems, since absolutely sized and positioned divs behave very erratically when confronted with content that doesn't fit.

The funny thing, as is almost always the case with div construction when used to emulate tables, is that the one tag that will let you do what you want with almost no tweaks at all is the table tag, the cells will expand to fit the content (except sometimes in Opera). I've made layouts almost identical to yours using one main table for the layout and it works fine, it's stable, doesn't rely on js stuff that can't be counted on to work.

table tags even have a specific header and footer tag, it's designed to make this exact layout.

Anytime I need elements in one cell to interact with elements in another cell directly in terms of sizing I use a simple table for the layout, since no other tag gives you that behavior, and since the literal single negative consequence of doing that is offending css purists, that's fine with me. A table does by default what your script forces the browser into, I try to pick the most stable, easy way to do stuff unless it's my own experimental thing, although your solution is pretty nice as an experiment.

Peter72

5:01 pm on Mar 28, 2004 (gmt 0)

10+ Year Member



I've tried it using tables, but ran into two problems.
First, I can't get the tablecells to size properly in strict XHTML. Remember, I want some absolute sizes in a 100%-sized table. Not a real problem, I am not bound to strict XHTML, it would just be nice to get that.
The second problem, is that I can't get overflow:auto to work properly on DIVs inside tablecells! Either the DIVs get to be the same size as the window instead of the tablecell, or they get to be sized to their content and thus stretch the table outside the window.

isitreal

5:27 pm on Mar 28, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, the problems you had are the only problems with using tables, they are built to expand, it's almost impossible to stop that behavior, which is what makes them such a powerful tag, the single most powerful one.

I think only Opera will actually respect the table height:100% in CSS and cut off the content when it exceeds it.

Overflow auto doesn't work reliably in table cells, I think the way tables are programmed into the browser is that they override all other tags, divs are built with secondary value in terms of page layout, so getting a div to override a table cell is almost impossible, in other words, the browser will create the table structure before anything else, which means that the div that is supposed to scroll will be set to 100% of the rendered td cell height, which adjusts to fit its content, not the originally specified height.

However, an iframe set to 100% height of the cell would work perfectly, if I'm looking for true stability with the functionality you're looking for that's how I do it. If you want two separately scrolling elements, that truly scroll, there is no other way that works cross browser that I know of, your current solution will work correctly only in Windows IE 5.5 and 6, plus Firebird 0.7 (only that version, no other mozilla version, haven't checked 1.7 yet though).

I had a very similar site to yours running for a few years, but Safari failing to support the div height sizing was the thing that made me finally give up on the javascript solution, javascript will never be stable cross browser as far as I'm concerned, it never has been, and I doubt it ever will be, since DOM standards will always depend on dom implementation in browsers, last I checked there were for example about 100 Mac Browsers out there, of which probably only Mozilla actually offer decent DOM support.

I'm also a big fan of the 'everything in the browser window' approach, whether achieved through iframes, frames, or the horribly buggy overflow:auto, but only on my own sites, since each technique has problems.

Peter72

7:36 pm on Mar 28, 2004 (gmt 0)

10+ Year Member



I've just tried my page in Internet Explorer 5.0 and 6.0, Mozilla 1.0 and 1.7, and Gecko 0.8, and it works correctly in all of those. Also tried it in Opera 6.0, there it doesn't seem like any style is applied at all, and Opera 7.0, there it seems like the overflow is interpreted as "hidden". So I will have to modify that in the javascript file, but writing browser-checks in javascript has always seemed a lot more acceptable to me that those weird CSS-browerhacks.

isitreal

7:47 pm on Mar 28, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



but writing browser-checks in javascript has always seemed a lot more acceptable to me that those weird CSS-browerhacks.

You might think of doing your browser detection server side, not client side for stuff that actually directly affects how your pages are going to display, especially given that 5-8% of users supposedly have javascript disabled, which is the real argument against having page functionality depend on JS.

I think what you'll find when looking for an actual cross browser js solution is that the solution won't work on some browsers, for example, on the div height for the site I had using that I had to default Safari to a fixed height to make it work. I doubt it ever worked in MSIE for Mac either.

Before I dumped this approach I'd spent about 2 months off and on trying to debug various browsers to get the page to the point where it rendered and functioned more or less consistently, until I realized that Safari just didn't work, and it would never work as well as just using CSS to do the whole job.

Opera 6 doesn't have very good DOM support, or CSS support, despite rumours to the contrary, although it is a very fast browser. This is probably why Opera started all over with 7. And there are some fairly noticeable differences between 7.1 and 7.2 in terms of fixed bugs.

What you call working however is not what I call working, to me when a scrolling part of the page can be scrolled with a mousewheel on mouseover, which is standard behavior for basically all OS's out there on any window open in them, it's working. Did Mozilla get that working again? Firefix 0.8 didn't work last time I checked. MSIE windows only got that working in 5.5, Safari, Opera, and I think all the mozillas except firebird, have never had it working, and I think no Mac browser made supports that correctly.

Having to scroll the content manually is to me worse than having no scrolling and just having the page stretch as far as it needs, which will at least let the user scroll the browser window properly, that's definitely the case of a technology not ready for prime time, I test this yearly hoping the other browser programmers will finally get it right, but release after release fails (even IE 6 had some bugs that IE 5.5 didn't have when it came to some overflow:auto scrolling situations).

In terms of operating systems, this kind of poor performance puts overflow:auto at around the level of Windows 95 in terms of full functionality, maybe Windows 3.1.

And that's not the only problem you'll see with overflow:auto, there are many others that you will find as you make a site, especially if you have a header element and content scrolling page with in scroll area navigation, like 'top' links.

When I compare this to using an iframe it's almost depressing how badly supported overflow is, I have to give MSIE 5.5-6 full credit, they are the only browser to offer more or less functioning support for this feature, although to make up for it they don't support position fixed at all, which all modern non msie browsers do, to some buggy degree or other.