The .attr() method gets or sets HTML attributes on matched elements. This tutorial covers all four API overloads (getter, name/value setter, plain object, callback setter), the critical difference between attributes and properties, comparisons with .prop(), .removeAttr(), and .data(), and five official jQuery demos.
01
Getter
First element only
02
Setter
Name + value
03
Object
Multiple attrs
04
Callback
Per element
05
vs .prop()
Attr vs state
06
Since 1.0
Core API
Fundamentals
Introduction
HTML elements carry attributes in markup — href on links, src and alt on images, title for tooltips, and id for unique identifiers. When JavaScript needs to read or change those values at runtime, jQuery provides .attr().
Available since jQuery 1.0, .attr() offers two main benefits over raw DOM calls: convenience (chain it on a jQuery object) and cross-browser consistency (jQuery normalizes inconsistent attribute reporting across browsers). Attribute values are almost always strings — with a few exceptions like value and tabindex.
Since jQuery 1.6, use .prop() for live DOM properties such as checked, selected, and disabled on form elements — not .attr(). The attribute and property of boolean elements behave differently; Example 2 demonstrates this.
Concept
Understanding the .attr() Method
Given a jQuery object representing one or more DOM elements, .attr() either reads an attribute from the first element (getter) or writes attributes to every matched element (setter). Getters return a string or undefined if the attribute is not set. Setters return the original jQuery object for chaining.
Think of attributes as the initial HTML declaration — what you wrote in markup. Properties are the live DOM state that can change as the user interacts. For a checkbox, attr('checked') reflects the initial HTML state and does not update when the user clicks; prop('checked') tracks the current checked state.
💡
Beginner Tip
$("em").attr("title") reads the title attribute from the first <em> only. To set attributes on every match, use the setter forms — .attr("id", value), a plain object, or a callback.
Foundation
📝 Syntax
jQuery .attr() accepts four argument forms:
1. Getter — read one attribute (since 1.0)
jQuery
.attr( attributeName )
attributeName — the name of the attribute to get.
Returns a string or undefined for the first matched element only.
2. Setter — name and value (since 1.0)
jQuery
.attr( attributeName, value )
attributeName — the attribute to set on every matched element.
value — string, number, boolean, or null. Passing null removes the attribute (same as .removeAttr()).
3. Plain object — set multiple attributes (since 1.0)
jQuery
.attr( attributes )
attributes — a plain object of attribute-value pairs applied to each matched element.
4. Callback setter — computed value per element (since 1.1)
jQuery
.attr( attributeName, function( index, attr ) {
// return value to set
} )
index — zero-based position of the element in the matched set.
attr — the element’s current attribute value (or undefined).
this — the current DOM element. Return a string or number to set; return nothing to leave unchanged.
Return value
Getter — String or undefined (first element only).
Setter — the original jQuery object (for chaining).
Attributes vs. properties
Use .attr() for HTML attributes in markup. Use .prop() for dynamic form state:
jQuery
// Attributes — initial HTML values (strings)
$("a").attr("href", "/about");
// Properties — live DOM state on form controls
if ( $("input").prop("checked") ) { /* user checked it */ }
if ( $("option").prop("selected") ) { /* currently selected */ }
$("input").prop("disabled", true);
WARNING: always quote 'class'
class is a reserved word in JavaScript. Always use quotes:
jQuery
// Correct
$("div").attr("class", "highlight");
// Syntax error — class is reserved
// $("div").attr(class, "highlight");
Official jQuery API example
jQuery
var title = $( "em" ).attr( "title" );
$( "div" ).text( title );
Unchecked: .attr('checked') → undefined, .prop('checked') → false
Checked: .attr('checked') → undefined, .prop('checked') → true
.attr() reflects initial HTML — .prop() tracks live state
How It Works
The checked attribute corresponds to defaultChecked, not the live checked property. After jQuery 1.6, always use .prop("checked") or .is(":checked") to test checkbox state.
Example 3 — Official Demo: Set src, title, and alt With an Object
Pass a plain object to set multiple attributes on an image in one call.
Image loads with src, title, and alt set
Displayed text: jQuery Logo (from .attr("alt"))
How It Works
Each key-value pair in the object adds or updates an attribute on every matched element. Quotes around attribute names in the object are optional in JavaScript.
Example 4 — Official Demo: Set id From a Function
Assign unique id values based on each element’s index.
div 0 → id="div-id0"
div 1 → id="div-id1"
div 2 → id="div-id2"
How It Works
jQuery calls the callback once per matched element. The returned string becomes the attribute value. Returning undefined leaves the current value unchanged.
📈 Practical Patterns
Derive attribute values from other element properties.
Example 5 — Official Demo: Set src From title With a Function
Copy a URL stored in the title attribute into src so the image loads.
title attribute holds the image path
.attr('src', fn) copies title → src and image loads
How It Works
Inside the callback, this is the raw DOM element. Reading this.title accesses the live property (same as the title attribute for most elements). jQuery sets src on each matched image.
Unique IDs for testing — $(".row").attr("id", function(i){ return "row-"+i; }).
Remove stale attributes — $("div").attr("title", null) to clear tooltips.
🧠 How .attr() Reads and Writes Attributes
1
Match elements
jQuery object holds one or more DOM nodes.
Input
2
Getter or setter?
One argument reads; two arguments or an object writes.
Mode
3
Cross-browser read/write
jQuery normalizes attribute access across browsers.
DOM
4
🏷
String or jQuery object
Getter returns string/undefined (first only); setter returns same collection for chaining.
Important
📝 Notes
Available since jQuery 1.0 — callback setter since 1.1.
Getter returns value for the first element only; setters apply to all matches.
Since jQuery 1.6, unset attributes return undefined (not empty string).
Use .prop() for checked, selected, and disabled — not .attr().
Pass null to remove an attribute; since 4.0, false also removes non-ARIA attributes.
Always quote 'class' — it is a JavaScript reserved word.
Changing type on inputs created via document.createElement() throws in IE8 and older.
Compatibility
Browser Support
.attr() has been part of jQuery since 1.0+. The callback setter arrived in 1.1+. jQuery normalizes cross-browser attribute inconsistencies — the main reason to prefer it over raw getAttribute / setAttribute in legacy projects.
✓ jQuery 1.0+
jQuery .attr()
Supported in jQuery 1.x, 2.x, 3.x, and 4.x across all modern browsers and IE with supported jQuery builds. Native equivalent: element.getAttribute() / setAttribute() — jQuery adds collection semantics, object/callback setters, and cross-browser normalization.
100%With jQuery loaded
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
.attr()Universal
Bottom line: Safe in any jQuery project. Use .attr() for HTML attributes; .prop() for live form state.
Wrap Up
Conclusion
The jQuery .attr() method gets or sets HTML attributes on matched elements. It is the standard way to read markup values like href, src, and title, and to write them back — including bulk updates via a plain object or per-element computation via a callback.
Remember the official demo: $("em").attr("title") reads the first element’s attribute as a string. For checkbox state, reach for .prop("checked") instead. Chain setters freely — .attr({...}).addClass("loaded") — and always quote 'class' when setting the class attribute directly.
Use .attr() for standard HTML attributes — href, src, alt, title
Use .prop() for checked, selected, and disabled
Pass a plain object when setting multiple attributes at once
Use the callback form when each element needs a different value
Always quote 'class' — or prefer .addClass()
❌ Don’t
Use .attr('checked') to test whether a checkbox is checked
Expect the getter to return values for every matched element
Confuse .attr() with .data() — data lives in jQuery’s cache
Write .attr(class, 'x') without quotes — syntax error
Change type on dynamically created inputs in old IE without try/catch
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about .attr()
Attributes in markup — properties in memory.
5
Core concepts
get01
Getter
First only
API
set02
Setter
All matches
API
{}03
Object
Bulk set
Syntax
fn04
Callback
1.1+
Syntax
.prop05
Form state
Use .prop()
Compare
❓ Frequently Asked Questions
.attr() gets or sets HTML attributes on matched elements. As a getter it returns the attribute value (a string or undefined) for the first element only. As a setter it updates or removes attributes on every matched element — by name/value, plain object, or callback function.
.attr() reads and writes attributes — the initial values declared in HTML markup (strings). .prop() reads and writes properties — live DOM state that can change at runtime. For checked, selected, and disabled on form elements, always use .prop() or .is(':checked') — not .attr('checked').
No. The getter form .attr(name) returns the attribute value for only the first element in the set. To read each element individually, loop with .each() or .map(). Setters apply to every matched element.
Pass null as the value: .attr('title', null). jQuery removes the attribute the same way .removeAttr('title') would. Since jQuery 4.0, non-ARIA attributes can also be removed with false — but null is the safest cross-version choice.
In JavaScript, class is a reserved keyword. Writing .attr(class, 'active') is a syntax error. Always quote the attribute name: .attr('class', 'active'). For class manipulation, jQuery also provides .addClass(), .removeClass(), and .toggleClass().
Use .attr() for standard HTML attributes visible in markup — href, src, title, alt, id. Use .data() for arbitrary application data stored via jQuery's data cache — it does not write to the DOM attribute and handles object values. Use .prop() for live form state.
Did you know?
Before jQuery 1.6, .attr('checked') sometimes returned the live property value — causing inconsistent behavior across browsers. jQuery split responsibilities: .attr() for attributes, .prop() for properties. The cross-browser consistency benefit of .attr() still matters for attributes like href on links, where browsers historically reported values differently.