Attributes and Properties · Astro Tech Blog

Attributes vs Properties

When the browser parses HTML, it creates DOM objects. Each HTML attribute becomes a DOM property. But there’s a subtle difference:

  • Attributes — written in HTML, always strings
  • Properties — DOM object properties, can be any type (boolean, object, number)

How They Relate

Most standard attributes automatically become properties:

<input id="email" type="text" value="hello">
input.id       // "email" (property)
input.type     // "text" (property)
input.value    // "hello" (property)
Demo: Attributes become Properties
HTML
<input id='my-input' type='email' value='test@example.com' disabled>
<pre id='ap-output' style='background:#f1f5f9;padding:8px;border-radius:4px;'></pre>
JavaScript
const inp = document.getElementById('my-input');
const out = document.getElementById('ap-output');

out.textContent =
'property .id: ' + inp.id + '\\n' +
'property .type: ' + inp.type + '\\n' +
'property .value: ' + inp.value + '\\n' +
'property .disabled: ' + inp.disabled + ' (boolean!)' + '\\n' +
'---' + '\\n' +
'attribute .getAttribute('disabled'): ' + inp.getAttribute('disabled') + ' (string or null)';
Live Output Window

Working with Attributes

Use these methods to work with attributes directly:

element.hasAttribute(name)     // check if attribute exists
element.getAttribute(name)     // get attribute value (always string or null)
element.setAttribute(name, value)  // set attribute
element.removeAttribute(name)  // remove attribute
element.attributes             // get all attributes (NamedNodeMap)
Demo: Attribute Methods
HTML
<div id='card' class='box' data-id='123' style='padding:12px;border:1px solid #cbd5e1;border-radius:6px;'>
Hover to see my attributes
</div>
<pre id='attr-output' style='background:#f1f5f9;padding:8px;border-radius:4px;margin-top:8px;'></pre>
JavaScript
const card = document.getElementById('card');
const out = document.getElementById('attr-output');

out.textContent =
'hasAttribute('class'): ' + card.hasAttribute('class') + '\\n' +
'getAttribute('data-id'): ' + card.getAttribute('data-id') + '\\n' +
'getAttribute('style'): ' + card.getAttribute('style') + '\\n' +
'---' + '\\n';

// Iterate all attributes
let attrList = 'All attributes:\\n';
for (let attr of card.attributes) {
attrList += '  ' + attr.name + '=' + attr.value + '\n';
}
out.textContent += attrList;
Live Output Window

When Properties and Attributes Diverge

Some attributes don’t map 1:1 to properties:

AttributePropertyNotes
classclassNameclass is reserved in JS
forhtmlForfor is a loop keyword
stylestyle (object)Attribute is a string, property is a CSSStyleDeclaration
hrefhref (full URL)Property returns resolved URL, attribute returns literal
valuevalue (current)Property = current input value; attribute = default value
Demo: Attribute vs Property Differences
HTML
<a id='mylink' href='/page'>Click me</a>
<input id='myfield' type='text' value='default'>
<pre id='diff-output' style='background:#f1f5f9;padding:8px;border-radius:4px;'></pre>
JavaScript
const link = document.getElementById('mylink');
const field = document.getElementById('myfield');
const out = document.getElementById('diff-output');

out.textContent =
'Link:' + '\\n' +
'  getAttribute('href'): ' + link.getAttribute('href') + '\\n' +
'  .href property: ' + link.href + '\\n' +
'---' + '\\n' +
'Input before typing:' + '\\n' +
'  getAttribute('value'): ' + field.getAttribute('value') + '\\n' +
'  .value property: ' + field.value;
Live Output Window

Data Attributes

HTML5 introduced data-* attributes. Access them via the dataset property:

<div data-user-id="42" data-role="admin">
div.dataset.userId   // "42" (camelCase!)
div.dataset.role     // "admin"
Demo: Data Attributes
HTML
<div id='user-profile' data-user-id='42' data-user-role='admin' data-last-login='2026-06-01'>
User Profile Card
</div>
<pre id='data-output' style='background:#f1f5f9;padding:8px;border-radius:4px;'></pre>
JavaScript
const profile = document.getElementById('user-profile');
const out = document.getElementById('data-output');

out.innerHTML =
'dataset.userId = ' + profile.dataset.userId + '<br>' +
'dataset.userRole = ' + profile.dataset.userRole + '<br>' +
'dataset.lastLogin = ' + profile.dataset.lastLogin + '<br>' +
'<br>Setting dataset.userRole = 'editor'...';

profile.dataset.userRole = 'editor';
Live Output Window

Key Takeaways

  • Attributes are HTML strings; properties are DOM object values
  • Use getAttribute/setAttribute for the HTML source value
  • Use the DOM property for the live/current value
  • classclassName, forhtmlFor in JS
  • data-* attributes are accessed via dataset (camelCase)
  • Properties can be any type (boolean, object); attributes are always strings