Just an idea: Using a prefix with id attributes for direct JS access
Tracy Gilmore

Tracy Gilmore @tracygjg

About: After my first contact with a computer in the 1980's, I taught myself to program in BASIC and Z80 assembler. I went on to study Computer Science and have enjoyed a long career in Software Engineering.

Location:
Somerset, UK
Joined:
Jul 16, 2017

Just an idea: Using a prefix with id attributes for direct JS access

Publish Date: Jul 17
4 5

A little-known fact is that valid DOM element id attributes are exposed by the DOM into the JavaScript space as properties of the window (globalThis) object. This means an element such as:

<div id=”testDiv”>Hello, World!</div>
Enter fullscreen mode Exit fullscreen mode

Can be accessed as follows without the need to use document.querySelector(‘#testDiv’) or its older cousin document.getElementById(‘testDiv’).

console.log(testDiv.textContent); // “Hello, World!”
Enter fullscreen mode Exit fullscreen mode

However, as is, this pollutes the global namespace and MDN cautions against using the id attribute this way primarily because of the potential conflict with other entities in the global namespace such as window properties. MDN advises using the aforementioned document methods.

When hand-crafting CSS, a long-lost art, the general (and sound) advice is to avoid using the id of an element to apply styling as this could be too specific. Personally, I have not had too much of an issue with styling by id but usually only in hobby projects and prototypes. In production code I usually stick with the guidance and would recommend the guidance to fellow frontend developers.

But, what if we could force the CSS issue whilst considerably reducing the potential of global namespace collision? Whilst testDiv is a valid CSS selection by id #testDiv, adding a dollar symbol to the front makes it invalid (#$testDiv is not a valid CSS selector).

At the same time, it is highly unlikely that the window API will acquire properties with such a prefix, reducing collision potential.

There are JS libraries (of old) that use the $ symbol, the most well-known of course being JQuery, and whilst there is a wealth of code out there in the wide using such libraries, I suspect they are not used anywhere near as much in production code these days.

In conclusion, prefixing element id attributes with a dollar symbol would:

  1. Impede the use of the id in CSS styling, not that it is done very often these days.
  2. Enable JS to reference the DOM element directly without the need to look up the element first using a document method such as querySelector or getElementById.
<div id=”$testDiv”>Hello, World!</div>
Enter fullscreen mode Exit fullscreen mode
console.log($testDiv.textContent); // “Hello, World!”
Enter fullscreen mode Exit fullscreen mode

Is this a crazy idea? I would like to hear what others have to say in the comments below.

Comments 5 total

  • ArtyProg
    ArtyProgJul 17, 2025

    use data-id='xxx'

    • Tracy Gilmore
      Tracy GilmoreJul 18, 2025

      Thank you for your comment but I do not think your suggestion is applicable. We could use the data attribute to provide an identifier for a DOM element and use it to style it in CSS. It would be less Specific than an id attribute but still dedicated to styling the specific element, especially when the value of the attribute is included and assuming it is unique.

      As for selecting DOM elements in JS code, using the data attribute would still require using the querySelector method, in fact that would be the only way as there is no getElementByAttribute method.

      All that said, your comment has set me thinking about a couple of things (thank you).

      1, Referencing DOM elements directly is generally not useful when using a JS framework that employs a virtual DOM because the reference is likely to be lost with subsequent updates of the DOM.

      2, The fact that by prefixing the dollar symbol to an id attribute invalidates it as a CSS select also means we would be unable to use the querySelector method even if we wanted to. However, one of the benefits of using the prefix is we should not need either document method to select the element, it will already have been done.

      Going back to my first thought, I have prepared a GitHub gist to demonstrate the point.

      Thanks again for your comment, much appreciated.

  • Ali Navidi
    Ali NavidiAug 1, 2025

    I believe MDN only cautions against this when the property is accessed directly via the window object, such as window.idValue or window["idValue"]. However, using document.getElementById or document.querySelector does not present any issues.

    Therefore, my solution is to avoid using the window object directly, which eliminates the risk of breaking the code in the future regarding this issue. Using unique names may also work for now (and also in the future) but there is also very small chance that a new entity comes with that name.

    What do you think?

    • Tracy Gilmore
      Tracy GilmoreAug 2, 2025

      Ali, Thanks for your comment. As requested, here is what I think.

      Within the web browser the window object equates to globalThis, which is how the properties can be referenced within the global namespace and without direct reference to window.

      window === globalThis  // true
      
      window.document === document  // true
      
      window['document'] === document  // true
      
      window['localStorage'] === window.localStorage  // true
      
      Enter fullscreen mode Exit fullscreen mode

      Thus it would be unwise to give a DOM element an id of localStorage. After selecting an element in the DOM using the developer tools ($0) it is possible to edit the element as HTML and add an attribute of id and set to localStorage. After that, the following tests get interesting.

      $0  // <section id=​"localStorage">​</section>​
      
      $0.id  // 'localStorage'
      
      $0.id === window.localStorage  // false
      $0.id === window['localStorage']  // false
      
      localStorage === window.localStorage  // true - Not the DOM element $0.
      localStorage === window['localStorage']  // true
      
      $0 === localStorage  // false
      
      Enter fullscreen mode Exit fullscreen mode

      However, there are no window properties that start with a dollar symbol. So, as my post suggested, using a dollar prefix for ids serves a number of purposes:

      1. Virtually no change of namespace conflict with window properties.
      2. Styling the element using its id (#$elementId) is not possible because CSS selectors cannot start with a dollar.
      3. In addition, the prefix denotes variables as referencing a DOM element, which is useful.

      I am not sure your comment about using unique names is valid as there is nothing to assert uniqueness. However, it would be easy to have a JS function to check for duplications.

        function checkElementsForDuplicateIds(target = document.body) {
          const elementsWithIds = [...target.querySelectorAll(`[id]`)].map(el => el.id);
          const uniqueIds = [...new Set(elementsWithIds)];
          const duplicateIds = uniqueIds.filter(id => elementsWithIds.filter((elId) => elId === id).length > 1);
          if (duplicateIds.length) {
            console.error(
              `Error, there are elements with duplicate id attributes: ${duplicateIds.join(
                ', '
              )}.`
            );
          }
        }
      
      Enter fullscreen mode Exit fullscreen mode
Add comment