LANGUAGES: C# | VB.NET | HTML
ASP.NET VERSIONS: 1.x
Ease Control Positioning Headaches
HTML Allows Great Flexibility for Page Design, but All the Options Can
Be Overwhelming - Unless You Know a Few Tricks
You’ve had problems with the WebForm designer in Visual Studio.NET. I know you have.
Controls have refused to go where you drag them, or they show up in different places
at run time than design time. Or maybe the designer has chosen to reformat HTML
that you’ve carefully typed. In fact, I don’t know a single developer who would
claim the HTML designer included with Visual Studio.NET is the best one around —
but it’s not the worst one, either. Once you understand some key techniques, it’s
possible to become quite efficient with it.
If you’re background is centered more in Windows development than Web development,
you’re likely more confused by the WebForm designer than most. The simplicity of
the Windows Forms designer is appealing compared to all the complex options available
in the WebForms design environment. However, once you’ve mastered the power that
WebForms (and HTML) have to offer, you’ll be whining about why you can’t design
things so flexibly in Windows Forms applications. Happily, Microsoft has made great
strides in improving both the WebForms and Windows Forms designers in the upcoming
Visual Studio.NET 2005, but you don’t need to wait until then to develop great applications.
This article will help you get the most out of the current technology.
When a new Web application project is created in Visual Studio.NET, a default WebForm
is created. Notice the text immediately visible in the center of this form. The
text says, “The page you are working on is in grid layout mode, and objects will
be arranged using absolute (x and y) coordinates. To use flow layout (top to bottom,
as in a word document), change the pageLayout property of the document to FlowLayout.”
It’s a message you’ve likely seen many times before, although it seems many developers
haven’t put much thought into its meaning.
If you’re from a Windows development background, you’ll find the default GridLayout
mode to be familiar and intuitive. Quite simply, if you drag a control to a pixel-specific
position on your form, it will stay there. You might wonder why anyone would ever
want a behavior other than this. Well, there are a few reasons why FlowLayout is
often a better choice than GridLayout.
Compatibility
The original HTML specification didn’t allow for precise placement of controls on
a Web page. The whole concept was to let the content of a page flow naturally to
whatever dimensions the user’s display allows. This foundational feature of HTML
is still in place today, and it is used by default on a WebForm when the pageLayout
property is set to FlowLayout. This adaptive layout is quite appealing in many ways.
For example, it empowers the Web browser to make decisions about how best to display
the content so you don’t have to worry about how the page will look on various devices
at various sizes, color depths, and resolutions. Therefore, it is virtually guaranteed
that content will always be displayed in a reasonable and useful way to the user.
It also allows you to dynamically output content of various sizes without worrying
about how it will affect other elements of your page. For example, if today’s article
of the day is unusually long, the page height will automatically expand and your
page footer will appear underneath the article as you’d expect.
However, some Web design artists are more interested in pixel-perfect placement
than they are with universal compatibility. It can be quite annoying to finally
get a control positioned just perfectly at design time, only to see some errant
Web browser choose to “fix” it by placing it elsewhere. Pixel-perfect placement
of Web page elements is one of the many issues that Cascading Style Sheets (CSS)
addressed when it was created, and GridLayout is the ASP.NET technology that exploits
it. It’s the only practical way to ensure a complex HTML page is displayed exactly
as a graphic artist designed it to look.
If you are in the fortunate position of being able to presume all your users have
a modern, fully functional PC-based Web browser, then GridLayout can be a great
tool. However, if you need to support a variety of browsers and handheld devices,
then you’re probably better off sticking with the more conventional FlowLayout approach.
Figure 1 concisely describes the pros and cons of both pageLayout
options.
|
Pros:
·
Compatible with every web browser and many handheld devices
·
Content is dynamically positioned so it should always look
decent
Cons:
·
Content may look decent, but you can't generally ensure
it will look great
·
Hard to predict how the content will look to all your users.
Pros:
·
Simple concept based on X & Y positioning
·
All content will display exactly where you've specified
Cons:
·
Limited compatibility with handheld devices & older
browsers
·
Dynamic content can spill out of designated
areas to look ugly and unreadable if you’re not careful
|
Figure 1: GridLayout and FlowLayout both
are valid options, but neither are perfect for all scenarios. Luckily, you can often
mix and match them to get the best of both worlds.
GridLayout Rendering Details
GridLayout is the default pageLayout property for every WebForm in a new Visual
Studio.NET Web application. Unfortunately, there is no good way to change this default.
However, once a new project has been created, this default can at least be changed
on a project-wide basis. To do this, select Properties from the Project dropdown
menu in Visual Studio.NET. Then select Designer Defaults in the treeview on the
left side of the dialog box (see Figure 2). Flow or Grid can then be selected from
the Page layout dropdown list. From this point on, whenever you add a new WebForm
to the project, it will (by default) have the pageLayout property that you’ve selected.
(You can still change the pageLayout on a page by page basis and have various pages
that use different layout modes, if you choose.)
Figure 2: When you start a new Web application,
you might want to adjust the default pageLayout property for your WebForms so you
won’t have to make this tedious adjustment to each of them individually.
If you drag a CheckBox Web control onto a blank WebForm that is set to GridLayout
mode, then run the project and view the resulting HTML, you’ll see this representation
of the CheckBox:
<span style="Z-INDEX: 101;
LEFT: 192px;
POSITION: absolute; TOP: 168px">
<input id="CheckBox1" type="checkbox"
name="CheckBox1" /></span>
You’ll notice that the CheckBox is placed inside a span tag that is absolutely positioned
at a specific pixel location using the LEFT and TOP pixel coordinates. Additionally,
a Z-INDEX is specified so you can place controls on top of (or beneath) other controls.
All this is great if the user’s browser supports it, but what happens if it doesn’t?
Well, ASP.NET is fairly smart about such matters, and does its best to compensate
if it detects an older “low-level” browser. If ASP.NET suspects the browser may
not be able to handle CSS positioning, it instead outputs nested tables to approximate
the positioning you’ve specified on your WebForm. That exact same checkbox will
be positioned with very different HTML if ASP.NET determines it to be necessary:
<TABLE height="189" cellSpacing="0"
cellPadding="0" width="297" border="0" ms_2d_layout="TRUE">
<TR vAlign="top">
<TD width="192" height="168"></TD>
<TD width="105"></TD>
</TR>
<TR vAlign="top">
<TD height="21"></TD>
<TD>
<input id="CheckBox1" type="checkbox" name="CheckBox1" />
</TD>
</TR>
</TABLE>
As you can see, a whole table structure must be created around the checkbox to attempt
to position it in the appropriate place. If you were designing a form in FlowLayout
mode, there’s a good chance you’d manually structure the page similarly to achieve
the same layout. It can be convenient for ASP.NET to automatically generate this
code for you. In effect, you might think of it as automatically converting a grid
layout to more of a flow layout. However, the result is sometimes less than perfect.
On complex pages the controls don’t always end up being positioned exactly where
you’ve specified. Additionally, it’s not especially efficient code compared to the
more concise CSS syntax, so it’s nice to avoid this kind of HTML output when you
can. It’s also nice to be able to override ASP.NET’s default decisions about when
to render low-level output. For this purpose, the targetSchema property of a WebForm
can be used to manually specify the flavor of HTML that is output. The Project Properties
dialog box discussed earlier (again, see Figure 2) allows you to set the default
targetSchema property for all new WebForms.
Precision Positioning: Be Careful What You Wish For
The beauty and the bane of GridLayout mode is that controls are placed exactly where
you specify. For example, let’s take a basic Web page with a banner at a top position
of zero, a DataGrid placed near the center 200 pixels down, and a page footer near
the bottom at pixel row 600. Tests show the page to look great when the DataGrid
has 10 rows, but when the DataGrid has 20 rows, it spills over the top of the footer
beyond row 600, causing an ugly, unreadable mess.
Because you’re choosing exactly where you want the controls, you now also need to
control exactly how big they get or else you’re going to end up with various crowding
problems such as this. It’s the kind of problem you’re asking for when you choose
GridLayout mode, and it is one of the main reasons I usually choose FlowLayout for
my WebForms. But don’t be too discouraged; there are usually some reasonable solutions
if you’re determined to stick with GridLayout. For example, you can box a DataGrid
inside a CSS “overflow” area of a specified size so it will never take up more space
on the page than you’ve specified:
<div style="OVERFLOW:auto;WIDTH:300px;HEIGHT:400px">
<asp:DataGrid id="DataGrid1"
runat="server"></asp:DataGrid>
</div>
If the DataGrid grows bigger than 300x400 pixels, the HTML above specifies that
scroll bars will “auto”matically appear as needed so the user will still have access
to all the information contained within the grid. This technique will work with
virtually any page element, not only a DataGrid.
Go with the Flow
In the early days of ASP.NET, there was a bit of a religious debate about which
layout mode was better. In many ways, this is like trying to decide if VB.NET or
C# is better. (Answer: they are both better in their own ways.) However, on the
subject of page layout, the debate has died down and the majority has spoken. These
days most experienced ASP.NET developers will tell you that FlowLayout is the way
to go most of the time. Don’t get me wrong — there’s no doubt that GridLayout is
very useful in many situations, but it often feels a bit like trying to fit a square
peg into a round hole. It has a bolted-on-after-the-fact feeling to it — because
it was. The beauty and strength of classic HTML (represented by FlowLayout) has
always been its ability to adapt content to a variety of Web browsers, screen sizes,
and related display devices. So if you’re using the rigid GridLayout mode (which
was not originally supported in HTML), then you should recognize you’re going against
the grain. Microsoft has recognized this shift in developer sentiment and the result
is that FlowLayout will be the new default pageLayout for WebForms in ASP.NET 2.0.
With FlowLayout mode, you don’t specify precise positions for controls. You won’t
find any Top or Left properties, nor will you find references to X, Y, or Z. Controls
are placed relative to other controls. You can specify that you want a textbox placed
next to a label, or underneath a label, but the browser will make the final decision
on the precise positioning based on the space available. Tables and Panels are often
used to ensure sets of related controls are grouped together. They are often used
in complex combinations, such as nesting a table inside the cell of another table.
Common sets of controls are often converted into user controls so they can be reused
on many pages within a project.
The HTML Table control (found on the HTML tab of the Visual Studio.NET toolbox)
is an excellent tool to use for positioning various elements of a Web page at design
time. You resize columns and rows with the click of a mouse, drag and drop controls
wherever you wish, and create new table cells easily via the right-click menu. If
you’d like to be able to interact with the table at run time, simply mark it with
the RunAt = Server attribute. If you only need to interact with specific rows or
cells of the table at run time, then you can mark only those elements with the RunAt
= Server attribute. This can be handy for hiding or highlighting page elements dynamically.
Don’t confuse the HTML Table control with the Table Web control that’s found in
the Web Forms tab of the Visual Studio.NET toolbox. The Table Web control is a bit
weak at design time compared with its HTML control counterpart, but it is a powerful
tool for building page sections dynamically at run time.
It should be noted that if you drop a control onto a GridLayout WebForm and then
switch the WebForm to FlowLayout, the control will be a bit confused about how it
should position itself. It will still have the absolute positioning style elements
in its HTML definition, and therefore may not flow quite as you’d expect. If you
truly want the control to switch to FlowLayout, you can go into the HTML view of
the page and delete the positioning style attributes. Alternatively, you can delete
the control and drag a new instance of the control onto the form in its place. This
new control will clearly see that the form is using FlowLayout and will conform
without hassles.
Why Be Choosey?
Don’t stress out about which pageLayout mode to pick. You can have the best of both
worlds. On the HTML tab of your Visual Studio.NET toolbox you’ll find two often-ignored
controls named Flow Layout Panel and Grid Layout Panel. You can use either of these
controls on any WebForm, regardless of the WebForm’s pageLayout property value.
As you might have guessed, these controls will let you have a GridLayout area inside
a FlowLayout page, and vice-versa. This can certainly be useful for leveraging the
strengths (and negating the weaknesses) of both techniques. When placing a control
inside a Grid Layout Panel, you should understand that the top-left position (0,0)
represents the top-left position of the Grid Layout Panel, not the WebForm. Therefore,
you could have many top-left positions in your page if you have many Grid Layout
Panels.
These special panel controls can also be useful when designing your own Web controls,
because you can use one to specify the placement of your control’s various elements
using whichever layout technique you prefer — without regard to the pageLayout property
of the hosting page.
Conclusion
In summary, although FlowLayout is usually the best default for ASP.NET development,
don’t be afraid to switch to GridLayout when you need it — especially if wide compatibility
is not a requirement. The important things to understand are the benefits and drawbacks
of the available options, and how various techniques can be mixed together to accomplish
any design imaginable. Hopefully you now have a better understanding of these types
of control positioning details.