Detecting and Extracting Layered Background Images versus Overlay Images in Web Pages
The AI Website Cloner Template implements a two-step browser automation pipeline that enumerates every <img> element and computed CSS background-image, then analyzes DOM hierarchy (sibling counts, z-index, and positioning) to classify assets as layered backgrounds or overlay images before persisting them to role-specific directories.
Detecting and extracting layered background images versus overlay images in web pages requires distinguishing between CSS background layers and foreground image elements that create composite visual effects. The JCodesMore/ai-website-cloner-template solves this through an integrated discovery and classification system defined in .github/skills/clone-website/SKILL.md. This approach ensures pixel-perfect replication by preserving the exact layering semantics of the original design.
The Browser-Based Asset Discovery Pipeline
The template executes a JavaScript payload within the browser automation (MCP) environment to capture the complete visual asset inventory of a target page.
Enumerating Visual Elements in SKILL.md
The discovery logic resides in .github/skills/clone-website/SKILL.md (lines 191–225). It collects two distinct categories of visual assets:
<img>elements with their complete DOM context, including parent classes, sibling counts, and computed positioning styles.- Computed
background-imagevalues from every DOM node that has a non-none background image declaration.
The payload returns a structured JSON object that distinguishes between these asset types:
{
images: [...document.querySelectorAll('img')].map(img => ({
src: img.src || img.currentSrc,
alt: img.alt,
width: img.naturalWidth,
height: img.naturalHeight,
parentClasses: img.parentElement?.className,
siblings: img.parentElement ? [...img.parentElement.querySelectorAll('img')].length : 0,
position: getComputedStyle(img).position,
zIndex: getComputedStyle(img).zIndex
})),
backgroundImages: [...document.querySelectorAll('*')].filter(el => {
const bg = getComputedStyle(el).backgroundImage;
return bg && bg !== 'none';
}).map(el => ({
url: getComputedStyle(el).backgroundImage,
element: el.tagName + '.' + el.className?.split(' ')[0]
}))
}
Identifying Layered Compositions vs. Foreground Overlays
The classification logic distinguishes between layered background images and overlay images by analyzing the DOM relationships captured in the discovery phase:
- Layered backgrounds are identified when a container element reports a
backgroundImageproperty and hosts one or more<img>children (indicated bysiblings > 0). This signals a composite visual stack where a CSS background works in conjunction with foreground imagery. - Overlay images are
<img>entries whosez-indexorpositionvalues (captured viagetComputedStyle) place them visually above the background layer of their parent container.
This strict separation prevents the common error of flattening a multi-layer composition into a single rasterized asset.
Downloading and Organizing Extracted Assets
Following discovery, a Node.js helper script (typically scripts/download-assets.mjs) consumes the JSON payload and establishes a predictable directory structure under public/images/. The script normalizes relative URLs, resolves absolute paths, and applies role-based naming conventions such as bg-hero.webp for backgrounds and overlay-logo.png for foreground elements.
import { promises as fs } from 'node:fs';
import path from 'node:path';
import https from 'node:https';
import http from 'node:http';
async function download(url, dest) {
const client = url.startsWith('https') ? https : http;
await new Promise((resolve, reject) => {
client.get(url, res => {
if (res.statusCode !== 200) return reject(new Error(`Failed ${url}`));
const file = fs.createWriteStream(dest);
res.pipe(file);
file.on('finish', () => file.close(resolve));
}).on('error', reject);
});
}
async function run() {
const raw = await fs.readFile('assets.json', 'utf-8');
const { images, backgroundImages } = JSON.parse(raw);
// Process standard image elements
for (const img of images) {
const url = new URL(img.src);
const out = path.join('public', 'images', path.basename(url.pathname));
await download(url.href, out);
}
// Process CSS background images (strip url() wrapper)
for (const bg of backgroundImages) {
const match = /url\(["']?(.*?)["']?\)/.exec(bg.url);
if (!match) continue;
const url = new URL(match[1], 'https://example.com'); // Base URL resolved in practice
const out = path.join('public', 'images', 'bg-' + path.basename(url.pathname));
await download(url.href, out);
}
}
run().catch(console.error);
The script preserves the hierarchical relationship between background containers and their overlay children, ensuring that the generated file paths reflect the layering semantics discovered in the browser.
Integrating Assets into Component Specifications
Extracted assets are formally declared in component specification files located at docs/research/components/*.spec.md. These specifications explicitly map each asset to its intended rendering context:
## Assets
- **Background image**: `public/images/hero-bg.webp` (applied via CSS `background-image: url('/images/hero-bg.webp')`)
- **Overlay image**: `public/images/logo-overlay.png` (rendered as `<Image src="/images/logo-overlay.png" alt="Logo" />`)
This documentation step guarantees that builder agents receive precise instructions for reconstructing the original layered composition, maintaining the visual separation between background textures and foreground graphics as implemented in the source web page.
Summary
- Discovery occurs in-browser via the JavaScript payload defined in
.github/skills/clone-website/SKILL.md, which captures both<img>tags and computedbackground-imagestyles alongside positioning metadata. - Classification relies on DOM hierarchy; containers with both CSS backgrounds and child
<img>elements are flagged as layered compositions, while positioned images with elevated z-index are marked as overlays. - Organization follows role-based naming in
public/images/, with backgrounds and overlays stored according to their visual function rather than arbitrary categorization. - Component specs formalize the separation by explicitly listing background URLs and overlay paths in
docs/research/components/*.spec.md, enabling pixel-perfect replication in generated React components.
Frequently Asked Questions
How does the AI Website Cloner Template distinguish between layered backgrounds and overlay images?
The template analyzes the DOM relationships captured during asset discovery. When a container element has a non-none backgroundImage computed style and simultaneously contains one or more <img> child elements (indicated by a siblings count greater than zero), the system identifies this as a layered background composition. Conversely, <img> elements with position values of absolute or fixed and elevated z-index values are classified as overlay images that sit atop the background layer.
Where is the image extraction logic defined in the repository?
The core discovery logic is embedded in .github/skills/clone-website/SKILL.md at lines 191–225. This file contains the browser automation script that enumerates visual assets, extracts computed styles, and generates the JSON payload used in subsequent processing steps. The download and organization phase is typically implemented in a helper script such as scripts/download-assets.mjs.
What naming conventions are used for extracted image assets?
The Node.js download helper applies role-based prefixes to distinguish asset types. Background images are typically prefixed with bg- (e.g., bg-hero.webp), while overlay images retain their original descriptive names or receive overlay- prefixes (e.g., overlay-logo.png). This convention ensures that designers and build agents can immediately identify the intended layering context of each file stored in public/images/.
How are extracted assets referenced in the final generated components?
Each asset is formally documented in component specification files at docs/research/components/*.spec.md. These specifications list background image URLs for CSS application and overlay image paths for component import statements. The explicit separation in the spec files ensures that React components render backgrounds via CSS properties while overlay images are imported as <Image> or <img> elements, preserving the original visual stacking order.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →