# elementCenter vs boundingBox in ego-browser: Understanding Element Positioning Helpers

> Understand elementCenter vs boundingBox in ego-browser for precise element positioning. Learn how each helper provides unique viewport data for developers.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-07-26

---

**The `center` helper returns an `{x, y}` coordinate representing the geometric middle of an element, while `boundingBox` returns a full rectangle `{x, y, width, height}` describing the element's viewport position and dimensions.**

When automating browser interactions with **ego-browser** from the **citrolabs/ego-lite** repository, precise element positioning is critical. The framework provides two distinct geometric helpers—`center` and `boundingBox`—that return different spatial data for the same DOM element. Understanding the difference between these positioning helpers ensures your automation scripts interact with elements correctly, whether you are clicking buttons or capturing screenshots.

## What `center` Returns: The Geometric Midpoint

The `center` helper calculates the **geometric center** of a resolved element, returning a simple point object with `x` and `y` coordinates.

According to the source code, the `resolveElementCenter` function in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) (lines 63‑46) first attempts to use the Chrome DevTools Protocol's `DOM.getBoxModel` to obtain the element's box model. If cached box model data is available, it calculates the center from the four corner coordinates. When this data is unavailable—such as when using role/name locators—it falls back to evaluating JavaScript that calls `getBoundingClientRect()` and computes `x + width/2` and `y + height/2`.

This approach ensures you get the exact midpoint for clicking, tapping, or dragging operations.

## What `boundingBox` Returns: The Full Rectangle

In contrast, the `boundingBox` helper returns a **complete rectangle** describing the element's position and size in viewport CSS pixels.

As implemented in [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts) (lines 199‑209), this helper evaluates `this.getBoundingClientRect()` directly on the resolved element. It returns an object containing `{x, y, width, height}`, or `null` if the element has zero size. Unlike `center`, which computes a derived point, `boundingBox` provides the raw geometric boundary data.

## Key Implementation Differences

### Source Code Structure

The architectural distinction between these helpers reflects their different purposes:

- **`resolveElementCenter`** in [`package/ego-browser/src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/element-resolver.ts): Handles complex center calculations using CDP box models with JavaScript fallbacks.
- **`boundingBox`** in [`package/ego-browser/src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/locator.ts): Wraps `getBoundingClientRect()` to return the full bounding client rectangle.
- **`pointer`** operations in [`package/ego-browser/src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts): Consume the center point for click and drag operations via `resolveLocatorCenter`.

### Data Shape and Type Safety

Because `center` returns a **point** (`{x, y}`) and `boundingBox` returns a **rectangle** (`{x, y, width, height}`), they are **not interchangeable**. Passing a bounding box where a point is expected—or vice versa—will cause runtime errors in your automation scripts.

## Practical Code Examples

The following examples demonstrate typical usage patterns for both helpers:

```javascript
// Example 1 – Click the exact centre of a button
await ego.click(await ego.center('css:button.submit'));
//   ^ ego.center → {x: 123, y: 456}

// Example 2 – Scroll an element into view using its bounding box
const box = await ego.boundingBox('#sidebar');
if (box) {
  // Scroll the page so the element's top-left corner aligns with the viewport
  await ego.scrollBy({dx: -box.x, dy: -box.y});
}

// Example 3 – Take a screenshot of a specific element
const box = await ego.boundingBox('xpath://*[@id="logo"]');
if (box) {
  await ego.screenshot({path: 'logo.png', clip: box});
}

```

## When to Use Each Helper

Choose the helper based on the geometric data your automation task requires:

- **Use `center`** when you need to interact with the middle of an element, such as for mouse clicks, taps, or drag operations where hitting the visual center is important.
- **Use `boundingBox`** when you need dimensional awareness, such as for scrolling elements into view, calculating offsets relative to other elements, or capturing element-specific screenshots using the `clip` parameter.

## Summary

- **`center`** returns an `{x, y}` point representing the geometric center, calculated from box models or `getBoundingClientRect()` in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts).
- **`boundingBox`** returns a full `{x, y, width, height}` rectangle directly from `getBoundingClientRect()` in [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts).
- The helpers are **not interchangeable** due to different return shapes.
- Use `center` for precise interaction points and `boundingBox` for dimensional measurements and viewport calculations.

## Frequently Asked Questions

### Can I use `boundingBox` instead of `center` for clicking elements?

No, because `boundingBox` returns a rectangle object while `center` returns a coordinate point. Methods like `ego.click()` expect an `{x, y}` point. You would need to manually calculate the center from the bounding box (`x + width/2, y + height/2`) rather than substituting the objects directly.

### Does `center` always calculate from the box model?

Not exclusively. According to the implementation in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts), it first attempts to use the cached CDP box model via `DOM.getBoxModel`, but falls back to JavaScript evaluation of `getBoundingClientRect()` when necessary, such as when resolving elements by role or name locators.

### What happens if an element has zero size?

The `boundingBox` helper returns `null` if the element has zero width or height, as detected by `getBoundingClientRect()`. The `center` helper may still attempt to calculate coordinates based on the rect data, but clicking a zero-size element's center typically has no visible effect.

### Which helper is better for taking element screenshots?

Use `boundingBox`. The screenshot method accepts a `clip` parameter that requires `{x, y, width, height}`—the exact shape returned by `boundingBox`. The `center` helper only provides coordinates without dimensions, making it unsuitable for defining screenshot boundaries.