Use a Firefox bookmarklet that asks for a CSS selector, finds exactly one matching element, loads html2canvas, renders that element, and downloads a PNG. The method is convenient and repeatable, but it reconstructs the image from the DOM rather than capturing browser pixels, so unsupported CSS, cross-origin images, and canvas security rules can change or block the result.
What this bookmarklet does
A bookmarklet is a bookmark whose URL starts with javascript:. When you activate it on a page, the script prompts for a selector, checks how many nodes match, renders the chosen node with html2canvas, and downloads element-screenshot.png.
This version deliberately requires one match. A selector such as .card may identify many cards; silently choosing the first one can produce the wrong image. The script therefore asks you to refine the selector whenever the match count is not exactly one.
Create and install the bookmarklet
- Open Firefox’s bookmarks manager or add any page as a temporary bookmark.
- Edit the bookmark and replace its address with the complete JavaScript below.
- Make sure the address begins with
javascript:. Some Firefox interfaces remove that prefix when code is pasted; retype it manually if necessary. - Save the bookmark in the Bookmarks Toolbar or another location you can reach while browsing.
Keep the bookmarklet as one line. Line breaks are usually accepted in an address field, but a compact form avoids accidental whitespace or formatting characters.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
Complete bookmarklet
javascript:(async()=>{
const selector=prompt('CSS selector to capture:','#content');
if(!selector)return;
let nodes;
try{nodes=document.querySelectorAll(selector)}catch(e){alert('Invalid CSS selector: '+e.message);return;}
if(nodes.length!==1){alert(nodes.length===0?'No element matched: '+selector:'Selector matched '+nodes.length+' elements. Refine it to match exactly one.');return;}
const el=nodes[0];
if(!window.html2canvas){
await new Promise((resolve,reject)=>{
const s=document.createElement('script');
s.src='https://html2canvas.github.io/html2canvas/dist/html2canvas.min.js';
s.onload=resolve;
s.onerror=()=>reject(new Error('Could not load html2canvas'));
document.head.appendChild(s);
});
}
const canvas=await html2canvas(el,{scale:window.devicePixelRatio,useCORS:true});
const a=document.createElement('a');
a.download='element-screenshot.png';
a.href=canvas.toDataURL('image/png');
a.click();
})().catch(e=>alert('Capture failed: '+e.message));
When activated, the script loads the library only if the page does not already provide window.html2canvas. It then uses the display’s device-pixel ratio for sharper output on high-density screens and requests CORS-enabled image loading.
Find a reliable CSS selector in Firefox
- Open Firefox Developer Tools with F12 or Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (macOS).
- Choose the Inspector tab.
- Activate the node picker, then click the element you want to capture.
- Inspect its tag, classes,
id, and parent structure. Prefer a stable identifier such as#pricingor[data-testid="invoice"]over an automatically generated class. - Test the selector in the Inspector’s console with
document.querySelectorAll('your-selector').length. The bookmarklet should report1.
Selectors containing quotes are safest when entered at the prompt. If you generate bookmarklet source programmatically and embed a selector directly, escape the selector’s quote characters for the surrounding JavaScript string instead of inserting it raw.
How the rendering works
DOM reconstruction, not a native screenshot
html2canvas reads the target element and builds a canvas from the DOM, computed styles, and resources it can access. Its documentation states: “The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.” It can therefore differ from what Firefox paints.
Why the output may look different
- Only CSS properties understood by html2canvas are rendered correctly; unsupported effects, filters, blend modes, and some advanced layout details may be missing.
- Web fonts may still be loading when you run the bookmarklet, producing fallback text. Wait until the page is visually settled and activate it again.
- Animations, transitions, blinking cursors, video frames, and canvas content can represent a different moment than the visible page.
- The element’s own box is captured. Fixed or sticky descendants, overflow clipping, pseudo-elements, and content outside the element’s bounds can behave differently from a browser-level capture.
Cross-origin images and tainted canvases
useCORS:true asks the browser to fetch images with CORS, but it cannot grant permission that the image server does not provide. Cross-origin images need same-origin access or a server response that permits your page’s origin. If a foreign image is drawn without the required permission, the canvas can become tainted; reading it with toDataURL() then fails for security reasons. A proxy or a same-origin copy is required when the image host does not send suitable CORS headers.
Useful variations
Capture the first match (only when that is intentional)
If a page uses a repeated component and you explicitly want the first one, replace the count check with const el=document.querySelector(selector);. The stricter version is safer for a reusable bookmarklet because it prevents an ambiguous selector from silently producing an unexpected file.
Use a fixed selector
For a page you control, replace the prompt with const selector='#content';. If the selector is written into generated code, escape quotes and backslashes correctly. Prompting is preferable for a general-purpose bookmarklet because it avoids most quoting problems.
Change image format or filename
PNG preserves detail and transparency. To request JPEG, use canvas.toDataURL('image/jpeg',0.92) and a .jpg filename; JPEG does not preserve transparency. WebP support depends on the browser and can be requested with image/webp.
Capture at a chosen scale
The supplied code uses window.devicePixelRatio. For a predictable file size, replace it with a number such as 2. Higher values increase pixel dimensions, memory use, encoding time, and download size; they do not add detail that the source page does not contain.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Bookmarklet versus Firefox’s native tools
| Criterion | Bookmarklet with html2canvas | Firefox native capture |
|---|---|---|
| Rendering method | DOM-based reconstruction into a canvas | Browser-level screenshot of rendered pixels |
| Selector repeatability | Prompt and reuse a CSS selector on matching pages | Use Inspector’s selected node command each time, or the command-line selector option |
| Cross-origin behavior | Requires same-origin access or permitted CORS; a tainted canvas cannot be read reliably | Captures what Firefox can display without exposing page pixels to script |
| Full-page support | Designed here for one element; large or overflowing content may need additional handling | Firefox screenshot UI supports a selected region, highlighted page part, visible page, and full page |
| Installation | Install one bookmark; the page loads html2canvas when needed | No script installation; use the Inspector context menu or Firefox screenshot controls |
| Best use | Repeatable, scriptable element exports on pages that permit resource access | Pixel fidelity, cross-origin content, and one-off captures |
For a single element, Firefox Inspector also offers Screenshot Node: activate the context menu on the node in the Inspector’s HTML pane and select that command. Firefox’s command-line screenshot feature includes a --selector option for selecting one element, along with delay and device-pixel-ratio controls. Choose native capture when visual fidelity matters more than bookmarklet repeatability.
Troubleshooting
Nothing happens when the bookmark is clicked
Check that the address starts with javascript:, that the bookmark was saved as a bookmark rather than a search keyword, and that Firefox did not strip the prefix during paste. Edit the URL and type the prefix manually.
“Invalid CSS selector” appears
Inspect the selector for missing brackets, unmatched quotes, or CSS syntax that is not valid in querySelectorAll(). Test it in the console first. Escape special characters in IDs with CSS escaping or choose a simpler attribute selector.
No element matched
The page may render the target after the bookmarklet runs, the selector may be scoped to a different document, or the element may be inside an iframe or shadow root. Wait for the component to appear and retry. A normal document query cannot cross into an iframe; run the bookmarklet in that frame if it is same-origin and accessible. Shadow DOM requires code that explicitly enters the relevant shadow root.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsThe selector matched several elements
Add an ID, a distinctive attribute, a parent-child relationship, or an :nth-of-type() qualifier. Confirm the count is one before capturing. Avoid relying on classes added only for styling if the site changes them frequently.
“Could not load html2canvas” appears
The page, network, extension policy, or a content-security policy may block the external script. Retry on a page that permits the library, or use Firefox’s native Screenshot Node command. A strict policy can prevent bookmarklets from injecting any script.
The download fails with a security error
One or more images or other resources tainted the canvas because their servers did not permit cross-origin use. Remove those resources from the target, obtain CORS permission, serve the assets from the same origin, or use native Firefox capture.
The image is blank, clipped, or low resolution
Wait for lazy content and fonts, scroll or otherwise trigger lazy loading, and retry. Check that the element has non-zero dimensions and that its important content is not outside an overflow-clipped box. Increase the scale only after confirming the capture itself is correct; a larger scale cannot restore content that html2canvas could not render.
Or skip the browser setup
ScreenshotNeo provides a selector-capable screenshot API when you need a repeatable server-side capture instead of a page bookmarklet. It can capture one element by CSS selector, load lazy images for full-page shots, set a viewport or device preset, apply custom CSS or JavaScript, wait for a selector, delay, or network idle, and return PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled.
Example request (see the ScreenshotNeo documentation for parameters):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether it was billed. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Python and Node.js alternatives for automated captures
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Use the bookmarklet for an immediate, local experiment on the page currently open in Firefox. Use an API when you need scheduled jobs, consistent environments, webhooks, bulk URLs, caching, authentication headers, cookies, geolocation, or a capture workflow that does not depend on a person’s browser session.
Frequently Asked Questions
Can a bookmarklet capture an element inside an iframe?
Not with a top-level document query. Run the bookmarklet in the iframe when Firefox permits access; cross-origin frames remain isolated by the browser’s same-origin policy.
Why does increasing device-pixel ratio not fix missing CSS?
The scale changes canvas resolution only. html2canvas still renders only the DOM and CSS properties it understands, so unsupported effects remain different or absent.
What should I use for a pixel-perfect capture?
Use Firefox’s native Screenshot Node or another browser-level capture. The bookmarklet is a DOM reconstruction and is best when selector-based repeatability matters.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




