Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamic resolution-dependent CSS in ASP.NET

0.00/5 (No votes)
2 Jan 2013 1  
A brute-force, cross-browser solution to percent-based CSS sizing

Introduction

Just about every web developer has been there: you try to be a good CSS purist, you eschew (mis)using tables for page layout, and you just want some child element to center vertically and horizontally within its parent, or respect a percentage-based size under adverse conditions, and maybe vertical-align refuses to work unless you use fixed measurements for line-height or a parent dimension. You try setting height and min-height, you fiddle with margin and padding, you try some IE-specific hacks, you make sure you've set the height on your html and body elements to 100%... you think you have it, then you preview it in 7 different browsers and now it's completely b0rk3d in one where it worked before. This is a solution which discards all finesse and brings a sledgehammer to the playground; instead of being clever or elegant, it simply beats every browser into submission when it comes to rendering the damn thing the way you want.

Approach

The overall goal here is simple: Visually simulate percentage units in CSS using fixed (pixel) measurements. There are obviously several ways to skin this cat, and several choices to make. You could adjust everything  every time the browser window gets resized (I didn't). You could do the entire thing in javascript and skip ASP.NET completely. I chose otherwise because I like having the viewport dimensions available on the server-side, e.g. for cases where there's custom rendering happening there. No matter what you do though, you're going to need at least some JavaScript to get those dimensions effectively. Then you'll want to hand them to the server, which should respond with a stylesheet containing measurement units custom-tailored to the browser's dimensions. 

About the code 

Thanks to Andy Langton's article at http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/ ,  you can easily get the size of the browser's viewport with one big ol' line of javascript:

var win = window, d = document, e = d.documentElement,
 g = d.getElementsByTagName('body')[0],                
 x = win.innerWidth || e.clientWidth || g.clientWidth, 
 y = win.innerHeight || e.clientHeight || g.clientHeight;	

Now you have the width in the x variable and the height in the y variable, both of which you can feed to the server using your personal method of choice -- e.g. an Ajax call, hidden field, etc. I just write in a link element pointing to my dynamic CSS handler, and tack the x and y values on as query string parameters: 

document.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/DynHeightCSS.ashx"
 + "?w=" + x
 + "&h=" + y
 + "\"" + " />");

This adds a stylesheet link to the page with a URL like this:
http://localhost:8080/css/DynHeightCSS.ashx?w=1920&h=1012.

The dynamic CSS handler (DynHeightCSS.ashx) calculates pixel dimensions for every percent value of the given browser dimensions, and embeds these into custom classes for setting height, line-height and width. For example, the first three classes in the generated response -- all representing 1% of height or width, respectively --  look like this (given my current browser dimensions of 1920 x 1012):

.height-1-pct {
    height<span class="code-none">: 10px<span class="code-none">;
<span class="code-none">}
.line-height-1-pct <span class="code-none">{
    height<span class="code-none">: 10px<span class="code-none">;
<span class="code-none">}
.width-1-pct <span class="code-none">{
    width<span class="code-none">: 19px<span class="code-none">;
<span class="code-none">}</span></span></span></span></span></span></

Here's an example of where you might want to use this tactic. The white box below is 45% of the page height, and you want to vertically center a span of text within it. Simply setting vertical-align: middle doesn't do anything (right), even with height or line-height set to 100%:

In the example (image above, markup below), the text block on the right is incorrectly aligned vertically. The only difference between that and the correctly aligned one (left) is the class attribute of height-45-pct (provided by our dynamic CSS) added to the left span. We know the white box is 45% of the page height, and we want our text block to be the same height -- but measured in pixels -- so we just use the dynamically-generated class corresponding to that height:

<div style="width: 50%; margin-top: 4px; float: left; text-align: center;">
	<span class="height-45-pct" style="display: table-cell; vertical-align: middle;">
	This text is supposed to vertically <br>align middle. The height is 400px.</span>
</div>
<div style="width: 50%; margin-top: 4px; float: left; text-align: center;">
	<span style="height: 100%; display: table-cell; vertical-align: middle;">
	So is this text, but line-height 100% <br>doesn't work quite the same.</span>
</div> 

Using the code

To use the code, simply download DynHeightCSS.ashx.cs, add it to your /css directory as an HTTP handler, and drop the aforementioned javascript into the head of your page. Then when you need to force an incorrigible element to obey a percentage measurement, use one of the dynamically generated classes to do so. NB -- percentages are always relative to the page, not the containing element; you'll need to do some math here & there to convert to page-relative fractions.

Points of Interest

There are obviously other use cases besides height, line-height and width where a brute force approach like this could be useful. Min and max heights come to mind. Having a percentage-to-pixel calculation in your CSS could free you up to use absolute positioning where it would otherwise be difficult to.

This is a first-draft proof-of-concept, not a fully fleshed out utility. I use it in production code, but I'm sure there are drawbacks that I haven't run into and you will. It is a bit bloated for sure, so it might be slimmed down a bit by only outputting the sizes and attributes you actually use. Some embellishments could also come in handy; for instance, if the javascript function removed and replaced the stylesheet <link> element when the browser was resized, or if it even even just changed the styles on the fly if the whole thing were done in JavaScript. Leave your thoughts in the comments, and I hope this has been useful!

History 

First version posted 12/31/2012.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here