JavaScript Node compareDocumentPosition() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Instance method

What You’ll Learn

The Node.compareDocumentPosition() method reports where another node sits relative to this one. Learn the DOCUMENT_POSITION_* bitmask flags, how to test them with &, and common ancestor / order checks.

01

Kind

Instance method

02

Returns

Bitmask integer

03

Test with

Bitwise AND (&)

04

Same node

Returns 0

05

Flags

Precede / contain…

06

Status

Baseline widely

Introduction

Sometimes you need more than “is this inside that?” You may need document order: does A come before B? Is B an ancestor? compareDocumentPosition() answers with a single integer bitmask.

MDN stresses that because the result is a bitmask, you must use the bitwise AND operator (&) for meaningful checks—not === against one flag alone when multiple bits might be set.

💡
Beginner tip

Read the call as “where is otherNode relative to me?” So head.compareDocumentPosition(body) describes body’s position relative to head.

Understanding compareDocumentPosition()

MDN: the method reports the position of its argument node relative to the node on which it is called.

  • Bitmask — zero or more Node.DOCUMENT_POSITION_* bits combined.
  • Same node — returns 0.
  • OrderPRECEDING / FOLLOWING in tree order.
  • ContainmentCONTAINS (ancestor) / CONTAINED_BY (descendant).

📝 Syntax

JavaScript
const mask = node.compareDocumentPosition(otherNode);

if (mask & Node.DOCUMENT_POSITION_FOLLOWING) {
  // otherNode follows node
}

Parameters

  • otherNode — The node whose position is reported relative to node.

Return value

An integer bitmask, or 0 when otherNode is the same as this node.

🎯 Position Flags

ConstantValueMeaning (about otherNode)
DOCUMENT_POSITION_DISCONNECTED1Different documents or different trees
DOCUMENT_POSITION_PRECEDING2Comes before this node (tree / consistent order)
DOCUMENT_POSITION_FOLLOWING4Comes after this node
DOCUMENT_POSITION_CONTAINS8Is an ancestor of this node
DOCUMENT_POSITION_CONTAINED_BY16Is a descendant of this node
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC32Order may be arbitrary / not portable

Multiple bits can combine. MDN example: earlier in the document and containing this node → CONTAINS | PRECEDING10 (0x0A).

⚡ Quick Reference

GoalCode
Does other follow me?node.compareDocumentPosition(other) & Node.DOCUMENT_POSITION_FOLLOWING
Is other my ancestor?… & Node.DOCUMENT_POSITION_CONTAINS
Is other my descendant?… & Node.DOCUMENT_POSITION_CONTAINED_BY
Same node?node.compareDocumentPosition(node) === 0
head before body?head.compareDocumentPosition(body) & Node.DOCUMENT_POSITION_FOLLOWING
MDN statusBaseline Widely available (since July 2015)

🔍 At a Glance

Four facts to remember about compareDocumentPosition().

Returns
bitmask | 0

Integer flags

Baseline
widely

Since July 2015

Test
mask & flag

Not === alone

Relative to
otherNode

Arg vs this

Examples Gallery

Examples follow MDN Node.compareDocumentPosition() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

MDN head/body check and the same-node zero result.

Example 1 — Does body Follow head? (MDN)

Use bitwise AND to test DOCUMENT_POSITION_FOLLOWING.

JavaScript
const head = document.head;
const body = document.body;

if (head.compareDocumentPosition(body) & Node.DOCUMENT_POSITION_FOLLOWING) {
  console.log("Well-formed document");
} else {
  console.error("<head> is not before <body>");
}
Try It Yourself

How It Works

Relative to head, body follows in document order, so the FOLLOWING bit is set and the condition is truthy.

Example 2 — Same Node Returns 0

Comparing a node to itself yields no position bits.

JavaScript
const el = document.getElementById("box");
console.log(el.compareDocumentPosition(el)); // 0
Try It Yourself

How It Works

MDN: the return is 0 when otherNode is the same as this node.

📈 Containment, Order & Combined Bits

Ancestor/descendant checks, sibling order, and multi-flag masks.

Example 3 — Ancestor and Descendant Flags

CONTAINS vs CONTAINED_BY depend on which node you call.

JavaScript
const parent = document.getElementById("parent");
const child = document.getElementById("child");

const fromChild = child.compareDocumentPosition(parent);
console.log(!!(fromChild & Node.DOCUMENT_POSITION_CONTAINS));
// true — parent is an ancestor of child

const fromParent = parent.compareDocumentPosition(child);
console.log(!!(fromParent & Node.DOCUMENT_POSITION_CONTAINED_BY));
// true — child is a descendant of parent
Try It Yourself

How It Works

Always interpret flags relative to the receiver. For “is A inside B?” you can also use B.contains(A) when both are Elements—this API is richer for order.

Example 4 — Preceding Sibling

Earlier siblings set DOCUMENT_POSITION_PRECEDING.

JavaScript
const a = document.getElementById("a");
const b = document.getElementById("b");

const mask = b.compareDocumentPosition(a);
console.log(!!(mask & Node.DOCUMENT_POSITION_PRECEDING));
// true — a precedes b relative to b
Try It Yourself

How It Works

From b’s point of view, a comes earlier in the tree, so the PRECEDING bit is set.

Example 5 — Combined Bits (Contains + Preceding)

An ancestor that also precedes you can set two flags at once.

JavaScript
const wrap = document.getElementById("wrap");
const nested = document.getElementById("nested");

const mask = nested.compareDocumentPosition(wrap);
console.log(mask);
// often 10 = CONTAINS (8) | PRECEDING (2)

console.log(!!(mask & Node.DOCUMENT_POSITION_CONTAINS));
console.log(!!(mask & Node.DOCUMENT_POSITION_PRECEDING));
console.log(mask === Node.DOCUMENT_POSITION_CONTAINS); // false — extra bits!
Try It Yourself

How It Works

This is why MDN insists on &. Comparing the whole mask with === to a single constant fails when other bits are also set.

🚀 Common Use Cases

  • Checking document order between two nodes (before / after).
  • Detecting ancestor or descendant relationships with one API.
  • Validating structure (for example head before body).
  • Sorting or filtering nodes by tree position.
  • Handling disconnected nodes (different trees / documents).

🔧 How It Works

1

Pick two nodes

Call on one node; pass the other as otherNode.

Inputs
2

Engine builds a mask

Sets PRECEDING, FOLLOWING, CONTAINS, and related bits as needed.

Bitmask
3

Test with &

mask & Node.DOCUMENT_POSITION_* is truthy when that flag is set.

Check
4

Act on the relation

Reorder UI, validate structure, or branch your logic.

📝 Notes

  • Baseline Widely available (MDN, since July 2015).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Always test flags with &; multiple bits may be set together.
  • IMPLEMENTATION_SPECIFIC can appear with disconnected / arbitrary ordering.
  • Related: contains(), cloneNode(), appendChild(), parentNode, JavaScript hub.

Universal Browser Support

Node.compareDocumentPosition() is Baseline Widely available across modern browsers (MDN: since July 2015). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

Node.compareDocumentPosition()

Safe for production. Remember bitmask & checks; same node returns 0.

Universal Widely available
Google Chrome Full support · Desktop & Mobile
Full support
Mozilla Firefox Full support · Desktop & Mobile
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium & Legacy
Full support
Opera Full support · Modern versions
Full support
Internet Explorer Long-standing support in legacy IE
Full support
compareDocumentPosition() Excellent

Bottom line: Use & with DOCUMENT_POSITION_* flags; do not rely on === against a single flag when bits may combine.

Conclusion

Node.compareDocumentPosition() describes where another node sits relative to this one as a bitmask. Test with &, remember 0 for the same node, and use the DOCUMENT_POSITION_* constants for clear intent.

Continue with contains(), cloneNode(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Test flags with mask & Node.DOCUMENT_POSITION_*
  • Use named constants, not magic numbers alone
  • Treat 0 as “same node”
  • Read the call as “where is other relative to me?”
  • Combine checks when order and containment both matter

❌ Don’t

  • Assume mask === FOLLOWING when other bits may be set
  • Swap receiver and argument without rethinking the flags
  • Ignore DISCONNECTED across trees/documents
  • Confuse DOM Node with the Node.js runtime
  • Skip & because the raw number “looks right”

Key Takeaways

Knowledge Unlocked

Five things to remember about compareDocumentPosition()

Relative position as a bitmask of document flags.

5
Core concepts
& 02

Use &

test each flag

Check
🔄 03

Same = 0

identical node

Edge
📁 04

Contains

ancestor / child

Tree
📈 05

Bits combine

e.g. 10

Gotcha

❓ Frequently Asked Questions

It reports where otherNode sits relative to the node you call it on, as a bitmask of DOCUMENT_POSITION_* flags (or 0 if both are the same node).
No. MDN marks Node.compareDocumentPosition() as Baseline Widely available (since July 2015). It is a standard DOM method — not Deprecated, Experimental, or Non-standard.
Because the return value is a bitmask. Several flags can be set at once. Use result & Node.DOCUMENT_POSITION_FOLLOWING (and similar) to test each flag.
If otherNode is the same node as this node, compareDocumentPosition returns 0 (no position bits).
CONTAINS (8) means otherNode is an ancestor of this node. CONTAINED_BY (16) means otherNode is a descendant of this node.
Yes. For example, if otherNode precedes this node and also contains it, both PRECEDING and CONTAINS are set (value 10).
Did you know?

MDN’s classic check head.compareDocumentPosition(body) & Node.DOCUMENT_POSITION_FOLLOWING is a tiny way to confirm a well-formed document where <body> follows <head>.

Next: contains()

Simple boolean check for descendants (inclusive of self).

contains() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful