Conflicting Absolute Positions – A Record Aside

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 divs 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 divs have been all true:

In all browsers#section4

  1. A div is rectangular.
  2. Just one nook of a div may be completely positioned on a web page.
  3. The placement of the diagonally opposing nook have to be decided by the width and top of the div.
  4. 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.

DIV example
fig. 1, DIV dimension is computed in most browsers when absolute positioning is specified.

A little bit of analysis revealed that I’m definitely not the primary individual to find this.

“In browsers that assist CSS you may specify all 4 edges and let the browser compute the width and the peak. Sadly this doesn’t work in Web Explorer…”

Autistic Cuckoo

“Technically you need to use each a proper and a left property and depart the width as auto. However sadly IE doesn’t assist this…”

css-discuss

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

  1. A div is rectangular.
  2. All 4 corners of a div may be completely positioned on a web page.
  3. 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 divs 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

  1. A div is rectangular.
  2. Just one nook of a div may be completely positioned on a web page.
  3. The placement of the diagonally opposing nook have to be decided by the width and top of the div.
  4. The width and top may be decided utilizing dynamic properties.

In all different browsers:#section9

  1. A div is rectangular.
  2. All 4 corners of a div may be completely positioned on a web page.
  3. 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.

  1. 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.)
  2. We conceal the overflow within the physique and html as a result of we by no means wish to see these scroll bars once more.
  3. We set the overflow to “auto” for the left and proper panels, and conceal it within the header.
  4. The header has a width of 100% and a relentless top of 80px.
  5. For the facet panel we specify the high (header top + padding), left (padding), and backside (padding) positions. Then we give it a relentless width of 200px.
  6. For the proper panel we specify the high (header top + padding), left (padding + facet panel width padding), proper (padding) and backside (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 divs, 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.

Leave a Comment