DOM elements possess both HTML attributes (defined in raw HTML markup) and JavaScript properties (DOM object properties). Understanding how attributes and DOM properties synchronize is vital for form controls and dynamic styling.
flowchart LR
HTMLMarkup["HTML: <input id='user-in' value='Initial' class='form-ctrl'>"]
HTMLMarkup --> Attrs["Attributes (getAttribute / setAttribute)"]
HTMLMarkup --> Props["DOM Object Properties (element.value, element.className)"]
Attrs --> A1["Reflects raw HTML string values"]
Props --> P1["Reflects live dynamic JavaScript state"]
| Operation | Attribute API Syntax | Direct Property Access Syntax |
|---|---|---|
| Read Value | el.getAttribute("class") |
el.className or el.id |
| Write Value | el.setAttribute("disabled", "true") |
el.disabled = true (Boolean!) |
| Remove | el.removeAttribute("disabled") |
el.disabled = false |
| Has Check | el.hasAttribute("data-role") |
"role" in el.dataset |
| Data Attributes | el.getAttribute("data-id") |
el.dataset.id (dataset API) |
// Demonstrating Attribute API vs DOM Property manipulation
document.addEventListener("DOMContentLoaded", () => {
const inputEl = document.createElement("input");
inputEl.setAttribute("type", "text");
inputEl.setAttribute("id", "username-field");
inputEl.setAttribute("data-user-id", "99");
inputEl.value = "Default Value";
document.body.appendChild(inputEl);
// 1. Reading HTML Attributes vs DOM Properties
console.log(`getAttribute('type'): ${inputEl.getAttribute("type")}`);
console.log(`DOM Property id: ${inputEl.id}`);
// 2. Custom Dataset API (data-* attributes)
console.log(`Dataset user ID: ${inputEl.dataset.userId}`); // Accesses data-user-id
// 3. Boolean Attribute Synchronization Pitfall
inputEl.disabled = true; // Boolean DOM property
console.log(`Has 'disabled' attribute? ${inputEl.hasAttribute("disabled")}`); // true
// 4. Class Property vs Attribute
inputEl.className = "input-field active"; // Use className, NOT class!
console.log(`classList array:`, Array.from(inputEl.classList));
});
className or classList for Classes: The HTML class attribute is accessed via element.className or element.classList because class is a reserved keyword in JavaScript.dataset for Custom HTML Data Attributes: HTML5 data-* attributes (data-user-role="admin") can be accessed cleanly via camelCase properties on element.dataset.userRole.disabled, checked, or readonly, assign booleans directly (el.disabled = true) rather than string attributes.How do you access the value of an attribute <button data-action-type="submit"> using the dataset property?
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.