Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Browser Rendering Differences and Browser Resets


:P
On this page:

When it comes to proper usage of CSS and HTML layout, I have to admit I’ve been somewhat slow to get up to speed. Although I’ve been fully aware of what ‘you’re supposed to be doing’ it’s been quite a different story from  what I’ve actually been doing. Part of it is that a lot of the apps I work on are based on older code that didn’t pay close attention to CSS based layout and so it’s often hard to retrofit those apps. But slowly and gradually I’ve been drifting more to the ‘recommended’ approach to page layout with CSS isolation to style sheets and as little to no inline styling of any kind and of course have come to realize that this is a much better way to work.

I suspect there are more of you out there who are in the same boat especially if you’re using ASP.NET and Web forms. Web forms with its high level of abstraction doesn’t make it very easy to use pure CSS style layout. Controls have display properties that are just too easy to set on the controls themselves rather than setting them externally in styles and there’s no doubt doing it the right takes some diligence and is more work in the immediacy of creating pages. But there’s also no doubt that proper CSS layout makes it easier to maintain pages later and change the look of them as well as making it easier to reference content via script code.

There are also the ASP.NET CSS Control Adapters but they are a pretty intrusive change and I’ve actually had lots of issues just getting them installed on several machines.However, with a little bit of diligence even some of the badly rendering ASP.NET controls (especially the GridView) can be managed reasonably well with pure CSS layouts.

Those damn browser differences

One thing that I’ve been struggling with for a long time is browser differences even when using the strict XHTML schemas for layout. The XHTML doctypes are the first step for doing consistent layout as they force at least a reasonable baseline on all browsers (particularly IE) and force them to use certain rendering rules. But even with XHTML there are still major differences between different browsers and how they set their default settings for various CSS tags.

For example check out the following layout rendered in several browsers. The area in question is the bottom of the list where the ‘status bar’ sits.

Internet Explorer (nearly perfect fit because at the time it was set up for IE):

Ie[7]

FireFox 3:

FireFox

Safari Windows:

Safari[5]

Opera:
Opera

Clearly IE creates its elements slightly bigger than the other browsers, but it looks like all 4 browsers are rendering slightly differently in terms of the size of this frame.

The layout for this frame looks like this (I've hardcoded the frame height and width here so it's easier to see where the heights etc are coming from):

<div id="divListContainer" class="blackborder">
    <div class="gridheader">Project List</div>
    <div class="toolbarcontainer">
    <small><a href="ShowProject.aspx" class="hoverbutton"><img src="images/punchin.gif" /> New</a> | Filter: 
        <select name="ctl00$Content$lstFilter" onchange="javascript:setTimeout('__doPostBack(\'ctl00$Content$lstFilter\',\'\')', 0)" id="ctl00_Content_lstFilter" style="width:200px;">
            <option selected="selected" value="OpenProjects">Open Projects</option>
            <option value="RecentProjects">Recent Projects</option>
            <option value="AllProjects">All Projects</option>
 
        </select>  
        | Project Name: 
        <input name="ctl00$Content$txtNameFilter" type="text" id="ctl00_Content_txtNameFilter" style="width: 75px;" />        
        <input type="submit" name="ctl00$Content$btnGoFilter" value="Go" id="ctl00_Content_btnGoFilter" />
    </small>
    </div>
        <div style="height: 407px; overflow: hidden; overflow-y: scroll;">
 
            <div class="itemtemplate" onclick="showProject(38)" >
                <div class="companydisplay"><small><i>West Wind Technologies</i></small></div>
                <div class="projimg"></div>
                <b><a href="ShowProject.aspx?id=38">Conference Preparations</a></b><br />
                <small>
                    08/01/07 
                    &nbsp;&nbsp;
                    Started 
                </small>
            </div>
 
            <div class="itemtemplate" onclick="showProject(50)" >
                <div class="companydisplay"><small><i>Centiv</i></small></div>
                <div class="projimg"></div>
                <b><a href="ShowProject.aspx?id=50">TradeOne Integration</a></b><br />
                <small>
                    01/24/08 
                    &nbsp;&nbsp;
                    Entered 
                </small>
            </div>

...
 
        </div>
        <div class="toolbarcontainer">
            <small><span id="ctl00_Content_lblStatus">11 projects</span></small>
        </div>
</div>

The height values are hardcoded so in theory there shouldn't be any discrepancies here, but as you can see the placement is slightly off - as much as 5 pixels between IE and Opera which are at both high and low ends.

Browser Reset to the Rescue

The trick to making this work well across browser is to use a browser reset style sheet. Again this may be old news to some of you, but I’ve been slow to catch on and haven’t been using resets until fairly recently. The above application was built early last year and it doesn’t use a reset.

A browser reset is meant to reset the browser’s CSS setting to a common default value set. Basically each browser has slightly different base settings mostly for margins, padding, borders etc. as well as many other settings that can affect browser rendering slightly and often results in the little inconsistencies like the ones above. The reset effectively is used to reset the browser to a common baseline, upon which any further CSS settings are based.

There are a number of different reset style sheets available. Following are a few links and references to a resets:

The last link compares various versions of resets and explains the differences. It’s a good read to see some of the tradeoff and comparisons.

After reviewing resets some time ago I’ve ended up with a slightly modified version of Eric Meyer’s reset with a few changes that affect default padding and list display. I tend to want some reasonable padding for table cells and expect list to render a certain way by default.

/* BROWSER RESET (based on Eric Meyer's Reset) */
html, body, div, span, applet, object, iframe, table, caption, tbody, tfoot, thead, tr, th, td, 
del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, 
h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, 
dl, dt, dd, ol, ul, li, fieldset, form, label, legend {
    padding: 0px;
    margin: 0px;
    border: 0px;
    outline: 0px;        
    line-height: normal;
    vertical-align: baseline;
    font-family: inherit;
    font-size: 100%;
}
:focus {
    outline: 0;
    }
body {
    background: white;
    line-height: 1;
    color: black;
    }
ol, ul {
    list-style: disc;
    margin: 20px;
    }
table {
    border-collapse: separate;
    border-spacing: 0;
    }
caption, th, td {
    font-weight: normal;
    /* text-align: inherit; */
    padding: 4px;
    }
blockquote:before, blockquote:after, q:before, q:after {
    content: "";    
    }
blockquote, q {
    quotes: "" "";
    margin: 15px;
    }
input,select,textarea
{
    font-size: inherit;
    font-weight: inherit;
    font-style: inherit;
}    
/* END BROWSER RESET */

With the reset applied before any other styles the above ‘dialog’ renders properly in all browsers from IE to Chrome. Unfortunately just throwing  a browser reset into an old applications that where designed with them in mind are also likely to cause a few rendering problems, because the main feature that these resets provide is to effectively remove all padding, margins and borders by default. This will cause things to render consistently but also often may end up producing very different results.

Hence you may have to – as I did at least for older apps – tweak the base Reset a little bit to make certain things render the way you’d assumed they would when the pages were created. The two main areas for me are the table columns render (I assumed a reasonable level of padding between cells), ordered and unordered lists which I assume to have standard list indentation and bullets and also blockquote margins. None of these are major changes but these three bit me most when just throwing in any of the browser resets I tried.

Resuable Stylesheets for most Apps?

Once a base reset exists I tend to use an additional standard style sheet that includes a host of custom styles that deal with common scenarios in ASP.NET style applications from things like gridheaders, alternating rows, dialogcontent, toolbarcontainer etc. that are more application specific but seem to show up just about in any common application.

This is absolutely a personal preference but I thought I’d share this here anyway, because I’ve found this sort of baseline extremely useful in getting layouts – especially for business type applications - done quickly.

body,table,td,th,input,textarea,select
{
    font-family: verdana,sans-serif;
    font-size: 10pt;
}
pre
{
    font-family: monospace,courier new;
    font-weight: normal;
    margin-top: 5px;
    margin-bottom: 5px;
}
h1
{
    background-color: #eeeeee;
    color: navy;
    font-size: 1.5em;
    font-weight: bold;
    padding: 5px;
    text-align: center;
    margin-bottom: 15px;
}
h2
{
    color: maroon;
    font-size: 1.4em;
    font-weight: bold;
}
h3
{
    color: steelblue;
    font-size: 1.1em;
    font-weight: bold;
}
table.blackborder>tbody td
{
    border: solid 1px lightgrey;    
}
th
{
    border-collapse: collapse;
    font-weight: bold;
    text-align: center;
}
a 
{ color:#003399; }
a:visited
{
    color: darkred;
}
a:hover 
{ color:red;}
hr 
{ color: navy; background: navy; border: 0; height:1px;}
   
ul 
{
    margin-bottom: 0px;
    margin-top: 2px;
    padding-bottom: 2px;
    padding-top: 2px;
}    
li
{
    padding-top: 2px;
    padding-bottom: 0px;
}
img
{
    border: 0px;
}
.blackborder
{
    border-style: solid;
    border-width: 2px;
    border-color: #003399;
    background: white;
    text-align: left;
}
p
{
    margin: 10px 0px 10px 0px;
}
small 
{
    font-size: 0.8em;
    font-weight: normal;
}
.bigtext
{
    font-size: 1.8em;
    font-weight: bold;
    color: navy;
}

/* block backgrounds for headers etc. */
.menuband, .gridheader, .gridheaderbig, .gridpager, .buttonlinks, .blockheader, .roundedbar_top, .roundedbar_bottom
{
    color: cornsilk;
    background-color: #003399;
    padding: 0px;
}
/* alternate background color color to offset the background
   used for the category list and banner strips for color
   variety. should be a companion color to the block background
   colors (previous tag
*/
.alternatebackground
{
    color: white;
    background-color: #0066cc;
}

/* used for any block tags like headers on tables etc. */
.blockheader
{
    font-weight:bold;
}
.menucolumn 
{ 
    padding:5px;
    border-bottom: solid 1px white ;
}
.menulink
{
    color: white;
    font-size: 0.8em;
    font-weight: normal;
    text-decoration: none ;
    display:block;
    text-align:left;
    padding-top:3px;
    padding-bottom: 3px;
    padding-left: 5px;
    border: solid 1px transparent;    
}
.menulink:visited { color: cornsilk; } 
.menulink:hover 
{ 
    color:#003399; 
    text-decoration:none; 
    font-weight:normal; 
    background: white url('images/menuhighlight.png') repeat-x;
}
.menuband
{    
    font-weight: bold;
    height: 20px;
    padding-top: 5px;
    text-align: center;
    background: url('images/vertgradient.png');
}
.menulinkcontainer
{
    padding: 5px;
}

.submitbutton
{
    border-style: none;
    border-color: inherit;
    border-width: 0px;
    font-weight: bold;
    height: 35px;
    width: 200px;
    background: url('images/submitbutton.gif');
    color: lemonchiffon;
}
.submitbutton:hover { background: url('images/submitbuttonhover.gif');
} 
.submitbutton:active { background: url('images/submitbuttonpressed.gif');
}
.smallbutton
{
    border-style: none;
    border-color: inherit;
    border-width: 0px;
    height: 22px;
    width: 90px;
    font-size: 0.8em;
    color: navy;
    background: url('images/smallbutton.gif');
}
.smallbutton:hover { background: url('images/smallbuttonhover.gif');
}
.smallbutton:active { background: url('images/smallbuttonpressed.gif');
}

.gridheader, .gridheaderbig, .gridheaderleft, .gridheaderright, .gridpager
{    
    padding: 4px;
    background:  #003399 url('images/vertgradient.gif') repeat-x 50% bottom;
    text-align: center;
    font-weight: bold;
    text-decoration: none;
}
.gridheader a, .gridheaderbig a
{
    color: cornsilk;
    text-decoration: none;
}
.gridheaderleft
{
    text-align: left;
}
.gridheaderright
{
    text-align: right;
}
.gridheaderbig
{    
    background-image: url('images/vertgradient40.png');
    background-repeat: repeat-x;
    background-position: 50% bottom;
}
.gridnormal
{
    background-color: #eeeeee;
}
.gridalternate
{
    background-color: #b5c7d6;
}
.gridhighlight
{
    background-color: white;
    background-image: url(images/lightorangegradient.png);
    background-repeat: repeat-x;
    cursor:pointer;
    border: solid 2px orange;
}
.gridpager
{
    font-weight: bold;
    text-align: right;
    color: White;        
    text-decoration: none;
}
.gridpagerselectedpage
{
    color: khaki;
    font-size: 1.1em;
    font-weight: bold;    
}
.gridpagerpage
{    
    text-decoration: none;
    color: White;        
}

.groupheader  
{
    background: SteelBlue; color: White; padding: 4px; margin-top: 10px; margin-bottom: 5px; font-weight: bold;
}    
.errormessage
{
    font-weight: bold;
    color: maroon;
}
.errordisplay
{
    font-weight: normal;
    color: darkred;
    border:solid 2px darkred;
    background-color:cornsilk;
    padding: 4px 5px 4px 10px;
    line-height: 1.5em;    
    margin: 15px 0px 15px 0px;
}
.errordisplay hr
{
    color: darkred;
}
.dialogwindow
{
    margin: 0px;
    background: #eeeeee;
    font-size: 0.8em;
}

.toolbarcontainer  
{
    background:#eeeeee;
    border: solid 1px silver;
    vertical-align: top;
    padding: 5px; 
}
.hoverbutton  
{
    text-decoration:none;        
    padding: 2px;     
    font-size: 0.8em;         
    border: solid 1px transparent; 
}
.hoverbutton:hover  
{    
    background: white url('images/menuhighlight.png'); 
    border: solid 1px silver; 
}     
.hoverbutton a
{
    text-decoration: none;
}
.tabbutton, .selectedtabbutton
{
    border-style: none;
    border-color: inherit;
    border-width: 0px;
    font-size: 0.8em;
    background: url('images/tabnormal.gif') no-repeat;
    text-align: center;
    vertical-align: middle;
    cursor: hand;
    color: darkblue;
    width: 120px;
    margin: 0px;
    padding:0px;
}
.tabbutton:hover
{
    background: url('images/tabhover.gif') no-repeat;
}
.selectedtabbutton 
{ 
    font-weight: bold; 
    color: white; 
    background:url('images/tabselected.gif') no-repeat;
    cursor:default;
}
.roundedbar_top
{
    height:20px;
    width: 170px; 
    padding: 5px 0px 0px 0px;
    font-weight:bold;
    text-align: center;    
    background: url('images/roundedbar_top.png') no-repeat;
    font-size: 1em;
}
.roundedbar_bottom
{
    height:12px;
    width: 170px; 
    background: url('images/roundedbar_bottom.png') no-repeat;
}
.containercontent
{
    padding: 20px;    
}
legend
{
    text-align: center;
    font-weight: bold;
    background: #DE8079;
    color: White;
    padding: 3px;
    border: solid 1px darkred;
}    
fieldset
{
    border: solid 1px silver;    
    margin-bottom: 15px;
}
.fieldsetpadding
{
    padding: 15px;
}
input[type=text], input[type=password], textarea, select
{                
    border: solid 1px steelblue;
    border-style:inset;
    font-size: 1em;
    background-color: #F5F7FA;        
}
input[type=button], input[type=submit]
{    
}
.statusbar
{
    position: fixed;
    bottom: 5px;
    left: 0px;
    right: 0px;
    height: 16px;    
    padding: 5px;    
    background: black;
    color: white;    
    border: solid 1px lightgray;
    opacity: .70;    
    filter: alpha(opacity="70");
    z-index: 200;
    overflow: hidden;
    overflow-y: auto; 
}
.statusbarhighlight
{
    font-weight: bold;
    background-color: khaki;
    color: Maroon;
    border: solid 1px silver;
}
.statusbarclose
{
    position: absolute;
    right: 10px; 
    top: 2px;
    color:red;
    font-size: 1.2em;
    font-weight: bold;
    cursor: pointer;
}

The styles above cover a wide range of ‘control like’ scenarios that seem to be common in the business applications I tend to build or work with. For more document driven application or consumer style applications some of these things probably aren’t a good fit, but for most of the things I work on most of these styles actually are used regularly. The point isn’t so much the exact details of the items but the concept of having a style sheet that provides reusability for common UI scenarios.

Again I don’t claim to be a CSS expert – I’m mainly throwing this out here for discussion because I’m interested in what others are doing. What are you doing for ‘standard’ styling in your applications? What browser resets have you tried and which one are working for you? Do you have a standard style sheet with your own custom styles that you reuse in many applications  and what do you put in there? What are your reusable styling scenarios. Reusability of base style sheets is something I don’t see discussed much, so I’d be interested to hear what other approaches are used.

Posted in HTML  ASP.NET  

The Voices of Reason


 

Zafar Iqbal
September 24, 2008

# re: Browser Rendering Differences and Browser Resets

A good post displaying basic concept of fixing layout issues in different browsers.

Thanks Rick

k_man
September 24, 2008

# re: Browser Rendering Differences and Browser Resets

Great post. Didn't know about the browser reset and I have been struggling with CSS based layouts for years.

I like your default layout but you should consider not have any font size hard coded with point sizes (font-size: 12pt;) and use em instead (font-size: 0.9em;).

Using em's really helps with users that need to resize fonts due to accessibility issues. It takes a bit of work to make everything look right when you are use to just specifying the point size but is well worth the effort.

Kamran Shahid
September 24, 2008

# re: Browser Rendering Differences and Browser Resets

Wow,
Thanks for the info

Rick Strahl
September 24, 2008

# re: Browser Rendering Differences and Browser Resets

@k_man - yes agreed. But the top level font needs to be set (ie. for body). If there are other values they are ommissions on my part and should also be based on em spacing.

Barbaros
September 25, 2008

# re: Browser Rendering Differences and Browser Resets

Thanks for the info,

But for buttons and other thing which will have a different background image, i use css mapping.

.menu li a
{
display: block;
padding: 5px 0px 5px 20px;
height: 15px;
color: #aaa;
background: transparent url( '../images/bg-menu.png' ) repeat-x 0px -25px;


}

.menu li a:hover
{

background-position: 0px 0px;
}

Sean Moynihan
September 26, 2008

# re: Browser Rendering Differences and Browser Resets

not specifically on css but re . last paragraph of blog on " general styling " I'd be interested to know what others are doing to maximise " real-estate" . Multi-tabs work great in a lot of cases , but not always ideal

Especially interested to know if wc5 users tend to use light-box styles , or even old-style pop-up windows or even just live with fact that users will have to scroll up/down a bit

I've also found that using Fieldsets give a very effective way to present a lot of detailed business info . See sample , the various fieldsets are just dropped in with a bit of ajax , click the magnify-glass images , they have all the attributes of div's so are a great way to get away from using tables .

http://cspages.org/safexpert/apps/rst/demo_sites.wcsx

tom
September 26, 2008

# re: Browser Rendering Differences and Browser Resets

Good post Rick. I am allways battling the how different browsers render pages. Currently I am using this little app to render webpages in different versions of ie. hopefully some of you will find it usefull also.

http://www.my-debugbar.com/wiki/IETester/HomePage

k_man
September 28, 2008

# re: Browser Rendering Differences and Browser Resets

> @k_man - yes agreed. But the top level font needs to be set (ie. for body).

Rick,

Yes agreed, it should to be set. But it can be set by using em instead of pt.

Check out http://jontangerine.com/log/2007/09/the-incredible-em-and-elastic-layouts-with-css . The whole article is good but check out the section "Setting Body Font Size".

k

Rick Strahl
September 28, 2008

# re: Browser Rendering Differences and Browser Resets

@k_man - maybe I'm dense, but how would I do this? If I set my main font to 1em I get something like 12 pt which is certainly not what I'd want. so I'd start with .8em (or less)?

All recent browsers allow resizing even from fixed fonts so I'm not sure that this is more or less of a moot point. I agree that all fonts but top level should be em based to be relative, but the base body I want to make sure I get that the way I expect it to at least in 'default' mode.

neliason
October 02, 2008

# re: Browser Rendering Differences and Browser Resets

It was my understanding that some people argue you should never set the font size, even the top level, because it overrides a user's default size. The argument assumes that some people go in an adjust their font size and we should not try to override a user's default setting.

Practically speaking most people dont even know they can change their font size. And I think many people with vision problems who have issues reading smaller fonts simply use a low screen resolution to make all text and images larger. And as Rick points out modern browsers make it really easy to quickly zoom in or increase the font size for a page.

Since most people dont change their default browser font size you probably dont want to use 1em because as Rick points out that is just too big. 0.8em or less is what you'd usually want to set it to.

But I think there is nothing wrong with setting a base pixel size font.

Knowledge Capsules
October 03, 2008

# Resetting styles for coping with cross browsing differences

Resetting styles for coping with cross browsing differences

k_man
October 12, 2008

# re: Browser Rendering Differences and Browser Resets

> @k_man - maybe I'm dense, but how would I do this?

You dense??? I doubt it. I have read and learned enough from you to know better.

I think this stuff is just hard to get a handle on because the lack of stable specs, lack of adherence to specs, browser incompatibilities, browser versions, etc.

> If I set my main font to 1em I get something like 12 pt which is certainly not what I'd want. so I'd start with .8em (or less)?

I won't say that this is a best practice or even the right way to do it. All this is based on my formal and informal testing over the years.

What I do these days is set the font-size in body to 1.0em. Then if twelve point font is not the right size I set the font-size in that class. So in the case of the css example you gave I do something like have 1.0em in body and 0.8em in p (paragraph).

I agree with you that the newer browsers are a lot better at rendering the page when you zoom in but there is a large percentage (30% for one of my clients) were the customers are still coming in with IE6. And from informal tests I have done mobile devices seem to handle em sizing better.

As a side note, maybe because I am getting older, maybe because of eye strain, or maybe because I like how much it is easier to read web 2.0 styled sites, etc. I usually almost always end up sizing the font bigger on most sites I visit.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024