Skip to main content

HTML Attributes vs DOM Properties

2 min read

Older Article

This article was published 8 years ago. Some information may be outdated or no longer applicable.

Developers (especially newer ones) regularly mix up HTML attributes and DOM properties. They sound similar, they often share the same names, and they overlap in confusing ways. Let’s sort it out.

Here’s the mental model that sticks: you define HTML elements and set attributes on them. The browser parses that HTML and creates DOM nodes. A DOM node is an object. Objects have properties.

HTML is a markup language, like XML. Markup languages operate with attributes.

DOM stands for Document Object Model. It’s an object, so it works with properties.

The DOM is language-independent, by the way. Most people use JavaScript, but you could access DOM properties through Python too.

Let’s test this. Create an HTML element and list 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

When the browser creates a DOM node from an HTML element, many DOM properties map to HTML attributes with the same name. But it’s not a 1:1 relationship. Not always.

id is both an attribute and a property. So is type. But value behaves differently. Watch what happens:

// 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);

The 5-second timeout gives you time to change the input box’s value before the comparison runs.

Calling getAttribute('value') doesn’t return the current value. It returns the initial value that was used to set up the <input> element. That’s one of the cases where the HTML attribute and the DOM property point to different things.

Make sure you actually type something new into the input box during those 5 seconds, or you won’t see the difference.