Click here to Skip to main content
15,881,715 members
Articles / Web Development / CSS

Dynamic resolution-dependent CSS in ASP.NET

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
2 Jan 2013CPOL4 min read 17.9K   205   7   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:

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: 

JavaScript
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):

CSS
.height-1-pct {
    height: 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></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%:

Image 1

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:

HTML
<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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect SWC
United States United States
Paul is a Software Architect at SWC Technology Partners, one of Crain’s 20 Best Places To Work for 2012. His coding exploits range from BASIC on a Commodore 64, but now focus on C#, SQL Server and the .NET stack. Paul also maintains the StormFactory ORM Code Generator on SourceForge.net. SWC Technology Partners is always looking for top technical talent; check out how cool it is to work here at http://reimagineyourcareer.com/, and feel free to contact me about positions here.

Comments and Discussions

 
QuestionWell, I guess it's one way of doing it, but.... Pin
Wombaticus24-Oct-15 1:25
Wombaticus24-Oct-15 1:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.