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

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.


Other post in ASP.NET

Related Post

  • 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 […]
  • WebForms vs MVC–The War Is OverWebForms vs MVC–The War Is Over loading... I just finished listening to a DotNetRocks podcast today with Paul Sheriff which largely talked about creating mobile web sites using ASP.NET WebForms. During the show they […]
  • CSS Animation ResourcesCSS Animation Resources loading... This week I discovered CSS Animations.  Well, I shouldn’t say I discovered it so much as I finally spent some time figuring out what it is and why I would care about it.  […]
  • Responsive Web Design ConversionResponsive Web Design Conversion Several weeks ago, I started the process of converting this blog to a responsive design.  At this point it is mostly done.  But it is done enough that I can tell you the process […]
  • ASP.NET Cross Domain Form SubmissionASP.NET Cross Domain Form Submission Not to be confused with cross page posting, cross domain submission allows us to post the contents of an ASP.NET form to a completely different domain. To achieve this we will need to […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer focusing on ASP.NET, C#, Node.js, JavaScript, HTML, CSS, BootStrap, and Angular.JS. Does your team need additional help in any of the above? Contact Dave today.

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 🙂

  • 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.

  • 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()

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