2

Use case: I'd like to dynamically add classes to the <html> element in my document so that some SASS mixins that are currently using .class-name & will work if applied within a selector which includes a body class -- otherwise I get .class-name .body-class .rest-of-selector which doesn't work unless class-name is applied at a higher level than the <body>

Previously I've used document.body.classList.add which seems neat, simple and robust.

In transitioning to add classes to the <html> element instead, I wondered what the equivalent code would be:

  • document.html -- nope, no such thing it seems
  • document.rootElement -- should work I think, but was null when I tested so not robust?!
  • document.getElementsByTagName('html')[0] -- pretty clunky, but surely effective/robust?
  • document.body.parentElement -- looks cleaner, should be reliable? Is this as direct as it gets?
  • document.querySelector('html') as suggested by Louys below -- feels like we shouldn't need to query for it though?
  • any other options I haven't thought of?
7
  • 1
    document.querySelector("html") ;) Commented Apr 22, 2021 at 1:01
  • or also document.childNodes[1] because it is supposed to be the doctype and the html node Commented Apr 22, 2021 at 1:03
  • Thanks @LouysPatriceBessette have added to the list in the question Commented Apr 22, 2021 at 1:08
  • 2
    QuerySelector is simple and robust. Commented Apr 22, 2021 at 1:10
  • 4
    @DrMeers, I think you should prefer this following answer: document.documentElement that give you directly the html node Commented Apr 22, 2021 at 1:16

1 Answer 1

4

As @thibsc and @LouysPatriceBessette said above, you have two excellent options in document.querySelector("html") and document.documentElement.

document.querySelector("html")

document.querySelector() is an important function to know in general, in addition to document.querySelectorAll(). It returns the first matching element in document order, which for `document.querySelectorAll("html") will be the root html object.

CanIUse compatibility chart

document.documentElement

The documentElement property of the document object (which can be thought of as an alias to the HTMLDocument object) always refers to the root element, which in HTML is generally the <html> tag.

CanIUse compatibility chart

Speed

In my super-scientific speed test, document.documentElement seems faster today:

let date = Date.now();
for (var i=0; i<123456; i++) {
    a = document.querySelector("html");
    a.classList.toggle("hello");
    a = null;
}
console.log(Date.now() - date);
//result: 254

let a;
let date = Date.now();
for (var i=0; i<123456; i++) {
    a = document.documentElement;
    a.classList.toggle("hello");
    a = null;
}
console.log(Date.now() - date);
//result: 225

In the end, your question is about what "feels" good - but these are the best ways to access the <html> element. You were correct about your other alternatives:

  • document.html -- doesn't exist
  • document.rootElement -- deprecated
  • document.getElementsByTagName('html')[0] -- Clunky but robust
  • document.body.parentElement -- Also robust

But perhaps what you want is this:

const $ = document.querySelector.bind(document);
$("html").classList.add("myClass");
Sign up to request clarification or add additional context in comments.

5 Comments

document.documentElement is what I was after -- no need to query, pick from a list, etc -- simple and robust
I'm actually curious why you want to avoid querying - is it just personal preference? I query a lot so that's actually my preferred solution, but maybe it shouldn't be
Oooh, you might also be interested to know all the trivia in developer.mozilla.org/en-US/docs/Web/API/Document - you can access all links via the document.links property, for instance!
a query implies a DOM search, which is overkill for this, and less robust than a canonical access point
Not only is rootElement deprecated, it never applied to the HTML DOM in the first place - it's specific to the SVG DOM. And personally, I'd prefer documentElement over querySelector('html') for the same reason I prefer document.body over document.querySelector('body').

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.