Editable posters with HTML and CSS
2026-08-27 → 2026-08-29
A poster does not need to be created by powerpoint or illustration app. HTML + CSS can be a viable alternative, especially when working with AI.
Short version#
tl;dr: Don’t try to generate the whole poster. Find or generate a background image first, and then create a poster using HTML and CSS. You can use AI agent in each step and don’t have to know HTML and CSS—just specify what you want. However, also remember that this workflow can very easily create a low-quality AI slop.
Image generation#
Supply the image-capable model the following information:
- Intended dimensions
- Theme
- A (rough) color palette
- The information the design must contain and what must not appear (e.g., The exact words and existing logos that should be included)
- A background image (either a copyright free image or a generated image) that fits the theme and color scheme of the poster (rather than a finished poster).
Example prompt:
Create a text-free background for an 8.5 × 11-inch portrait poster.
Theme: [subject and visual metaphor]
Rough palette: [dominant colors and accent colors]
Leave quiet space for:
- [headline]
- [dates, venue, and other necessary information]
- [logos and QR code]
Composition: [where the visual focus and quiet space should sit]
Mood: [a few adjectives]
Do not include text, letters, numbers, logos, QR codes, or watermarks.
Avoid: [visual clichés or unwanted elements]
Keep the information out of the background#
Use a text-free background image. Put the headline, schedule, logos, and QR code in HTML so that factual corrections do not require regenerating artwork. A sample structure:
poster/
├── index.html
├── build.sh
├── assets/
│ ├── background.png
│ ├── organization-logo.png
│ └── qr-info.svg
├── poster.png
└── poster.pdf
Record the image prompt, asset sources, and logo-use notes in a README.
Fix the canvas#
.poster {
width: 816px;
height: 1056px;
}
@page {
size: letter portrait;
margin: 0;
}
@media print {
html, body {
width: 8.5in;
height: 11in;
}
}
Set the physical format first. Otherwise every spacing and alignment decision is tuned to the wrong shape.
Build both outputs#
Put the rendering commands in a build script (a similar script can be generated by AI agent):
#!/usr/bin/env bash
set -euo pipefail
poster_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
chrome_bin="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
poster_url="file://$poster_dir/index.html"
"$chrome_bin" \
--headless=new \
--hide-scrollbars \
--window-size=816,1056 \
--screenshot="$poster_dir/poster.png" \
"$poster_url"
"$chrome_bin" \
--headless=new \
--no-pdf-header-footer \
--print-to-pdf="$poster_dir/poster.pdf" \
"$poster_url"
Save it as poster/build.sh, then run:
chmod +x poster/build.sh
./poster/build.sh
This minimal version assumes Google Chrome on macOS. The @page rule in the HTML controls the PDF’s physical page size; --window-size controls the PNG dimensions.
A useful build script asks headless Chrome for a PNG and PDF, checks the PDF page size, renders the PDF back to an image, and decodes the QR code from both artifacts. It can also normalize PDF metadata with qpdf so an unchanged source produces an unchanged PDF.
To replace the QR destination and rebuild everything:
./poster/build.sh --qr 'https://FINAL-URL'
Do not stop after checking the source SVG. A QR code can be valid before layout and unreadable after scaling or PDF rendering. Decode what people will actually receive.
Set the layout system, then iterate#
Use CSS Grid or Flexbox for the overall structure. Define the main rows and columns, then group related elements such as sponsor logos and a QR code. Shared rules should control heights, gaps, and baselines; reserve per-element offsets for small optical corrections.
Once that system is in place, the rest is iteration. Render the poster and adjust alignment. Then tune element sizes and colors. Finish with small spacing and decorative tweaks, rebuilding after each pass.