Published Friday, 1. October 2010, 00:53, Danish time.

Over time there has been a lot of ranting and quarrels on the net about ASP.NET WebForm’s “name mangling” – which is WebForm’s computed ID attributes on HTML elements generated by server side WebControls. Just try to search Google for “ASP.NET” + “name mangling”. The sum of web designer work hours spend worldwide on fighting with this in ASP.NET’s life time must be astronomical.

I have read a lot of these discussions and it puzzles me that I never found a good description of the root cause in any of these discussions on the net.

It's really a basic and unsolvable conflict between object oriented web development and precisely targeted CSS styling.

The problem is of course not unique to ASP.NET WebForms; it applies to all component based page frameworks.

Let’s go through it.

The web developer side of the problem

When you are developing a web page component and deliver it “to the world”, you never know where, how often, and how your component is used. It follows from object oriented thinking (OO) that a class doesn’t know about its container.

If somebody decides to use multiple instances of your component in the same page, and they all render the same HTML element ID, this would violate W3C standards. HTML element IDs must be unique in an HTML page.

In WebForms up until .NET version 3.5 SP1, Microsoft solved this problem by automatically computing the IDs rendered. On a WebForm, controls live inside other controls and the rendered HTML IDs will then basically reflect the tree structure that the controls form. That’s why you see IDs like “MainForm_SideBar_SearchButton”. (In this case, the SearchButton control lives inside a control named “Sidebar”, which again lives inside a control named  “MainForm”.)

If somebody then moves the SearchButton control out of the Sidebar, it will get a new ID. Not so nice if you depend on the IDs – which is exactly what web designers tend to.

The web designer side of the problem

Web designers like element IDs.

When you write CSS, the IDs have the highest priority when the browser determines which style to use for a given HTML element. IDs are said to have a high “CSS specificity” and surpass classes and element types. This means that styling against IDs is safe, if you want to be sure that your CSS rule trumps everything else (and right now we totally ignore using local styles – which is bad practice anyway).

If you want to read more about how the browser calculates specificity, I recommend W3C’s description which is short and precise (there is another good description here).

It’s perfectly fine to style against IDs, if what you are styling is HTML in a single, flat .html file. But as soon as you move into the enterprise level web apps – or just work on complex web apps in general – you are not in control of all the HTML being spit out.

The essence of this is, that it's a bad idea to base styling on IDs when working in the world of componentized web pages.

The solution: style against CSS classes

Luckily, with some planning and coordination, it’s fairly easy to make things work using CSS classes instead of IDs. And if you combine HTML element type and CSS class name, you will get a pretty good CSS specificity out of it. This way you will lower the risk of having colliding CSS styles. You can also just add more classes and element types to a selector in order to give it higher specificity, so “div.layout ul li” will have higher specificity than “ ul li”.

There are of course cases, where it makes sense to style against IDs – e.g. a page header showing a logo image. In these cases, consider writing the plain HTML directly in the file yourself, instead of having components rendering it. Then it’s very visible to others what goes on. Oh, and you should not overwrite the Render() method in ASP.NET components to manipulate the rendered IDs – it will just get you into trouble at some point.

More thoughts and afterthoughts

In general, you should think of CSS class names as "the contract" between the developer and the designer. In a component based site, CSS designers should think: “every time an element like this shows up, I want it styled like this”. Things are not as predictable as with static HTML pages, which is why CSS people must think in a more generalizing way.

I think that the CSS specificity rules also show that CSS was really designed to deal with plain, static HTML files – rather than dynamically generated pages.

In WebForms in .NET4, Microsoft has partly solved the problem with the introduction of the ClientIDMode property, which gives the developer better control over the rendered HTML ID, including locking it down entirely by setting ClientIDMode=Static.

But the fundamental OO vs. CSS conflict is still there.

Add comment

  Country flag

  • Comment
  • Preview