On two separate events this month, I’ve been required to supply a format wherein a fixed-width scrolling facet “pane” and versatile scrolling foremost “pane” should resize to fill all out there area in a browser window.
Article Continues Under
As a CSS purist, I’ve at all times tried to keep away from such dynamic layouts, however typically they’re required. When they’re, I prefer to have previous grumble about the truth that I’ve resorted to utilizing JavaScript for my layouts.
Essentially the most superior approach of attaining such a format is to make use of a JavaScript toolkit comparable to DOJO—however for what I used to be making an attempt to attain, even DOJO felt too bloated and appeared liable to create additional issues.
We are able to, in fact, obtain these format targets by utilizing JavaScript to resize the div
s each time the web page is loaded or resized. Sadly—amongst different complications—that’s made extra difficult by the alternatives between window.innerHeight
and doc.documentElement.clientHeight
and doc.physique.clientHeight
, and the necessity for cross-browser occasion listeners.
It appears that evidently utilizing JavaScript is an attainable however inelegant resolution for this format. What I actually need is a light-weight, easy-to-understand, pure CSS template…
The issue with percentages#section2
We frequently use components which have dynamic widths and heights by defining these attributes as percentages. However there’s an issue with percentages: they don’t play effectively with others. Regardless of everybody’s finest makes an attempt, you simply can’t combine up pixels and percentages (though I’ve learn rumors that it’s within the playing cards).
Whereas we will create comparatively efficient layouts utilizing simply percentages, we will’t then have a fixed-width facet panel or a fixed-height header. So percentages simply aren’t going to do the job in our format.
Adopting a tried and examined philosophical approach, I went again to the fundamental assumptions to attempt to discover one thing else I’d missed. I noticed that I believed the next statements about div
s have been all true:
In all browsers#section4
- A
div
is rectangular. - Just one nook of a
div
may be completely positioned on a web page. - The placement of the diagonally opposing nook have to be decided by the width and top of the
div
. - If the width and top are dynamic, they have to be decided utilizing JavaScript.
It struck me that assumption no. 2—that just one nook of a div
may be completely positioned on a web page—needs to be very simple to both affirm or deny. What occurs if we completely place a div
by defining its high
, left
, backside
, and proper
properties, all on the similar time? In any case, though I consider it as being a “battle,” it’s really completely legitimate CSS.
Assigning “conflicting” absolute positions#section5
I had assumed that in the event you assigned high
, left
, backside
, and proper
properties that the majority browsers would merely ignore two of these properties.
It appeared like a good assumption on the time. I anticipated some variation between the browsers, however I additionally anticipated all of them to disregard two of the 4 positions.
I used to be completely fallacious about that. What really occurs is one thing reasonably magical. In each browser I examined, except IE5 and IE6, all 4 guidelines are obeyed. The result’s that the div
is successfully “stretched” to fill the viewport.
A little bit of analysis revealed that I’m definitely not the primary individual to find this.
Typically, this little little bit of CSS trickery appears to have been discarded resulting from its incompatibility with IE5 and IE6, and in consequence has remained largely unnoticed, though it’s good to see that IE7 now helps these “conflicting” absolute positions.
Incompatibility doesn’t make the invention ineffective. Our authentic statements should still apply to IE5 and IE6, however we now have a distinct set of statements for all different browsers.
In all browsers aside from IE5 and IE6#section6
- A
div
is rectangular. - All 4 corners of a
div
may be completely positioned on a web page. - If the placement of diagonally opposing corners has been decided the width and top is implied.
An alternate resolution for IE#section7
What does this imply? It means our assumption that just one nook of a div may be completely positioned on a web page creates an issue particularly for IE5 and IE6. Because it seems Web Explorer really affords us its personal various. Earlier on, I stated that you may’t combine pixels and percentages, however that wasn’t strictly true: you may in Web Explorer.
Utilizing the facility of dynamic properties, it’s now doable to declare property values not solely as constants, but in addition as formulation.
Dynamic properties are undeniably highly effective, however as they’re solely supported in IE, they are typically of little actual use.
However, as soon as once more, incompatibility isn’t a motive for discarding this little trick. With the ability to decide the width and top of our div
s as a formulation means we will specify “the width of the web page minus 40px.” So long as we will do this in IE5 and IE6, we will modify our authentic assumption #4 just a bit bit and decide on our remaining set of statements.
In IE5 and IE6#section8
- A
div
is rectangular. - Just one nook of a
div
may be completely positioned on a web page. - The placement of the diagonally opposing nook have to be decided by the width and top of the
div
. - The width and top may be decided utilizing dynamic properties.
In all different browsers:#section9
- A
div
is rectangular. - All 4 corners of a
div
may be completely positioned on a web page. - If the placement of diagonally opposing corners has been decided, the width and top is implied.
Ah! Now that’s way more prefer it. So long as the entire above statements are true, we actually ought to be capable of put our total template collectively utilizing (virtually) pure CSS.
Placing all of it collectively#section10
Our splendidly easy HTML appears like this:
<physique>
<div id="header">
<p>Our header</p>
</div>
<div id="facet">
<p>Our facet panel</p>
</div>
<div id="proper">
<p>Our foremost panel</p>
</div>
</physique>
In fashionable browsers#section11
Our CSS for all fashionable browsers is now strikingly easy.
- We specify the width and top of the physique as 100%. (That is really solely wanted for our Web Explorer resolution, however there’s completely no hurt in together with it in our foremost CSS.)
- We conceal the overflow within the
physique
andhtml
as a result of we by no means wish to see these scroll bars once more. - We set the
overflow
to “auto” for the left and proper panels, and conceal it within the header. - The header has a width of 100% and a relentless top of 80px.
- For the facet panel we specify the
high
(header top + padding),left
(padding), andbackside
(padding) positions. Then we give it a relentless width of 200px. - For the proper panel we specify the
high
(header top + padding),left
(padding + facet panel width padding),proper
(padding) andbackside
(padding) positions.
All of that may be very simply translated into the next CSS:
<type kind=”textual content/css”>html {
overflow: hidden;
}physique {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
top: 100%;
}#header {
padding: 0;
margin: 0;
place: absolute;
high: 0px;
left: 0px;
width: 100%;
top: 80px;
overflow: hidden;
}#facet {
padding: 0;
margin: 0;
place: absolute;
high: 100px;
left: 20px;
backside: 20px;
overflow: auto;
width: 200px;
}#foremost {
padding: 0;
margin: 0;
place: absolute;
high: 100px;
left: 240px;
proper: 20px;
backside: 20px;
overflow: auto;
}</type>
Creating the exception for IE5 and IE6#section12
In IE5 and IE6 the backside
and proper
attributes of the principle and left panels are simply ignored.
Because of this the highest left nook continues to be pinned in place for every of our div
s, and we simply must outline our widths and heights.
We wish the peak of each the principle panel and the facet panel to be 100% of the peak of the web page minus the header top and the highest and backside padding (100%-80px-20px-20px).
We wish the width of the principle panel to be 100% of the width of the web page minus the width of the facet panel, the left padding, the proper padding, and the gutter padding (100%-200px-20px-20px-20px). The width of the facet panel is a continuing, and has already been outlined, so nothing wants including right here.
By utilizing a conditional remark we will embrace these expressions for IE5 and IE6. (Line wraps marked » —Ed.)
<!--[if lt IE 7]>
<type kind="textual content/css">
#facet {
top:expression(doc.physique.clientHeight-120); »
/* 80+20+20=120 */
}
#foremost {
top:expression(doc.physique.clientHeight-120); »
/* 80+20+20=120 */
width:expression(doc.physique.clientWidth-260); »
/* 200+20+20+20=260 */
}
</type>
<![endif]-->
Don’t overlook: we particularly needed to set the peak and width of the physique to 100% for this to work, however we didn’t want to cover that from different browsers, so it’s included in the principle type sheet.
And there we now have the completed format.
Okay, these dynamic expressions aren’t legitimate, however they’re not less than hidden from the browsers that don’t want them. Though they’re offered as CSS these dynamic expressions are in fact JavaScript, and as such they received’t work in IE5 and IE6 if JavaScript is turned off.
However then, not one of the various options would work in that scenario both.
{Though this method was developed independently, an article that instructed lots of the similar strategies was revealed in 2004 by Alex Robinson. —Ed.}
Recognized points#section14
There’s a small and annoying bug in Opera 8. Though the facet div
resizes appropriately when the web page first masses, it doesn’t dynamically resize when the window dimension is modified.
This appears to be as a result of we’ve given it a relentless width, and I’ve, to date, been unable to discover a approach round this concern. Fortunately, it’s mounted in Opera 9, and it isn’t a very crucial bug to start with.