jQuery Ancestors

An ancestor is any element that wraps around another element - a parent, a grandparent, a great-grandparent, and so on all the way up to the <html> tag. jQuery gives you three methods for travelling upwards through these ancestors: parent(), parents(), and parentsUntil(). This lesson shows exactly how each one behaves and when to reach for it.

parent() - one step up

The parent() method returns the direct parent of the selected element, and only that one element. It never climbs higher than a single level. If you select several elements, it returns the direct parent of each of them.

Using parent()

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>

<div>
  <p>This paragraph contains a <span>span element</span> inside it.</p>
</div>

<script>
$(document).ready(function() {
  // Highlight the element that directly contains each <span>
  $("span").parent().css({ "color": "red", "border": "2px solid red" });
});
</script>

</body>
</html>

parents() - every ancestor

The parents() method returns all ancestor elements of the selected element, walking all the way up to <html>. Because it can match many elements, you will usually pass a selector to keep only the ancestors you care about, such as parents("ul") to grab only the surrounding lists.

Using parents() with a filter

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>

<ul>
  <li>Outer item
    <ul>
      <li>Inner item with a <span>span element</span> inside.</li>
    </ul>
  </li>
</ul>

<script>
$(document).ready(function() {
  // All ancestors of <span> that are <ul> elements
  $("span").parents("ul").css("border", "2px solid green");
});
</script>

</body>
</html>

parentsUntil() - a range of ancestors

The parentsUntil() method returns all ancestors between two given elements. It starts at the selected element's parent and keeps going up, but it stops as soon as it reaches the element matched by the argument. The stopping element itself is not included in the result.

Using parentsUntil()

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>

<div>
  <ul>
    <li><span>A span nested inside li, ul, and div.</span></li>
  </ul>
</div>

<script>
$(document).ready(function() {
  // All ancestors between <span> and <div>, not including <div>
  $("span").parentsUntil("div").css("background", "#fff3cd");
});
</script>

</body>
</html>
  • parent() climbs exactly one level and returns a single parent.
  • parents() climbs to the very top and can return many ancestors.
  • parentsUntil() climbs a slice of the tree, stopping before the matched element.
Note: The element you pass to parentsUntil() acts as a boundary and is excluded from the results. This is a common point of confusion, so double-check whether you need the boundary element included - if you do, use parents() instead.
MethodHow far it travelsSelector argument
parent()Exactly one level upOptional filter on the parent
parents()All the way to <html>Optional filter on ancestors
parentsUntil()Up to (but not including) the matchMarks where to stop
Note: When a page is deeply nested, parents("selector") is often clearer and safer than chaining parent().parent().parent(), because it does not break when the nesting depth changes.

Exercise: jQuery Ancestors

How does .parent() differ from .parents()?