AI for HTML and CSS: layout from a description or a screenshot

How to get a model to write markup without junk divs and broken responsiveness: prompt, mockup screenshot input, a Python script and result checks.

5 min · · development · models

A neural network for HTML code usually copes with typical layouts: cards, headers, forms, landing pages. Trouble starts with details: needless nested div elements, fixed pixels instead of responsive units, invented class names that do not exist in your project. Below: how to describe the task, how to hand the model a mockup screenshot, how to check the result automatically, and what it costs.

What to ask for: a description or a screenshot

There are two working inputs, and they solve different problems.

A text description fits when the structure is simple or you already have a design system. You list the blocks, behaviour and constraints, the model assembles the markup. You can start with a cheap text model for this.

A mockup screenshot is for when the design is already drawn. A model that accepts images sees block placement, proportions, heading hierarchy and approximate colours. In the Zukko model table, images are accepted by, for example, claude-sonnet-5-5, claude-opus-5-5, gpt-6.1-sol and deepseek-v4-pro. deepseek-v4.1-flash and glm-5.3-flash do not accept images, so they only work from a text description. For the current list and capabilities, call GET https://api.zukko.pro/v1/models or open the Models page in the dashboard.

The best combination is a screenshot plus a short text with constraints. The screenshot answers "what does it look like", the text answers "how should it be built".

A prompt that produces clean markup

A model follows what you explicitly forbid and allow. A working template:

bash
Build the block shown in the mockup image.

Requirements:
- Semantic tags: header, main, section, nav, footer, button instead of div where appropriate.
- One index.html file with a <style> block. No frameworks and no external fonts.
- Mobile-first: base styles for 360px, then min-width media queries.
- Sizes in rem and %, colours and spacing as CSS variables in :root.
- Give images alt and width/height so the layout does not jump.
- Name classes with BEM: block__element--modifier.
- Do not add JavaScript unless it is needed.
- Return only the code, as a single code block tagged html.

Every line closes a typical problem. Without "mobile-first" you get a desktop grid with one media query for phones. Without "code only" half a page of explanations arrives in the answer, and you have to strip it with a script.

If your project has its own classes, attach a fragment of existing markup and write "use classes from here, do not invent new ones". That way there are fewer made-up names.

A script: mockup in, file out

A Python example with the official openai SDK. The address for the OpenAI format is https://api.zukko.pro/v1:

bash
import base64, re, sys
from openai import OpenAI

client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")

PROMPT = open("prompt.txt", encoding="utf-8").read()
FENCE = "`" * 3  # code fence in the model reply

def layout_from_screenshot(path: str, model: str = "claude-sonnet-5-5") -> str:
    with open(path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode()
    resp = client.chat.completions.create(
        model=model,
        max_tokens=6000,

The usage line is there so you can see the real token count: an image takes tokens by the rules of the specific model, so an exact figure cannot be named in advance. Request parameters are described in the chat completions documentation. If the model returns an error on image upload, see the article on image size and format limits.

Responsiveness: what to check by hand and what automatically

Generated responsiveness most often breaks in three places:

  1. Horizontal scroll on a narrow screen. Cause: a fixed pixel width on a table, image or flex container without flex-wrap. Check: open the page in DevTools device mode at 360px and try scrolling right.
  2. Text overlapping text. Large headings without clamp() or a media query. Ask the model to set sizes with clamp(min, fluid, max).
  3. Stretched images. Missing max-width: 100% and height: auto.

A good trick is a second pass. Send the model the finished code and the list of problems you found: "fix only what is listed, leave the rest". It is cheaper and more reliable than asking for a full rewrite.

Automatic checks: validator and linter

A model can produce invalid HTML, and the browser will quietly "repair" it, so you notice nothing until an odd bug in another browser. Add a check to your script:

  • The W3C validator (Nu Html Checker). Catches tag nesting, unclosed elements, wrong attributes. There is an online version and a command-line one; check the validator's documentation for exact launch options.
  • A CSS linter (for example, stylelint). Catches property typos and duplicates. Configure the rules for your project.
  • An accessibility check. At least one run with something like the browser's built-in Lighthouse panel: contrast, form field labels, alt on images.

If the validator finds errors, send its text back to the model together with the code. One or two iterations are often enough.

What it costs

Calculated at Zukko prices on 18 October 2026. Assumption for the example: the input is a screenshot plus prompt totalling 2,500 tokens (read the real number from usage), and the output is a 3,000-token page.

Formula: input × input price + output × output price.

ModelCalculationCost per page
claude-sonnet-5-52,500 × $0.4 / 1M + 3,000 × $2 / 1M = $0.001 + $0.006$0.007
claude-opus-5-52,500 × $0.8 / 1M + 3,000 × $4 / 1M = $0.002 + $0.012$0.014

A text-only request without an image to deepseek-v4.1-flash (600 input tokens, 3,000 output): 600 × $0.013 / 1M + 3,000 × $0.038 / 1M ≈ $0.00012. That is for cases where a description is enough and there is no mockup.

Even with two or three correction rounds, a page layout costs pennies; the main cost here is your time spent reviewing. If you run many requests in a row, follow the tips in how to cut token usage.

Pick a model by trying it on two or three of your own mockups: nobody can predict in advance which one handles your style best. Create a key in the dashboard; top-up is available via SBP, MasterCard or crypto.

FAQ

Which neural network is best for HTML and CSS?

There is no universal answer. Compare by price, context size and strength index from the model table, and test two or three models on the same mockup. If you need a screenshot as input, choose only models that accept images.

Can I get layout from text alone, without a screenshot?

Yes. Describe the blocks, their order, mobile behaviour and constraints (no frameworks, BEM, CSS variables). The look will be less predictable, but the request is cheaper and models without image support will do.

How do I avoid junk markup?

Explicitly forbid the extras: meaningless nested div elements, inline styles, external libraries. Require semantic tags and run the result through a validator. If you have project classes, show them in the request.

Do I still need to check the code after the model?

Yes. Open the page at 360px, run the validator and test keyboard navigation. A model can confidently produce markup that fails validation or breaks at unusual widths.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

AI for HTML code: layout from a screenshot · Zukko