Why CSS ID selectors are Evil in ASP.NET Web Forms

Anyone familiar with CSS knows that class selectors are generally reserved for controlling how an element looks (font, color, size, etc) and id selectors are generally reserved for where the element is positioned on the screen.  The reason for this is that id selectors correspond to the id attribute of the elements on the screen and if you are using well formed html, you can only have one element on the page with any specific ID.  That is, IDs are unique.

However, ASP.NET uses that exact same feature of IDs… that they are unique.. to ensure that an ASP.NET control or an HTML control with the runat=”server” attribute set also have unique IDs, and this is where all the problems start.

Let’s say you have an aspx page with an asp:Label control on the screen with an ID of label1.  (Highly descriptive name, I know, but this is just an example.)  For our first example, we will just place this on a regular aspx page and there won’t be any master pages or user controls involved.

In our css file, we can then create a rule:

#label1{ layout information here }

And everything will work as intended.

But, place that same label inside of a user control and it won’t work.  This is because the asp.net runtime will generate a new ID attribute that is a combination of the user control’s ID and the Label control’s ID.

You get a similar behavior when you put a label in an ASPX page that has a master page attached to it.  In this case, you end up with an ID prefixed with ctl00_.  (You ARE using master pages, right?!)

OK, you say.  So, we just won’t use id selectors in combination with ASPX Controls.  We’ll do all of our positioning with DIVs that have IDs.

Well, that sounds good until the real world strikes.  What happens when you discover that you need to make that DIV a runat=”server” control?

Yep, you run into all the same issues.  That rule that was working so beautifully suddenly stops working.  Arrrgh!

So, what to do?

Well, you really have two choices.  You can come up with some sort of naming convention that let’s everyone know that the ID is part of a CSS rule and therefore the element it is in can’t be made a runat=”server” control.  Or, you can avoid using ID selectors in ASP.NET completely.  In this case, you might use multiple classes per element.  One class would be the positioning class and the other would be the presentation class.  Like so:

<div class=”posClass dispClass”>more text and html here</div>

The advantage of using a special naming convention is that you can still be sure the names are unique.  The disadvantage is that you are going to have times when you are going to need to do some wacky html tricks to achieve what you want.  For example, you may need to hide a div using the code behind file.  But, because you can’t make it a runat=”server” control, you will need to create another div that is runat=”server” so that you can hide the element without killing the rule.

On the other hand, if you use classes, you have no assurance that the class will be assigned uniquely to one an only one element.  But, you will be able to make any control on the screen a runat=”server” control if you need to.

For my own coding purposes, I’ve chosen to use classes exclusively and have banned ID selectors from my style sheets.  In my mind the flexibility outweighs the possibility that I’ll be using the same positioning class in multiple locations.

So, how have you solved this issue?  Let me know in the comments section.

Like this Article? Subscribe to get every article sent to your email.

Related Post

  • if IE Conditional CSS using ASP.NET Themesif IE Conditional CSS using ASP.NET Themes Yesterday when I introduced Artisteer I mentioned that they use conditional link comments to include IE6 and IE7 specific CSS in the master page. In my world, I like to use ASP.NET […]
  • Finding a CSS Class DefinitionFinding a CSS Class Definition A couple of weeks ago I pointed out that you could easily find the definition of a property, method, variable, or class by right-clicking the item and selecting, "Go To Definition" from […]
  • Unique BODY tags per pageUnique BODY tags per page Last week I talked about a situation where the previous programmer had placed the body tag inside the ContentPlaceholder in order to allow for a different body tag on the page. Since […]
  • Two CSS Files When Using ASP.NET Themes?Two CSS Files When Using ASP.NET Themes? One of the projects that I'm working on is for a company targeting the Canadian marketplace.  These sites have to be written in both French and English for that country, which means there […]
  • ASP.NET Web Design SoftwareASP.NET Web Design Software What if there was a product that would allow you to create your web site themes as easy as you could create a PowerPoint presentation theme?  Wouldn’t that be cool? This past weekend I […]

About Dave Bush

Dave Bush is a .NET programmer and Certified ScrumMaster who is passionate about managing risk as it relates to developing software. When he is not writing or speaking about topics related to Application Lifecycle Risk Management (ALRM), he is an example to his peers as he develops web sites in the ASP.NET environment using industry best practices.

One Pingback/Trackback

  • Richard

    Alternatively, if you’re absolutely sure that the control will only appear in the markup once, you can set ClientIDMode=”Static” on the server control to get the desired behaviour.

    • Dave

      Yes, if you are using a more recent version of .NET, you could do that. But just the fact that you have to qualify the comment indicates that it isn’t a way that you’re going to be able to confidently give a new programmer.

  • Phil

    > You ARE using master pages, right?!

    Wrong. I’ve never liked master pages, partly for the sort of issue decribed here. A combination of common style sheets and user-controls (for the header, header.ascx, for example) can achieve much the same practicality without the headaches involved in using master pages.

    • Dave

      I hope we never work for the same organization then :)

  • http://lbrtw.com/ Anders

    Well, the culprit isn’t ASP.NET, but rather older versions of ASP.NET WebForms. ASP.NET MVC does not have this problem, but instead hands the problem of id uniqueness over to you to deal with.

    Also, the system ASP.NET WebForms used for decorating control ids in repeaters and custom controls is well-known and actually very predictable. But that is not saying it is a good thing.

    If you opt for using old versions of ASP.NET WebForms you have yourself to blame really. :) Upgrade to later versions if you are stuck in old projects, or stay away from WebForms for newer projects.

    • Dave

      Yes, the article is targeting web forms. Unfortunately, most of us don’t have a choice as to which platform we are programming in but we do have some control over how we work with the platform we’ve been handed. Many organizations stay with what they’ve always done because the cost of upgrading to Microsoft’s flavor of the week, regardless of how good it is (and I agree, MVC is the way to go if you can convince those controlling your platform to move in that direction) is too high. Not only does it cost money to train your programmers, many of which can barely handle the coding they are doing, but the cost of rearchitecting and recoding the existing applications is high.

      When I have a choice, now, all of my development is some sort of MVVM using knockoutjs and jQuery, which largely takes care of many of the issues this article addresses. But I’m also still maintaining old ASP.NET 2.0 web form applications.

  • http://lbrtw.com/ Anders

    Yes, it’s true that some organizations never upgrade, and it’s a pity, because I don’t agree that staying with outdated development frameworks is cheaper than upgrading. And you shouldn’t have to upgrade to the flavor of the week, just keep it to the flavor of the decade. (Note: Rant is not against you, but rather targeted at execs who don’t understand that old frameworks cost more to maintain than to upgrade in the long run)

    Also, employing senior developers for twice the salary, but who gets five times the work done compared to “programmers, many of which can barely handle the coding they are doing” is a good thing.

    I think we actually agree… :)

  • Pingback: Dew Drop – February 28, 2013 (#1,506) | Alvin Ashcraft's Morning Dew

  • http://twitter.com/velvetflair/status/308093387385491456/ @velvetflair

    Why CSS ID selectors are Evil in http://t.co/qRlcceBB1J Web Forms http://t.co/Wky6wvumq5

Awards & Certs


Links