HTML Attributes vs DOM Properties

When working with various JavaScript frameworks, or only just by working in the field of web development, newcomers and novice developers often confuse attributes and properties concerning HTML pages.

In this article, we'll clarify the difference between these two.

We will start with a definition that, if sticks, will help to remember the differences at all times.

We can define HTML elements in a website, and we can set attributes for these elements. Once the browser parses this HTML code, it will create the appropriate DOM node. This DOM node is, in fact, an object and because it's an object it has properties.

Don't forget that HTML is a markup language, just like XML. Since both of them are markup languages, they operate using attributes.

Equally, remember that DOM is short for Document Object Model - and since it's an object, it works with properties.

Note that the DOM is independent of any language, but most of the time it is used with JavaScript; however, DOM properties could also be accessed via Python for example.

We can easily check this by creating an HTML element and call the .attribute property of it to list all its attributes:

<input type="text" id="inputBox" value="Hello!">
const inputBox = document.getElementById('inputBox');
const attrs = inputBox.attributes;
for(var i = attrs.length - 1; i >= 0; i--) {
  console.log(`${attrs[i].name} ==>  ${attrs[i].value}`);
}
// id ==>  inputBox
// value ==>  Hello!
// type ==>  text

Interestingly enough, when the DOM node is created based on the HTML element, many of the DOM properties map to HTML attributes that have the same name, however, we can't state that there's a 1:1 relationship between them.

Based on the previous statement we can assume that id is both an attribute and a property, so is type. However, when we examine value further we'll see that it doesn't always return the value that we'd expect:

// attributes vs properties
const inputBox = document.getElementById('inputBox');

console.log(
  inputBox.id === inputBox.getAttribute('id') // true
);

console.log(
  inputBox.type === inputBox.getAttribute('type') // true
);

setTimeout(() => {
  console.log(
    inputBox.value === inputBox.getAttribute('value') // false if value changed
  );
  console.log(`inputBox.value is ${inputBox.value} and inputBox.getAttribute('value') is ${inputBox.getAttribute('value')}`);
}, 5000);

Note that the 5 second timeout was added so that we get a chance to update the value of the input box.

By accessing the value attribute via getAttribute() doesn't return the current value but instead returns the value that was used to initiate the <input> element. This is one of the few scenarios when the HTML attribute doesn't return the same value as the DOM property.

In order to see this behaviour please make sure to change the value of the input box in that 5 second period provided by the setTimeout function.