Web Q&A

Web Page Layout, Quirks Mode, and More

Edited by Nancy Michell

Contents

Debugging Without Admin Rights

Q I've heard it's better to use absolute/relative positioning as opposed to a table-driven layout on a Web page. Is that true? I've also heard that it's really better to use cascading style sheets (CSS) only and try to avoid the use of JavaScript altogether. What are the issues I will most likely encounter when I make the choice?

Q I've heard it's better to use absolute/relative positioning as opposed to a table-driven layout on a Web page. Is that true? I've also heard that it's really better to use cascading style sheets (CSS) only and try to avoid the use of JavaScript altogether. What are the issues I will most likely encounter when I make the choice?

A There was one case here at Microsoft in which a site had to be localized to work with 31 different languages. The site was originally written for English only and had absolute/relative positioning all over the place. Once all the strings were translated, the site looked really horrendous because everything was positioned based on the length of strings in English. To fix the problem, all the HTML had to be rewritten to use table layouts to produce a consistent look across languages.

A There was one case here at Microsoft in which a site had to be localized to work with 31 different languages. The site was originally written for English only and had absolute/relative positioning all over the place. Once all the strings were translated, the site looked really horrendous because everything was positioned based on the length of strings in English. To fix the problem, all the HTML had to be rewritten to use table layouts to produce a consistent look across languages.

On the other hand, table layout is generally not compliant with accessibility standards; you need to use CSS for that. Tables are appropriate for table data such as financial data and other lists of information, but only in specific scenarios. You should use a text reader on your site to see if it is accessible—it's a good exercise for anyone who is not vision-impaired.

You can recreate pretty much any table layout using CSS. It's not always fun, but it will work. There's been a move away from tables and towards CSS layout in a few places in Microsoft, most notably at www.msn.com. You can view the source if you're interested. There are also some findings at www.danboe.net.

You also need to consider whether or not you want to use "quirks" mode (explained in the next question). When you don't use quirks mode in Microsoft® Internet Explorer and other browsers, the layout challenges really begin.

Some Web controls (like the DataGrid and file upload) require additional CSS tricks (horizontal line only, row height, and so on) and extra layout work for browsers other than Internet Explorer to meet the compliance requirements.

Q Can you tell me what the terms "quirks mode" and "standards mode" refer to?

Q Can you tell me what the terms "quirks mode" and "standards mode" refer to?

A In the early days of the Web, different browsers exhibited differ-ent behavior for the same HTML code. Along with the later browser versions (Internet Explorer 6.0, for example), came more rendering standardization. One major player in the standards game was the Document Type Definition (DTD) which helped pages comply with W3C rendering recommendations.

A In the early days of the Web, different browsers exhibited differ-ent behavior for the same HTML code. Along with the later browser versions (Internet Explorer 6.0, for example), came more rendering standardization. One major player in the standards game was the Document Type Definition (DTD) which helped pages comply with W3C rendering recommendations.

However, when these new standards and new browser interpretations are enforced, older Web pages often render incorrectly and can be both unappealing and dysfunctional because the new rendering engines often can't make sense of the convoluted coding these pages employed to make the layout look the way the designer wanted it. As you may remember, some strange contortions were required in the old days to make pages look nice.

Under this new system, when one of these later browsers receive a document with a DTD indicated in the DOCTYPE element, the browser renders the page according to these new standards—this is called standards mode. If there is no DOCTYPE element, the DOCTYPE is unclear, or if any one of many other conditions exist, such as DOCTYPEs that state the version of HTML that should be rendered, then the browser renders in quirks mode. Of course there are other modes as well. Content that is identified to the browser as text/xml or other XML or XHTML MIME types is rendered in strict mode.

While there is more to this topic, the basic answer is that the mode tells the browser how to interpret the layout code for the page. For more information on rendering compatibility, see compatMode Property.

Q More and more I'm hearing about DTDs. Can you explain what they're used for?

Q More and more I'm hearing about DTDs. Can you explain what they're used for?

A A DTD is a Document Type Definition, and a DOCTYPE is the HTML element that indicates to a browser exactly which DTD it should use. As noted in the previous answer, a DTD gives the browser information about how to render the page. The following shows an example:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "https://www.w3.org/TR/html4/loose.dtd">

A A DTD is a Document Type Definition, and a DOCTYPE is the HTML element that indicates to a browser exactly which DTD it should use. As noted in the previous answer, a DTD gives the browser information about how to render the page. The following shows an example:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "https://www.w3.org/TR/html4/loose.dtd">

This DOCTYPE element points the browser to the exact location of the DTD. In each DTD, all elements and text styles, and what they mean, are defined. Numbering style, bullet styles, alignments, margins (in pixels), and tons of other specific rendering instructions are spelled out. If you design a Web page using a particular DOCTYPE definition but then refer to a different DTD, the page will not look as you intended. But choosing a DTD does eliminate the problem of different browsers rendering pages differently and unexpectedly.

Remember also that if you want to validate your HTML using a tool, you will need to tell the tool what to measure against, and you do that by indicating a DTD. The W3C's HTML validator can be found at validator.w3.org, and other validators are available from www.w3.org/QA/Tools/#validators for your validation needs.

Web pages are much more complex today than they were a few years ago, and readers expect a professional look. Using DTDs keeps you from leaving the appearance of your Web site and the location and presentation of all its elements to chance. There's lots more to explore on this topic at Working with HTML DOCTYPE Declarations in FrontPage.

Q I want to prevent users from clicking a button in my application multiple times. Each time this button is clicked, a new record is added to the database and I don't want duplicate records added.

Q I want to prevent users from clicking a button in my application multiple times. Each time this button is clicked, a new record is added to the database and I don't want duplicate records added.

I've tried various ways to accomplish this, but with little success. The main issue I've encountered is having the server-side code still execute when I disable the button on the client side, while still allowing the validation controls to work. Is this possible?

A The code in Figure 1 illustrates how you can disable the controls upon submission. One thing you should take into consideration is that if the user clicks the Stop button while the page is posting, then you will end up with a page that might have the buttons disabled and may be unusable. This code has been tested with validator controls and, with their current implementation, it seems to work fine.

A The code in Figure 1 illustrates how you can disable the controls upon submission. One thing you should take into consideration is that if the user clicks the Stop button while the page is posting, then you will end up with a page that might have the buttons disabled and may be unusable. This code has been tested with validator controls and, with their current implementation, it seems to work fine.

Figure 1 Prevent Repeated Submission

DisableCtrlOnSubmit

public class DisableHelper {
    public static void DisableCtrlOnSubmit(
            System.Web.UI.Page Page, params string[] strControls) {
        StringBuilder sbJS = new StringBuilder(200);
        sbJS.Append ("<script language='javascript'>");
        sbJS.Append (@
          "function MSDisable() { 
             try { 
               if (Page_IsValid==false) return;   
               window.setTimeout('MSDisableCtrls()',0);
             }
             catch(e) { 
               window.setTimeout('MSDisableCtrls()',0);
             } 
           }");
         sbJS.Append ("function MSDisableCtrls() { ");
         foreach (string strControl in strControls) {
             sbJS.Append (strControl);
             sbJS.Append (".disabled=true;");
         }

         sbJS.Append ("}</");
         sbJS.Append ("script>");
         if (!Page.IsClientScriptBlockRegistered("MSDisableImpl")) {
             Page.RegisterClientScriptBlock(
                 "MSDisableImpl", sbJS.ToString ());
         }
         Page.RegisterOnSubmitStatement ("MSDisable", "MSDisable();");
     }
 }

Figure 1 Prevent Repeated Submission

Using DisableCtrlOnSubmit in a Page

<html>
    <head>
        <title>Disable Ctrls</title>
    </head>
    <body>
        <form id="Form1" method="post" runat="server">
            <asp:textbox text="0" id="TextBox1" runat="server" />
            <asp:requiredfieldvalidator id="RFV1" runat="server" 
                errormessage="Required" controltovalidate="TextBox1" />
            <asp:comparevalidator id="CFV1" runat="server" 
                errormessage="Numeric" operator="DataTypeCheck"
                controltovalidate="TextBox1" type="Integer" />
            <br />
            <asp:textbox text="0" id="TextBox2" runat="server" />
            <asp:requiredfieldvalidator id="rfv2" runat="server"        
                errormessage="Required" controltovalidate="TextBox2" />
            <asp:comparevalidator id="cfv2" runat="server" 
                errormessage="Numeric" operator="DataTypeCheck"
                controltovalidate="TextBox2" type="Integer" />
            <br />
            <asp:label id="lblResult" runat="server" text="Result:" />
            <asp:button id="cmdAdd" onclick="Add" 
                runat="server" text="Add" />
            <asp:button id="cmdSubstract" onclick="Substract" 
                runat="server" text="Substract" />
            <br />
            <asp:validationsummary showmessagebox="True" 
                id="ValidationSummary1" runat="server" />
        </form>
        <script runat="server" language="C#">
            void Page_Load (System.Object sender, System.EventArgs e) {
                DisableHelper.DisableCtrlOnSubmit (
                this, "Form1.cmdAdd", "Form1.cmdSubstract");
            }
            void Add (System.Object sender, System.EventArgs e) {
                lblResult.Text = (Int32.Parse (TextBox1.Text) + 
                    Int32.Parse(TextBox2.Text)).ToString();
                System.Threading.Thread.Sleep (2000);
            }
            void Substract (System.Object sender, System.EventArgs e) {
                lblResult.Text = (Int32.Parse (TextBox1.Text) – 
                    Int32.Parse(TextBox2.Text)).ToString();
                System.Threading.Thread.Sleep (2000);
            }            
        </script>
    </body>
</html>

The idea is that you only disable controls you want to disable (of course it could be used to disable a Div or a Panel or something that contains other controls), so in the Page_Load you just add any controls that support the HTML-disabled attribute that you want to disable on postback, like so:

DisableHelper.DisableCtrlOnSubmit(this, "Form1.cmdAdd",
    "Form1.dropDownList1", "Form1.cmdOk", "Form1.cmdCancel");

You might want to consider changing the code so that you pass a reference to the button and use GetPostBackEventReference so that your controls inside other naming containers work.

Q I want to be able to develop and debug ASP.NET solu-tions without giving developers admin rights on either the client or the server. I realize that there are a couple of Knowledge Base articles on debugging without admin rights but my developers need to be able to set up new solutions in Visual Studio® .NET 2003 without admin rights to the Windows Server™ 2003 installation.

Q I want to be able to develop and debug ASP.NET solu-tions without giving developers admin rights on either the client or the server. I realize that there are a couple of Knowledge Base articles on debugging without admin rights but my developers need to be able to set up new solutions in Visual Studio® .NET 2003 without admin rights to the Windows Server™ 2003 installation.

A The question of which rights to allow developers is one of risk versus productivity, in that there are tasks that developers commonly perform that may require administrator rights. Restricting developers to only user-level rights (even on their own machine) means that someone else will need to perform these tasks (such as installing new tools, for example) for them. Alternatively, you can provide your developers with both a low-privileged account and a local administrator account, and have them use RunAs to elevate their privileges where necessary to accomplish administrative tasks (this is automated when running Setup.exe packages, so a low-privileged user will automatically be prompted for elevated credentials for the install). Of course, the developers should be strongly encouraged to run using the low-privileged account by default.

A The question of which rights to allow developers is one of risk versus productivity, in that there are tasks that developers commonly perform that may require administrator rights. Restricting developers to only user-level rights (even on their own machine) means that someone else will need to perform these tasks (such as installing new tools, for example) for them. Alternatively, you can provide your developers with both a low-privileged account and a local administrator account, and have them use RunAs to elevate their privileges where necessary to accomplish administrative tasks (this is automated when running Setup.exe packages, so a low-privileged user will automatically be prompted for elevated credentials for the install). Of course, the developers should be strongly encouraged to run using the low-privileged account by default.

It's important to balance risk against productivity. If developers have too few privileges, they will be unable to replicate the target user environment, and will not be able to test their own code. With too many privileges, they will not be able to test how well their code behaves under the target user's privilege, and the application produced may require unnecessary privilege levels in order to run. These kinds of bugs, sometimes referred to as LUA bugs (for least-privilege user account), result from developing with elevated privilege, and can be very painful and expensive to track down and fix.

Please note that Visual Studio 2005 will ship with out-of-the-box support for creating and debugging ASP.NET applications as a least-privileged user, without requiring IIS at all, using a local-only Web server that comes with Visual Studio 2005. It's important to note that this will require additional testing to ensure that your code works in your deployment environment, but this feature is designed to support precisely the scenario described.

Debugging Without Admin Rights

Here are some resources for developing and debugging ASP.NET applications without admin rights:

Send your questions and comments to  webqa@microsoft.com.

Thanks to the following Microsoft developers for their technical expertise: Gaylon Blank, Daniel Boerner, Greg Bybee, Jim Cheshire, John Conwell, G. Andrew Duthie, Sean Gephardt, Brian Hitney, Alun Jones, Carlos Aguilar Mares, Eduard Rusanovschi, Michael Schmidt, Matthew Smolen, and James Whittred.