Quick Tip: Use HTML Comments to Indicate Pseudo-elements

Use HTML Comments to Indicate Pseudo-ElementsAt the recent W3Conf Nicolas Gallagher explained that although pseudo-elements have helped us add decorative content to our pages while keeping our HTML clean, this has led to some maintainability issues.

Developer tools can help to some degree, but oftentimes dynamically added content like pseudo-elements or extra elements added via JavaScript are initially harder to track down.

As Nicolas pointed out, the far-future improvement in this area is the Web Components spec, but I think this is something we can improve on right now.

Let’s say we have the following CSS, using pseudo-elements:

.exampleModule {
  float: left;
  border: solid 2px #ccc;
  position: relative;

.exampleModule:before {
  content: url(icon.png);
  float: left;

.exampleModule:after {
  content: url(corner.png);
  position: absolute;
  bottom: 0;
  right: 0;

The CSS is just illustrative, and really doesn’t matter for this example; it could be anything that uses one or more pseudo-elements. The main takeaway here is what you would see in the HTML:

<div class="exampleModule">
<!-- pseudo: icon.png -->
<!-- pseudo: corner.png -->

Now you don’t have to view the CSS or inspect the element with your dev tools; as soon as you look at the HTML, you know that the decorative content (in this case the two images) is added via pseudo-elements.

The same principle can be applied to content that is injected via JavaScript, and I suppose you could also include HTML comments in modules to list the different states that the module could be in, as represented by classes in the CSS. But that’s a little more complicated, and could probably be a topic for another post.

15 Responses

  1. Senff says:

    Not sure I understand. If you are sure that (in this case) icon.png and corner.png are being placed before and after the exampleModule (at least sure enough to add the HTML comments at those specific locations), why use pseudo-elements at all and not just add the HTML itself instead of the comments?

    • You’re right, and that’s why Nicolas seemed to imply in his talk that in many cases it could be better to just throw in some extra empty elements.

      But some people don’t like the idea of extra empty elements, so this is an option to consider. Also, when you push this to production, you have the option to strip out all the comments and make the markup smaller, thus getting the best of both worlds, because the extra markup would not be stripped out if they were real elements.

      But I agree with you, to me it seems silly to add the comment and not be willing to just add the element to begin with. But hey, some people are just finicky about what they put in their HTML, and are more comfortable using a pseudo-element for this, so I thought maybe it would be helpful if the pseudo-element was indicated via a comment.

  2. Simon says:

    Nice tip =)

  3. So ordered lists would look like:

        <!– pseudo: 1 –> <li>apple</li>
        <!– pseudo: 2 –> <li>orange</li>
        <!– pseudo: 3 –> <li>banana</li>

  4. Isn’t the idea of using pseudo elements to separate visual-only elements out into the CSS? This way when you change the image you also need to change the comment and won actually nothing in terms of maintenance… We have devtools that show the CSS applied to an element. I don’t quite see the need for this.

    • Well, then don’t use the image name in the HTML, just write something generic.

      Yes, I agree, in many cases the dev tools will solve this problem, but from my experience with dev tools, you can’t always immediately spot the pseudo-element, and sometimes it’s missed. You can’t “inspect” a pseudo-element directly, you have to inspect the element it’s applied to, then scroll through the styles pane to see what’s there.

      I don’t think any solution is perfect in a case like this. Either way you’re losing something. But if you work a lot in the HTML, using multiple class names, I don’t think this is a big addition to maintenance, especially if you can make it generic enough that you don’t have to touch it again.

      I suppose I’m assuming OOCSS in this scenario, where you’re actually spending a lot of time adding and modifying class names, so I don’t think this would add much extra. But hey, I see where you’re coming from. :)

  5. BerggreenDK says:

    In my opinion all the comments in HTML ought to be stripped before going live. An HTML file is the OUTPUT from a server-request. My primary goal is to make sure that its cross platform compatible as far as possible (>=MSIE8) and all modern browsers. Secondly its about speed and responsive design, so mobiles have to download the least amount of data pr. page request. Both for server traffic, but also for user-experience. Thats why I use CSS to optimize the way the graphic is reused.

    I dont see HTML as “art” as some people does. For me true HTML art is when a page validates, shows equally on any platform, is ultra fast and as slim as possible while using all the correct tags to ease the SEO and screenreaders.

    All the comment stuff is junk to me, its for people who think HTML should be written by hand. Thats SOOOO last millenium people. Yes, I handcode my templates when my templatescripts arent good enough or I add new parts of templates, handwritten.

    But seriously, I dont give a damn about readability for humans once the page has gone live. For my sake it could be zip encoded and it often is.

    • Lavabeams says:

      What editor gives you “I dont see HTML as “art” as some people does. For me true HTML art is when a page validates, shows equally on any platform, is ultra fast and as slim as possible while using all the correct tags to ease the SEO and screenreaders.” that isn’t editing the html by hand..

    • This tip was for development code, not production code. I was going to put a note in about that, but I wanted this to just be a quick tip, and nothing extensive. So… I agree. :)

  6. Robert V says:

    You can dynamicaly add comments for pseudo elements via Javascript:

    Array.prototype.forEach.call(document.querySelectorAll('*'), function(element) {
     	if (getComputedStyle(element, 'before').content) {
     		var comment = document.createComment(':before');
     		element.firstChild ? element.insertBefore(comment, element.firstChild) : element.appendChild(comment);
     	if (getComputedStyle(element, 'after').content) {

    I just test if the content property for the before and after elements is non-empty. If it is the empty String, then it is ” which is not empty, so it also works, if you have content: ”; in your CSS.

    Or as bookmarklet:

    javascript:Array.prototype.forEach.call(document.querySelectorAll('*'), function(element) {if (getComputedStyle(element, 'before').content) {var comment = document.createComment(':before');element.firstChild ? element.insertBefore(comment, element.firstChild) : element.appendChild(comment);}if (getComputedStyle(element, 'after').content) {element.appendChild(document.createComment(':after'));}});

    Of course, I would prefer, if devtools would show them in the DOM and you could inspect them individually. Currently Chrome shows the before and after styles for the main-element (but also allows editing of the styles for the pseudo elements)

  7. Sam Jarvis says:

    I don’t really like this. Extra source for something you should be able to handle without the helper. Write CSS that is readable/structured well enough to make pseudo-elements easier to recognise.

    Plus, pseudo-elements are already a mild deviation from the concept of content/presentation separation. Adding extra source to indicate them is simply code bloat.

    Sure, this is acceptable if you’re stripping out comments before serving, but that’s not implied in the article.

    • Minifying JS and CSS is much more common, but I think for large websites even the HTML should be minified and comments should be stripped out. But yeah, I guess I should have mentioned that as it was intended to be an assumed fact, even though I don’t think many people do it.

  8. IsaacDiMe says:

    It’s interesting.
    Maybe i would comment just or
    But anyway, i0m not so fan of having unneeded markup,

  9. jack says:

    chrome seems to be doing something similar in its developer tools now

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).