DEV Community

zongkai sun
zongkai sun

Posted on

Rendering 24 Shareable Images a Day With HTML, CSS and Playwright

Rendering 24 Shareable Images a Day With HTML, CSS and Playwright

I'm Xiaosuanshi (小算师) — a free site that serves daily horoscopes for all 12 Western zodiac signs and 12 Chinese zodiac animals, fully automated. This is part of my "building in public" series where I open up the pipeline instead of just the product.

The render pipeline

Every morning this site produces 24 pin images (12 zodiac signs + 12 Chinese zodiac animals) before any social post goes out. Instead of a canvas library or an image generator, each pin is just a static HTML template — 1000x1500, styled with CSS:

/* pinGenerator.js — 每张 Pin 就是一个 1000x1500 的 HTML 模板 */
body {
  width: 1000px; height: 1500px; overflow: hidden;
  background: linear-gradient(160deg, #3a0d0d, #d84343);
  font-family: 'DejaVu Sans', sans-serif;
  color: #fff; display: flex; flex-direction: column;
}
.title { font-size: 88px; font-weight: 800; }
.rule  { width: 220px; height: 5px; background: #FFD166; }
Enter fullscreen mode Exit fullscreen mode

Why HTML over canvas? Three practical reasons:

  • Fonts and emoji render exactly like the real site (no bitmap font mismatch),
  • Gradients, shadows and Chinese glyphs are handled by the browser engine for free,
  • Every template is testable in a normal browser before you screenshot it. Then a headless Chromium takes a screenshot at 2x device scale, so the output is a crisp 2000x3000 raster:
// 渲染交给 Playwright 无头 Chromium,一行截图
const { chromium } = require('playwright');
const page = await browser.newPage({
  viewport: { width: 1000, height: 1500, deviceScaleFactor: 2 },
});
await page.setContent(html, { waitUntil: 'networkidle' });
await page.screenshot({ path: file, type: 'png' });
Enter fullscreen mode Exit fullscreen mode

All 24 PNGs go into a folder with a manifest.json that lists title, description, link and file for each pin. Publishing platforms only ever read that manifest — which is what makes the whole system composable: add a platform, and it just consumes the same manifest.

Today's reading

Year of the Horse — Wednesday, September 16, 2026 (Chinese zodiac animal)
Horses, today is a day for adventure. Embrace new experiences.
Love

Your energy will be infectious in your relationship. Have fun together.
Career

Your adaptability will serve you well in your career. Be flexible.
Lucky number: 5

Full reading: daily horoscope

One post a day from this project. All content is AI-generated for entertainment. Follow if you build in public too.

Top comments (0)