Question

jQuery .prop() vs .attr(): Understanding Properties and Attributes

javascriptjquerydomattrprop

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 checked attribute says the checkbox starts checked.
  • The checked property 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, and disabled should usually use .prop().
  • Original HTML configuration like id, href, or literal data-* 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.

Take Quiz

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 the style attribute as text.
  • .prop('style') returns the DOM style object.

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:

  • id
  • className
  • innerHTML
  • style

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.

Take Quiz

Real Codebase Usage

In real projects, developers usually follow a few practical rules.

1. Use .prop() for boolean UI state

Common examples:

  • checked
  • selected
  • disabled
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:

  • id
  • href
  • src
  • alt
  • title
  • data-* 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 a CSSStyleDeclaration object, 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 attributeYesNo
Reads DOM propertyNoYes
Best for original markup valuesYesNo
Best for live UI stateNoYes
Returns string-like attribute valueUsuallyNot necessarily
Can return objectsRarelyYes

Common examples

CaseUseWhy
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()

TaskBetter 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+

VersionBehavior
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.

Take Quiz

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:

  • checked
  • selected
  • disabled
  • readonly

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 reading style directly.

Upgrade advice for jQuery 1.6+

Review old .attr() calls that deal with live state:

  • checked
  • selected
  • disabled
  • value

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.

Take Quiz

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 style attribute 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.
Take Quiz

Keep learning

Related questions

View more