How to Scroll to an Element with a Dynamic ID and Adjust for Padding or Fixed Headers
Adam C. |

In many web applications, you often need to scroll to specific elements dynamically based on partial or unknown IDs. This can be especially useful when elements are generated dynamically, and you only know a portion of the ID, such as a prefix or suffix.

Photo by Frankie on Unsplash

Additionally, if your web page has a fixed header (like a navigation bar), you'll need to adjust the scroll position to ensure the target element is fully visible and not hidden behind the fixed header.

In this guide, we’ll cover:

  1. How to scroll to an element using a dynamic (partial) ID.
  2. How to apply an offset for fixed headers or padding to ensure proper visibility.

1. Scrolling to an Element with a Dynamic ID

To scroll to an element when you know only part of its ID (e.g., it starts with or contains a certain string), you can use the CSS attribute selector in combination with JavaScript’s querySelector() method.

Example: Scroll to an Element with a Dynamic ID Prefix

Let’s say you want to scroll to an element where the ID starts with target-123- (where the 123 is dynamic).

const targetRank = "123"; // Dynamic portion of the ID
const element = document.querySelector(`[id^="target-${targetRank}-"]`); // Find element where ID starts with "target-123-"

if (element) {
  element.scrollIntoView({
    behavior: "smooth", // Smooth scrolling animation
    block: "start",     // Align the element at the start of the viewport
  });
}

Explanation:

  • [id^="prefix"]: This CSS attribute selector selects an element where the id starts with a specific prefix (target-123- in this case). The ^= symbol matches the beginning of the string.
  • querySelector(): This method allows you to use the selector to find the element with the matching dynamic ID.
  • behavior: "smooth": This provides a smooth scrolling effect.
  • block: "start": This ensures the element is aligned with the top of the viewport.

2. Scrolling with Offset for Fixed Headers or Padding

In cases where you have a fixed header (like a navigation bar) or need to add some padding to the scroll position, you’ll want to adjust the scroll position manually. The scrollIntoView() method does not account for fixed elements, so we need to calculate the position and scroll accordingly.

Example: Scroll to an Element with an Offset (Fixed Header)

Assume your page has a fixed header that is 80px tall. Here’s how you can adjust the scroll position to ensure the element is not hidden behind the header:

const targetRank = "123"; // Dynamic portion of the ID
const element = document.querySelector(`[id^="target-${targetRank}-"]`); // Find element where ID starts with "target-123-"

if (element) {
  // Calculate the position of the element and adjust for the fixed header
  const yOffset = -80; // Height of the fixed header (80px)
  const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

  // Scroll to the calculated position
  window.scrollTo({
    top: y,
    behavior: 'smooth', // Smooth scrolling animation
  });
}

Explanation:

  • getBoundingClientRect().top: This method returns the position of the element relative to the viewport (its top position).
  • window.pageYOffset: This gives the current vertical scroll position of the window.
  • yOffset: This is the offset for the fixed header. In this case, it’s set to -80 to account for the 80px header.
  • window.scrollTo(): This method allows you to scroll the page to a specific top position (with an optional behavior: 'smooth' for smooth scrolling).

3. Dynamic Offset Calculation (If Header Height Varies)

If the height of the fixed header changes dynamically (for example, on responsive layouts or different screen sizes), you can calculate the header’s height dynamically:

const targetRank = "123"; // Dynamic portion of the ID
const element = document.querySelector(`[id^="target-${targetRank}-"]`); // Find element where ID starts with "target-123-"
const fixedHeaderHeight = document.querySelector('.fixed-header')?.offsetHeight || 0; // Dynamically get the height of the fixed header

if (element) {
  const yOffset = -fixedHeaderHeight; // Use the dynamic header height
  const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

  window.scrollTo({
    top: y,
    behavior: 'smooth', // Smooth scrolling animation
  });
}

In this example:

  • document.querySelector('.fixed-header')?.offsetHeight: Dynamically retrieves the height of the element with the .fixed-header class. If no such element exists, it defaults to 0.
  • yOffset = -fixedHeaderHeight: This dynamically adjusts the offset based on the actual height of the header.

Key Takeaways

  • Dynamic ID Matching: Use the querySelector() method with CSS attribute selectors like [id^="prefix"] to scroll to elements with dynamic or partial IDs.
  • Adjusting for Fixed Headers: Manually adjust the scroll position to account for fixed headers or padding using getBoundingClientRect() and window.pageYOffset.
  • Smooth Scrolling: You can always apply smooth scrolling by using behavior: "smooth" in both scrollIntoView() and window.scrollTo().

Full Example:

Here’s a complete example that handles both dynamic ID scrolling and adjusting for a fixed header:

const targetRank = "123"; // Dynamic portion of the ID
const element = document.querySelector(`[id^="target-${targetRank}-"]`); // Find element where ID starts with "target-123-"
const fixedHeaderHeight = document.querySelector('.fixed-header')?.offsetHeight || 0; // Dynamically get the height of the fixed header

if (element) {
  const yOffset = -fixedHeaderHeight; // Use the dynamic header height
  const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

  // Scroll to the calculated position with smooth scrolling
  window.scrollTo({
    top: y,
    behavior: 'smooth', // Smooth scrolling animation
  });
}

This method ensures you can scroll to an element with a dynamic ID while also considering padding or fixed headers, providing a seamless user experience.