.offsetParent() (since jQuery 1.2.6) returns the closest positioned ancestor of each matched element. It takes no arguments. Official docs note this is useful for calculating offsets, animations, and placing objects on the page.
Remember
$("li.item-a").offsetParent(); // official: positioned "II"
$("#box").offsetParent(); // nearest relative/absolute/fixed
$(".child").offsetParent().css(…); // style the positioning context
// parent() → immediate parent (any position)
// closest(sel) → nearest match to your selector
// offsetParent() → nearest positioned ancestor
Start from a child, walk up until a positioned ancestor appears.
Select the element whose positioning context you need.
Call .offsetParent() — no arguments.
Static ancestors are skipped; relative / absolute / fixed stop the walk.
If none exist, browsers typically return html or body.
Use the result with .offset() / .position() for layout math.
Piece
Required?
Role
Matched set
Yes
Element(s) to start from
Arguments
None
Method takes no parameters
Stop condition
—
Ancestor with non-static position
Return value
—
New jQuery set of positioned ancestor(s)
Pseudocode
Pseudocode
call $(starts).offsetParent()
result = empty set
for each start in the matched set:
ancestor = start.parentElement
while ancestor is not null:
if ancestor.position is relative
or absolute
or fixed:
add ancestor to result
break
ancestor = ancestor.parentElement
// if none found → document root (html/body)
return result as a new jQuery object
Reference
Cheat Sheet
Keep ancestor methods side by side.
Topic
Detail
Syntax
.offsetParent()
Since
jQuery 1.2.6
Looks for
relative / absolute / fixed
Skips
position: static
Includes self?
No — ancestors only
vs .parent()
Immediate parent vs positioned ancestor
vs .closest()
Your selector vs position rule
DOM change?
No — query only
Try it
Live Preview
From li.item-a, compare .offsetParent(), .parent(), and .closest("li").
I
II
A
B
1
2
C
III
Sample sets li.item-ii to position: relative via jQuery (official demo idea).
Result
Ready — choose a call and click Run.
Code
jQuery Examples
Short, copy-ready snippets. Open DevTools, or use Try It Yourself for a live editor.
Example 1 — Official: From Item A to Positioned II
Mark the offset parent of nested item A (jQuery API demo).
II [op]
(item A’s offset parent is the positioned II)
How It Works
Position. Set li.item-ii to relative.
Start. Select li.item-a.
Walk. Skip the static ul parent.
Stop. Land on positioned II and mark it.
Example 2 — .offsetParent() vs .parent()
Immediate parent is not always the positioning context.
jQuery
$("#box").css("position", "relative");
var p = $("#child").parent()[0].id;
var op = $("#child").offsetParent()[0].id;
$("#out").text("parent=" + p + " · offsetParent=" + op);
parent=wrap · offsetParent=box
wrap is static; box is relative
How It Works
parent. Returns the direct wrapper (#wrap).
offsetParent. Skips static #wrap.
Find. Lands on positioned #box.
Lesson. Use .offsetParent() when you need the positioning context.
Example 3 — .offsetParent() vs .closest("li")
.closest() can match the start element; .offsetParent() never does.
jQuery
$("li.item-ii").css("position", "relative");
var c = $("li.item-a").closest("li").hasClass("item-a");
var op = $("li.item-a").offsetParent().hasClass("item-ii");
$("#out").text(
"closest is item-a? " + c +
" · offsetParent is item-ii? " + op
);
offsetParent tag: BODY
(or HTML — depends on the browser)
How It Works
All static. No relative/absolute/fixed ancestor exists.
Fallback. The browser returns body or html.
Check. Read tagName to see which root you got.
Tip. Add an explicit positioned wrapper when you need a stable context.
Edge Cases & Pitfalls
Why the offset parent is not always the element you expect.
static
Static ancestors are skipped
Default CSS position: static never becomes an offset parent.
self
Never returns the start element
Even if the start node is positioned, the method looks at ancestors only.
root
No positioned ancestor → document root
Expect body or html depending on the browser when the tree is all static.
sticky
sticky is not in the official list
Docs specify relative, absolute, and fixed. Do not assume sticky always counts.
Compatibility
Browser Support
.offsetParent() has been part of jQuery since 1.2.6. It works in every browser that runs your loaded jQuery version and mirrors the idea of the native DOM offsetParent property.
✓ Stable · jQuery 1.2.6+
jQuery .offsetParent()
Supported across jQuery 1.x (1.2.6+), 2.x, and 3.x. Prefer a current jQuery 3.x build. Result depends on live CSS position values.
100%With jQuery
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
.offsetParent()Universal
Bottom line: Safe for layout and animation helpers. Ensure a positioned ancestor exists when you need a predictable context.
Analysis
Performance Notes
Approach
Cost
Best for
.parent()
Cheapest
One step up
.offsetParent()
Walk until positioned
Positioning context
.closest(sel)
Walk until selector
Known ancestor selector
Cost grows with how deep the walk is. Prefer an explicit positioned wrapper near the element when you call this often (for example in animation loops).
Remember
Key Takeaways
Role: closest ancestor with relative / absolute / fixed.
Skips:position: static (the default).
vs parent: immediate parent ≠ positioning context.
One line:.offsetParent() finds the nearest positioned ancestor — the context for offsets and absolute placement.
Frequently Asked Questions
.offsetParent() walks up from each element in the current set and returns the closest ancestor whose CSS position is relative, absolute, or fixed. Useful for understanding the positioning context used for offsets and animations.
An element with position: relative, absolute, or fixed. Static (the CSS default) ancestors are skipped. Official jQuery docs define positioned this way.
.parent() returns the immediate parent only. .offsetParent() may skip several static ancestors until it finds a positioned one — or the document root when none exist.
.closest(selector) finds the nearest ancestor (or self) matching a selector you provide. .offsetParent() finds the nearest positioned ancestor — no selector needed.
No. It searches ancestors. Even if the starting element is positioned, the method looks upward for a positioned ancestor.
No. It only returns a new jQuery object wrapping the positioned ancestor(s).