Question
jQuery .prop() vs .attr(): Understanding Properties and Attributes
Question
In jQuery 1.6, the new .prop() method was introduced. I want to understand when I should use .prop() instead of .attr().
For example:
$(selector).click(function () {
// Native DOM API
this.getAttribute('style');
// jQuery alternatives
$(this).prop('style');
$(this).attr('style');
});
In this case, do .prop('style') and .attr('style') return the same thing?
Also, if .prop() is now the correct method in some situations, will older .attr() code break after upgrading to jQuery 1.6?
Here is a fuller example:
var selector = '#id';
$(selector).click(function () {
var getAtt = this.getAttribute('style');
var thisProp = $(this).prop('style');
var thisAttr = $(this).attr('style');
console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="id" style="color: red; background: orange;">test</div>
When this runs, getAttribute('style') returns a string, .attr('style') returns a string, but .prop('style') returns a CSSStyleDeclaration object. Why does that happen, and how should this affect the way I write jQuery code going forward?
Short Answer
By the end of this page, you will understand the difference between HTML attributes and DOM properties in jQuery, why .attr() and .prop() can return different values, and when each method should be used. You will also see why style, checked, selected, and value often behave differently and how to avoid bugs when upgrading or maintaining older jQuery code.
Concept
Attributes and properties are related, but they are not the same thing.
- Attributes are the values written in the HTML markup.
- Properties are the live values on the DOM element object in JavaScript.
For example, in this HTML:
<input type="checkbox" checked>
- The
checkedattribute says the checkbox starts checked. - The
checkedproperty tells you whether the checkbox is currently checked right now.
That difference matters because the browser turns HTML into DOM objects. Once the page is loaded, JavaScript works mostly with properties, not raw attribute text.
In jQuery:
.attr()is for reading or writing HTML attributes..prop()is for reading or writing DOM properties.
This is why your style example behaves differently:
this.getAttribute('style'); // string from HTML attribute
$(this).attr('style'); // string from attribute
$(this).prop('style'); // style object on the DOM node
The style property on a DOM element is not stored as plain text in JavaScript. It is exposed as an object, usually a CSSStyleDeclaration, which gives programmatic access to CSS properties.
This distinction became clearer in jQuery 1.6 because jQuery separated attribute handling from property handling more explicitly. Before that, .attr() sometimes mixed both ideas, which caused confusion.
Why this matters in real programming:
- Boolean states like
checked,selected, anddisabledshould usually use.prop(). - Original HTML configuration like
id,href, or literaldata-*attributes often uses.attr(). - If you use the wrong one, your code may read the initial markup instead of the current state, or vice versa.
Mental Model
Think of an HTML element like a house listing and the actual house.
- The attribute is the information written in the listing: "This house has blue walls."
- The property is the real current state of the house when you visit it: maybe the walls are now green.
For style:
.attr('style')is like reading the original text written on the listing..prop('style')is like walking into the house and inspecting the real paint controls panel.
Another example with a checkbox:
.attr('checked')asks, "Did the HTML say this started checked?".prop('checked')asks, "Is it checked right now?"
That is the key idea: attributes describe markup, properties describe live state.
Syntax and Examples
Core syntax
$(element).attr(name)
$(element).attr(name, value)
$(element).prop(name)
$(element).prop(name, value)
Example 1: style
<div id="box" style="color: red; background: orange;">Hello</div>
var el = $('#box');
console.log(el.attr('style'));
// "color: red; background: orange;"
console.log(el.prop('style'));
// CSSStyleDeclaration object
Explanation
.attr('style')returns the raw value of thestyleattribute as text..prop('style')returns the DOMstyleobject.
That means this works:
console.log(el.prop('style').color);
// may output: "red"
Example 2: checkbox state
<input id="agree" type="checkbox" checked>
var box = $('#agree');
console.log(box.attr('checked'));
// "checked" in older jQuery behavior, or the attribute value if present
console.log(box.prop('checked'));
// true
If the user unchecks the checkbox:
console.log(box.attr('checked'));
// may still reflect the original HTML attribute
console.log(box.prop('checked'));
// false
Explanation
For current UI state, use .prop('checked').
Example 3: changing values
$('#agree').prop('checked', false);
$('#box').attr('title', 'A greeting box');
Use:
.prop()for live JavaScript properties.attr()for literal HTML attributes
Step by Step Execution
Consider this example:
<div id="id" style="color: red; background: orange;">test</div>
$('#id').click(function () {
var getAtt = this.getAttribute('style');
var thisProp = $(this).prop('style');
var thisAttr = $(this).attr('style');
console.log(getAtt);
console.log(thisProp);
console.log(thisAttr);
});
What happens step by step
1. The browser parses the HTML
It sees:
style="color: red; background: orange;"
That text is stored as an HTML attribute.
2. The browser creates a DOM element object
The <div> becomes a JavaScript object with many properties, including:
idclassNameinnerHTMLstyle
The style property is not a string. It is an object that represents inline CSS.
3. this.getAttribute('style') runs
This reads the raw attribute value from the markup.
Result:
"color: red; background: orange;"
4. $(this).attr('style') runs
jQuery reads the HTML attribute value.
Result:
"color: red; background: orange;"
5. $(this).prop('style') runs
jQuery reads the DOM property named style.
Result:
CSSStyleDeclaration { ... }
6. Why the results differ
Because the browser exposes style in two forms:
- as a string attribute in HTML
- as a style object property in the DOM
Practical effect
If you want the exact text from the HTML attribute, use:
$(this).attr('style')
If you want to inspect or change style programmatically, use the property or jQuery CSS helpers:
$(this).prop('style').backgroundColor
$(this).css('background-color')
Real World Use Cases
When .attr() is useful
Reading markup configuration
<a id="docs" href="/guide">Guide</a>
console.log($('#docs').attr('href'));
Useful when you need values defined in HTML.
Working with custom attributes
<div id="card" data-role="admin"></div>
console.log($('#card').attr('data-role'));
When .prop() is useful
Reading form control state
if ($('#terms').prop('checked')) {
submitForm();
}
Enabling and disabling controls
$('#submitBtn').prop('disabled', true);
Checking selected options
console.log($('#country option:selected').prop('selected'));
Special case: CSS
For CSS, developers usually use .css() instead of .attr('style') or .prop('style').
$('#box').css('color');
$('#box').css('background-color', 'blue');
This is cleaner and works for both inline and computed styles in common jQuery usage.
Real Codebase Usage
In real projects, developers usually follow a few practical rules.
1. Use .prop() for boolean UI state
Common examples:
checkedselecteddisabled
if ($('#rememberMe').prop('checked')) {
savePreference();
}
This avoids bugs where code reads the original HTML instead of the current state.
2. Use .attr() for static element metadata
Examples:
idhrefsrcalttitledata-*when not using.data()
var imageUrl = $('#avatar').attr('src');
3. Prefer dedicated helpers when available
Instead of this:
$('#panel').attr('style');
$('#panel').prop('style');
developers usually write:
$('#panel').css('display');
$('#panel').css('color', 'green');
4. Use guard clauses with properties in event handlers
$('#send').on('click', function () {
if ($(this).prop('disabled')) {
return;
}
sendMessage();
});
5. Use validation patterns with current state
function canSubmit() {
return $('#email').val().trim() !== '' && $('#agree').prop('checked');
}
The current state of user input usually lives in properties, not attributes.
6. Legacy jQuery code may need targeted updates
Most old .attr() calls do not automatically "break," but some become semantically wrong in jQuery 1.6+ if they were relying on old mixed behavior. The risky cases are mainly boolean and stateful properties.
Common Mistakes
Mistake 1: Using .attr() for checkbox state
Broken idea:
if ($('#newsletter').attr('checked')) {
console.log('Checked');
}
Why it is a problem:
- It may reflect the original HTML attribute, not the current user-selected state.
Better:
if ($('#newsletter').prop('checked')) {
console.log('Checked');
}
Mistake 2: Expecting .prop('style') to return a string
Broken expectation:
var styleText = $('#box').prop('style');
console.log(styleText.toUpperCase());
Why it fails:
.prop('style')returns aCSSStyleDeclarationobject, not a string.
Better:
var styleText = $('#box').attr('style');
console.log(styleText.toUpperCase());
Or use .css() when reading a specific style:
console.log($('#box').css('color'));
Mistake 3: Using .attr() to disable a button dynamically
Potentially confusing:
$('#save').attr('disabled', 'disabled');
Better:
$('#save').prop('disabled', true);
Mistake 4: Forgetting that attributes are text-based
console.log($('#item').attr('tabIndex'));
console.log($('#item').prop('tabIndex'));
These may not behave the same because the property may be normalized by the browser.
Mistake 5: Using .attr('value') for current form values
Broken assumption:
console.log($('#name').attr('value'));
This may return the initial value from the HTML, not the current typed input.
Better:
console.log($('#name').val());
Or when specifically needed:
console.log($('#name').prop('value'));
Comparisons
.attr() vs .prop()
| Feature | .attr() | .prop() |
|---|---|---|
| Reads HTML attribute | Yes | No |
| Reads DOM property | No | Yes |
| Best for original markup values | Yes | No |
| Best for live UI state | No | Yes |
| Returns string-like attribute value | Usually | Not necessarily |
| Can return objects | Rarely | Yes |
Common examples
| Case | Use | Why |
|---|---|---|
style text | .attr('style') | Reads inline style attribute as text |
| style object | .prop('style') | Gets CSSStyleDeclaration |
| checkbox checked state | .prop('checked') | Reads current state |
| button disabled state | .prop('disabled') | Reads current state |
| image source attribute | .attr('src') | Reads markup attribute |
| input current value | .val() | Best jQuery helper for form values |
.prop() vs .css()
| Task | Better choice |
|---|---|
| Read a CSS property value | .css() |
| Set a CSS property value | .css() |
| Access the raw style object | .prop('style') |
Read the literal style attribute text | .attr('style') |
Old jQuery behavior vs jQuery 1.6+
| Version | Behavior |
|---|---|
| Before 1.6 | .attr() sometimes handled properties too |
| 1.6 and later | .attr() and .prop() are more clearly separated |
That means old code may still run, but some state-related .attr() calls should be reviewed and updated.
Cheat Sheet
Quick rules
- Use
.attr()for HTML attributes. - Use
.prop()for DOM properties. - Use
.val()for form values. - Use
.css()for CSS values.
Good defaults
$(el).attr('href')
$(el).attr('data-id')
$(el).prop('checked')
$(el).prop('disabled')
$(el).prop('selected')
$(el).val()
$(el).css('color')
style specifically
$(el).attr('style') // "color: red; background: orange;"
$(el).prop('style') // CSSStyleDeclaration object
Boolean properties
Prefer .prop() for:
checkedselecteddisabledreadonly
Common edge cases
.attr('checked')may describe the original markup, not current state..prop('style')returns an object, not a string..attr('value')may not match what the user has typed..css()is usually better than readingstyledirectly.
Upgrade advice for jQuery 1.6+
Review old .attr() calls that deal with live state:
checkedselecteddisabledvalue
Those are the most likely places where .prop() or .val() is the better choice.
FAQ
What is the difference between jQuery .attr() and .prop()?
.attr() works with HTML attributes from markup. .prop() works with live DOM properties on the element object.
Should I use .prop('checked') or .attr('checked')?
Use .prop('checked') for the current checkbox state.
Why does .prop('style') return an object instead of a string?
Because the DOM style property is a CSSStyleDeclaration object, not raw attribute text.
Is .attr('style') the same as getAttribute('style')?
For this use case, yes. Both read the style attribute as text.
Will old .attr() code break in jQuery 1.6?
Not all of it. But code that relied on .attr() for properties like checked, selected, or disabled should be reviewed.
What should I use instead of .prop('style') for CSS values?
Usually .css() is the best choice for reading or setting CSS.
Should I use .prop('value') or .val() for form inputs?
In jQuery code, .val() is usually the clearest and most common choice.
Can attributes and properties ever have the same value?
Yes. Many do at first. But after user interaction or JavaScript changes, the property may change while the attribute stays the same.
Mini Project
Description
Build a small settings panel with a checkbox, a text input, and a colored preview box. The project demonstrates when to use .attr(), .prop(), .val(), and .css() in realistic jQuery code.
Goal
Create a page that reads static attributes, reacts to live form state, and updates styles correctly using the right jQuery methods.
Requirements
- Add a checkbox that enables or disables a text input.
- Add a text input whose current value is shown in a preview area.
- Add a preview box with an initial inline style and display both its
styleattribute and a live CSS property. - Use
.prop()for enabled/disabled and checked state. - Use
.val()for the input value and.css()for reading or updating CSS.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.