Absolute vs Relative XPath
⚠ From Real Projects: Replace this section with your own experience before publishing.
Quick Answer
Absolute XPath starts at the root of the page with a single slash (/html/body/…) and spells out every step to the element. Relative XPath starts with a double slash (//) and finds the element anywhere in the page by its attributes, text or neighbours. Absolute XPath breaks whenever the page structure changes; relative XPath survives. Use relative XPath in real projects.
Comparison at a Glance
| Aspect | Absolute XPath | Relative XPath |
|---|---|---|
| Starts with | / (single slash, from the root) |
// (anywhere in the document) |
| Path | Every element from <html> down |
Only what identifies the element |
| Length | Long | Short |
| Readability | Hard to tell what it targets | Self-describing (@name='email') |
| When the layout changes | Breaks — or silently matches the wrong element | Usually keeps working |
| Speed | No meaningful difference in modern browsers | No meaningful difference in modern browsers |
| Use in projects | Avoid | Preferred |
The Sample Page
<html>
<body>
<div id="app">
<form id="login">
<div class="row"><label>Email</label><input name="email" type="text"></div>
<div class="row"><label>Password</label><input name="password" type="password"></div>
<button type="submit">Sign in</button>
</form>
</div>
</body>
</html>
Absolute XPath
Absolute XPath lists the full hierarchy from the root node to the target:
/html/body/div/form/div[1]/input → the email field
/html/body/div/form/div[2]/input → the password field
- Starts with a single slash (
/). - Depends on every element above the target — and on positions like
div[1]. - Usually produced by "Copy full XPath" in browser DevTools.
Why it breaks
Suppose a developer adds a welcome banner at the top of the form:
<form id="login">
<div class="banner">Welcome</div> <!-- new -->
<div class="row"><label>Email</label><input name="email"></div>
…
Now /html/body/div/form/div[1]/input points at the banner, which has no input — nothing matches, and the test fails with NoSuchElementException. Worse, in other layouts a shifted index quietly matches the wrong element. The relative XPath //input[@name='email'] still finds the email field, because it never depended on the structure.
Relative XPath
Relative XPath starts with // ("search anywhere") and anchors to something meaningful about the element:
//input[@name='email'] → by attribute
//button[text()='Sign in'] → by visible text
//label[text()='Password']/following-sibling::input → relative to its label
//form[@id='login']//input[@type='password'] → scoped to a container
- Short and readable — the locator describes what it finds.
- Independent of wrappers and positions.
- The standard choice in production frameworks.
Note that a relative XPath can still be brittle if you write it with positions — //form/div[1]/input has the same problem as absolute XPath. Anchor to attributes and text, not indexes.
Which Is Faster?
A common interview question. Older tutorials claim relative XPath is faster (or slower, because // searches the whole document). In modern browsers the difference is negligible — a few microseconds either way, far below the time of a single page action. Speed is not the reason to choose. Relative XPath wins on maintainability: it keeps working when the layout changes. If you want to mention performance, the useful point is that CSS selectors and IDs are the simplest, fastest-to-read locators, and that a precise locator is always better than a broad one.
When a Simple XPath Isn't Enough: Axes
When the element itself has nothing unique, locate it through a stable neighbour using XPath axes:
| Axis | Finds | Family analogy |
|---|---|---|
parent:: |
The direct parent | Your parent |
child:: |
Direct children | Your children |
ancestor:: |
Parent, grandparent and above | Parents and grandparents |
descendant:: |
Children, grandchildren and below | Children and grandchildren |
following-sibling:: |
Later siblings | Younger siblings |
preceding-sibling:: |
Earlier siblings | Older siblings |
following:: |
Everything after it in the page | Everyone after you |
preceding:: |
Everything before it | Everyone before you |
self:: |
The node itself | Yourself |
The classic project use is a dynamic table: find the row by a value you know, then move to the cell you need — //td[text()='Ravi']/ancestor::tr//button[text()='Edit']. Full coverage with tested examples: Selenium Locators & XPath.
How to Write Stable XPath
- Prefer an ID, a test attribute such as
data-testid, orname. - Use visible text for buttons and links:
//button[normalize-space()='Sign in']. - For dynamic IDs, match the stable part:
//input[starts-with(@id,'user-')]. - Scope to a container when there are duplicates:
//form[@id='login']//input[@name='email']. - Use axes from a stable neighbour when the target has nothing unique.
- Avoid indexes, and don't paste "Copy full XPath" from DevTools.
- Check it matches exactly one element: DevTools → Elements → Ctrl+F, or the Selector Playground.
See how Selenium finds and uses elements step by step in the Selenium WebDriver Visualizer.
From Real Projects
Identifying elements by id and class name and writing XPath was a daily part of my automation work on Canolog and Testsigma. I preferred id and class name when they were unique and stable, and used XPath for everything else — always keeping locators inside POM classes so they could be reviewed and fixed in one place. If an XPath starts from the root of the page, expect it to break with the next layout change.
Frequently Asked Questions
What is the difference between absolute and relative XPath?
Absolute XPath starts from the root with
/and lists the full path; relative XPath starts with//and finds the element anywhere by its attributes, text or neighbours.Which XPath is faster?
Neither in any meaningful way — the difference is negligible in modern browsers. Choose relative XPath because it's far more maintainable.
Why is relative XPath preferred?
It's shorter, readable and keeps working when wrappers or positions in the page change; absolute XPath breaks or matches the wrong element.
What does
//mean in XPath?"Search anywhere below this point." At the start of an expression it searches the whole document; in the middle (
//form//input) it searches all descendants.What does a single
/mean?A direct child step. At the start it means the document root, which is why absolute XPath starts with
/html.What should I do when an element has no unique attribute?
Locate it relative to a stable neighbour with axes such as
following-sibling::orancestor::, or scope it to a unique container.Is it OK to copy XPath from Chrome DevTools?
"Copy full XPath" gives an absolute path — avoid it. "Copy XPath" may give a short relative path with an ID, which is a starting point, but check that it doesn't rely on indexes.
Related
- Selenium Locators & XPath: Complete Guide
- Selenium Locators Practice: 150+ Exercises
- Selenium Locators Cheat Sheet
- The Complete Selenium WebDriver Guide