# Capturing an element

Capture one element with a CSS selector, or a rectangle you choose, with an optional transparent background.

Add `selector` and the image contains only that element.

```bash
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&selector=.infobox" \
  --output eiffel-infobox.png
```

You get the fact box from the side of the article and nothing else. The image is exactly as big as the element.

![The infobox of the Wikipedia article about the Eiffel Tower](https://curlshot.com/docs/examples/wikipedia-element.webp)

## Pick an element with a selector

A CSS selector is a short pattern that points at an element on a page. It is the same language web designers use to style pages.

| Selector | What it matches |
| --- | --- |
| `.infobox` | An element with the class `infobox`. |
| `#content` | The element with the id `content`. |
| `table` | A `<table>` element. |
| `main article` | An `<article>` inside `<main>`. |

To find one, open the page in your browser, right-click the part you want and choose **Inspect**. Look at the element's `class` or `id`.

### selector

Capture only the first element that matches this CSS selector.

There is no default. Leave it out and the capture is not limited to an element.

If several elements match, the first one on the page is used. The element does not have to be on the first screen. An element further down the page is captured too.

A selector can be up to 1000 characters long.

> **Heads up**
>
> The `#` character has a special meaning in a web address. Write it as `%23`, so `#content` becomes `selector=%23content`. Spaces become `%20`. Your language's URL functions do this for you, as shown in [Encode the URL](https://curlshot.com/docs/screenshot-url.md#encode-the-url).

## Capture a rectangle

Sometimes there is no handy element. Then you can cut out a rectangle by its position and size.

```bash
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&clip_x=0&clip_y=0&clip_width=1280&clip_height=300" \
  --output eiffel-top-strip.png
```

You get a strip 1280 pixels wide and 300 pixels tall, from the top of the page.

The position is measured from the top left corner of the whole page, not of the first screen. So a large `clip_y` reaches content far down the page.

### clip_x

Left edge of the area, in pixels from the left of the page.

There is no default. If you leave it out while clipping, the area starts at `0`.

### clip_y

Top edge of the area, in pixels from the top of the page.

There is no default. If you leave it out while clipping, the area starts at `0`.

### clip_width

Width of the area in pixels.

There is no default. It is required when you use any `clip_*` option. The smallest value is `1` and the largest is `8000`.

### clip_height

Height of the area in pixels.

There is no default. It is required when you use any `clip_*` option. The smallest value is `1` and the largest is `30000`.

If the rectangle sticks out past the edge of the page, it is trimmed to fit. If it starts outside the page, you get [`invalid_options`](https://curlshot.com/docs/errors.md#invalid_options).

> **Sizes and pixel density**
>
> Selector and clip sizes are in page pixels. With [`device_scale_factor=2`](https://curlshot.com/docs/options.md#device_scale_factor), a 600 pixel wide element gives a 1200 pixel wide image.

## Transparent background

By default the page is drawn on white. With [`omit_background=true`](https://curlshot.com/docs/options.md#omit_background) the white is left out, so areas the page does not paint stay see-through.

This is useful for logos, badges and charts that you want to place on your own background.

```bash
curl -X POST "https://curlshot.com/api/v1/screenshot" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1 style=\"display:inline-block;margin:0;font:600 48px sans-serif\">Eiffel Tower</h1>",
    "selector": "h1",
    "omit_background": true
  }' \
  --output heading.png
```

You get the title, "Eiffel Tower", as a small image with nothing behind the letters. This works because the HTML sets no background of its own.

### omit_background

Keep the page background transparent.

The default is `false`.

Two things to know:

- It needs a format that can store transparency. Use `png` or `webp`. With `format=jpeg` you get `invalid_options`.
- It removes only the browser's default white. If the site sets its own background colour, that colour stays in the screenshot.

When you control the markup yourself, the second point is yours to decide. See [HTML and Markdown input](https://curlshot.com/docs/html-and-markdown.md).

## When the element is not there

If nothing matches the selector, you do not get an empty image. You get an error:

```bash
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&selector=.does-not-exist"
```

```json
{
  "error_code": "selector_not_found",
  "error_message": "No element matches the selector \".does-not-exist\".",
  "documentation_url": "https://curlshot.com/docs/errors#selector_not_found"
}
```

The same error code comes back when the element exists but is hidden, because there is nothing to photograph.

It is not counted against your quota.

The usual causes:

- A typo in the selector. Test it in your browser console with `document.querySelector('.infobox')`.
- The element appears late, after a script has run. Add [`wait_for_selector`](https://curlshot.com/docs/options.md#wait_for_selector) with the same selector, so the capture waits until the element is visible.
- The site shows a different layout to our browser. Phone and desktop layouts often use different class names. Check which [device](https://curlshot.com/docs/devices.md) you asked for.

```bash
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&selector=.infobox&wait_for_selector=.infobox" \
  --output eiffel-infobox.png
```

> **Common mistakes**
>
> - **Using `selector` together with `clip_*`.** Pick one. Sending both returns `invalid_options`.
> - **Sending only `clip_x` and `clip_y`.** A rectangle needs a size. Add `clip_width` and `clip_height`.
> - **Using them with `format=pdf`.** Element and clip captures produce images only.
> - **An unencoded `#`.** Everything after a bare `#` is dropped from the address before it is sent. Write `%23`.
> - **A selector that is not valid CSS.** That returns `invalid_options`, not `selector_not_found`.
> - **An element that is too big.** A very large element at a high pixel density returns [`content_too_large`](https://curlshot.com/docs/errors.md#content_too_large). Lower `device_scale_factor`.

## Where to go next

- [Waiting and timing](https://curlshot.com/docs/waiting.md): wait for an element that appears late.
- [Custom CSS, JavaScript and clicks](https://curlshot.com/docs/customize.md): hide or restyle things around the element.
- [Full-page screenshots](https://curlshot.com/docs/full-page.md): when you want everything.
- [Options reference](https://curlshot.com/docs/options.md#selector): the capture options with their limits.
