JavaScript Node compareDocumentPosition() Method

Beginner
6 min read
Updated: Oct 2026
5 examples
Live preview

What Is compareDocumentPosition()?

node.compareDocumentPosition(otherNode) reports where otherNode sits relative to node (MDN) — as a bitmask of DOCUMENT_POSITION_* flags (or 0 if they are the same node).

Status: Baseline Widely available (since July 2015) — not Deprecated, Experimental, or Non-standard. Always test flags with bitwise & (MDN).

Remember
node.compareDocumentPosition(other)
→ bitmask (or 0 if same node)

1  DISCONNECTED
2  PRECEDING      (other before node)
4  FOLLOWING      (other after node)
8  CONTAINS       (other is ancestor)
16 CONTAINED_BY   (other is descendant)
32 IMPLEMENTATION_SPECIFIC

Test:  result & Node.DOCUMENT_POSITION_FOLLOWING
GoalPrefer
Before / after / contains?compareDocumentPosition + &
Is descendant? (simple)contains()
Same node reference?isSameNode() / ===

How to Use compareDocumentPosition()

Call it on one node, pass the other, then test bits with &.

  1. Pick the reference node (node).
  2. Call node.compareDocumentPosition(other).
  3. Test flags: result & Node.DOCUMENT_POSITION_FOLLOWING, etc.
  4. Remember several flags can be set together.
PieceRequired?Role
otherNodeYesNode to locate relative to this
Return—Integer bitmask (or 0)
TestYesBitwise & with a flag constant

Pseudocode

Pseudocode
mask = a.compareDocumentPosition(b)

if mask == 0:
  a and b are the same node
else if mask & FOLLOWING:
  b comes after a in document order
else if mask & PRECEDING:
  b comes before a

if mask & CONTAINED_BY:
  b is inside a (descendant)
if mask & CONTAINS:
  b is an ancestor of a

Cheat Sheet

Keep these flags handy when reading the bitmask.

FlagValueMeaning (other vs this)
DISCONNECTED1Different trees / documents
PRECEDING2other before this
FOLLOWING4other after this
CONTAINS8other is ancestor
CONTAINED_BY16other is descendant
IMPLEMENTATION_SPECIFIC32Order not portable
Same node0No bits set

Live Preview

Compare #a to another node. Flags are tested with bitwise &.

Tree

A (reference)

B (inside wrap)

C (after A)

Browser demo of Node.compareDocumentPosition().

Result
Pick a pair, then Compare…

JavaScript Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Does body Follow head?

MDN-style bitmask check with &.

JavaScript
const head = document.head;
const body = document.body;
const mask = head.compareDocumentPosition(body);

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

How It Works

  1. Compare head to body. Ask where body sits relative to head.
  2. Read the bitmask. Several flags may be set.
  3. AND with FOLLOWING. Truthy means body is after head.
  4. Do not use === 4 alone if other bits may also be set.

Example 2 — Same Node Returns 0

Comparing a node to itself yields no position bits.

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

How It Works

  1. Pass the same reference. otherNode === node.
  2. Result is 0. No DOCUMENT_POSITION bits.
  3. Useful guard. Detect identity before testing flags.
  4. Prefer === when you only care about sameness.

Example 3 — Ancestor (CONTAINS)

CONTAINS means other is an ancestor of this.

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

console.log(!!(mask & Node.DOCUMENT_POSITION_CONTAINS)); // true
console.log(!!(mask & Node.DOCUMENT_POSITION_PRECEDING)); // often true too
Try It Yourself

How It Works

  1. Call on the child. Pass the parent as other.
  2. CONTAINS is set. Parent is an ancestor.
  3. PRECEDING often too. Ancestors come before in tree order.
  4. Mask can be 10 (8 + 2) — test each flag separately.

Example 4 — Descendant (CONTAINED_BY)

Flip the call: parent asks about the child.

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

console.log(!!(mask & Node.DOCUMENT_POSITION_CONTAINED_BY)); // true
console.log(parent.contains(child)); // simpler yes/no API
Try It Yourself

How It Works

  1. Call on the parent. Pass the child as other.
  2. CONTAINED_BY. Child is a descendant.
  3. Also FOLLOWING is common (descendant comes after).
  4. Prefer contains() when you only need a boolean.

Example 5 — Decode the Bitmask

List every flag that is set — great for learning.

JavaScript
function flags(mask) {
  const names = [];
  if (mask & Node.DOCUMENT_POSITION_DISCONNECTED) names.push("DISCONNECTED");
  if (mask & Node.DOCUMENT_POSITION_PRECEDING) names.push("PRECEDING");
  if (mask & Node.DOCUMENT_POSITION_FOLLOWING) names.push("FOLLOWING");
  if (mask & Node.DOCUMENT_POSITION_CONTAINS) names.push("CONTAINS");
  if (mask & Node.DOCUMENT_POSITION_CONTAINED_BY) names.push("CONTAINED_BY");
  if (mask & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) names.push("IMPL");
  return mask === 0 ? ["SAME_NODE"] : names;
}

const a = document.getElementById("a");
const b = document.getElementById("b");
console.log(flags(a.compareDocumentPosition(b)));
Try It Yourself

How It Works

  1. Get the mask. One integer from compareDocumentPosition.
  2. Test each flag. Push a name when & is truthy.
  3. Handle 0. Label it as the same node.
  4. Read the list. See combined relationships clearly.

Edge Cases & Pitfalls

Check these before relying on raw numeric results.

bitmask

Always use bitwise AND

MDN: the result is a bitmask. Use result & FLAG, not result === FLAG.

combined

Multiple flags at once

Ancestor cases often set CONTAINS + PRECEDING (e.g. 10).

disconnected

Disconnected trees

DISCONNECTED may combine with PRECEDING/FOLLOWING in an arbitrary but consistent order.

simpler

Prefer contains() for yes/no

If you only need “is this inside that?”, use contains().

Browser Support

Node.compareDocumentPosition() is marked Baseline Widely available on MDN (since July 2015).

✓ Baseline · Widely available

Node.compareDocumentPosition()

Returns a DOCUMENT_POSITION_* bitmask for otherNode relative to this node. Test with bitwise AND. Same node → 0.

100% Widely available
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
compareDocumentPosition() Excellent

Bottom line: Safe everyday DOM API. Decode with &; use contains() when a boolean is enough. See the MDN compareDocumentPosition reference.

Performance Notes

ApproachCostBest for
compareDocumentPositionCheap tree walkFull relative relationship
contains()Cheaper intentDescendant yes/no
=== / isSameNodeO(1)Identity only

Fine for UI logic. Prefer the smallest API that answers your question — do not decode a bitmask when contains() is enough.

Key Takeaways

  • Bitmask: relative position of other to this.
  • Test with &: never assume a single exact number.
  • 0: same node.
  • CONTAINS vs CONTAINED_BY: ancestor vs descendant.

One line: compareDocumentPosition answers “where is the other node?” via combinable position flags.

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

Next: contains()

Learn the simple boolean descendant check.

contains tutorial →

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.

8 people found this page helpful