How to Render a Pricing Table as an Image

Render a pricing or comparison table as a PNG. Useful for marketing emails, sales decks and competitor research dashboards.

HTML Content

<div class="pricing-table">
    <div class="plan-header">
        <div class="plan-cell"></div>
        <div class="plan-cell">Basic</div>
        <div class="plan-cell">Pro</div>
        <div class="plan-cell">Enterprise</div>
    </div>
    
    <div class="price-row">
        <div class="plan-cell">Monthly Price</div>
        <div class="plan-cell">$9.99</div>
        <div class="plan-cell highlight">$19.99</div>
        <div class="plan-cell">$49.99</div>
    </div>
    
    <div class="feature-row">
        <div class="plan-cell">API Calls</div>
        <div class="plan-cell">1,000</div>
        <div class="plan-cell">10,000</div>
        <div class="plan-cell">Unlimited</div>
    </div>
    
    <div class="feature-row">
        <div class="plan-cell">Custom Domain</div>
        <div class="plan-cell">
            <span class="no">✕</span>
        </div>
        <div class="plan-cell">
            <span class="yes">✓</span>
        </div>
        <div class="plan-cell">
            <span class="yes">✓</span>
        </div>
    </div>
    
    <div class="feature-row">
        <div class="plan-cell">Team Members</div>
        <div class="plan-cell">1</div>
        <div class="plan-cell">5</div>
        <div class="plan-cell">Unlimited</div>
    </div>
    
    <div class="feature-row">
        <div class="plan-cell">Priority Support</div>
        <div class="plan-cell">
            <span class="no">✕</span>
        </div>
        <div class="plan-cell">
            <span class="yes">✓</span>
        </div>
        <div class="plan-cell">
            <span class="yes">✓</span>
        </div>
    </div>
    
    <div class="feature-row">
        <div class="plan-cell">SLA</div>
        <div class="plan-cell">-</div>
        <div class="plan-cell">99.9%</div>
        <div class="plan-cell">99.99%</div>
    </div>
</div>

CSS Styles

body {
    margin: 0;
    padding: 24px;
    background: white;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.pricing-table {
    width: 800px;
    background: white;
    border-radius: 12px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}

.plan-header {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    background: #f8fafc;
    border-bottom: 2px solid #e2e8f0;
}

.plan-header .plan-cell {
    padding: 24px;
    font-weight: 600;
    font-size: 18px;
    color: #1e293b;
    text-align: center;
}

.plan-header .plan-cell:first-child {
    text-align: left;
}

.price-row, .feature-row {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    border-bottom: 1px solid #e2e8f0;
}

.plan-cell {
    padding: 16px 24px;
    color: #475569;
}

.price-row .plan-cell {
    font-size: 24px;
    font-weight: 600;
    color: #1e293b;
}

.price-row .plan-cell:first-child {
    font-size: 16px;
    font-weight: normal;
    color: #475569;
}

.highlight {
    background: #eff6ff;
    position: relative;
}

.highlight::after {
    content: "Popular";
    position: absolute;
    top: -12px;
    left: 50%;
    transform: translateX(-50%);
    background: #3b82f6;
    color: white;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 500;
}

.yes {
    color: #22c55e;
    font-size: 20px;
}

.no {
    color: #ef4444;
    font-size: 20px;
}

.plan-cell:not(:first-child) {
    text-align: center;
}

API Request

POST https://app.html2img.com/api/html
{
    "html": "<div class=\"pricing-table\"><div class=\"plan-header\"><div class=\"plan-cell\"></div><div class=\"plan-cell\">Basic</div><div class=\"plan-cell\">Pro</div><div class=\"plan-cell\">Enterprise</div></div><div class=\"price-row\"><div class=\"plan-cell\">Monthly Price</div><div class=\"plan-cell\">$9.99</div><div class=\"plan-cell highlight\">$19.99</div><div class=\"plan-cell\">$49.99</div></div><div class=\"feature-row\"><div class=\"plan-cell\">API Calls</div><div class=\"plan-cell\">1,000</div><div class=\"plan-cell\">10,000</div><div class=\"plan-cell\">Unlimited</div></div><div class=\"feature-row\"><div class=\"plan-cell\">Custom Domain</div><div class=\"plan-cell\"><span class=\"no\">✕</span></div><div class=\"plan-cell\"><span class=\"yes\">✓</span></div><div class=\"plan-cell\"><span class=\"yes\">✓</span></div></div><div class=\"feature-row\"><div class=\"plan-cell\">Team Members</div><div class=\"plan-cell\">1</div><div class=\"plan-cell\">5</div><div class=\"plan-cell\">Unlimited</div></div><div class=\"feature-row\"><div class=\"plan-cell\">Priority Support</div><div class=\"plan-cell\"><span class=\"no\">✕</span></div><div class=\"plan-cell\"><span class=\"yes\">✓</span></div><div class=\"plan-cell\"><span class=\"yes\">✓</span></div></div><div class=\"feature-row\"><div class=\"plan-cell\">SLA</div><div class=\"plan-cell\">-</div><div class=\"plan-cell\">99.9%</div><div class=\"plan-cell\">99.99%</div></div></div>",
    "width": 848,
    "height": 475,
    "css": "body{margin:0;padding:24px;background:white;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}.pricing-table{width:800px;background:white;border-radius:12px;box-shadow:0 4px 24px rgba(0,0,0,0.08);overflow:hidden}.plan-header{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;background:#f8fafc;border-bottom:2px solid #e2e8f0}.plan-header .plan-cell{padding:24px;font-weight:600;font-size:18px;color:#1e293b;text-align:center}.plan-header .plan-cell:first-child{text-align:left}.price-row,.feature-row{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;border-bottom:1px solid #e2e8f0}.plan-cell{padding:16px 24px;color:#475569}.price-row .plan-cell{font-size:24px;font-weight:600;color:#1e293b}.price-row .plan-cell:first-child{font-size:16px;font-weight:normal;color:#475569}.highlight{background:#eff6ff;position:relative}.highlight::after{content:\"Popular\";position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:#3b82f6;color:white;padding:4px 12px;border-radius:12px;font-size:12px;font-weight:500}.yes{color:#22c55e;font-size:20px}.no{color:#ef4444;font-size:20px}.plan-cell:not(:first-child){text-align:center}"
}
Pricing Table Example

Customize the pricing tiers, features, and styling to match your product offering.

How it Works

  1. CSS Grid for perfect column alignment
  2. Responsive design with proper spacing
  3. Highlighted “Popular” plan with badge
  4. Clear visual indicators for feature availability
  5. Professional typography and color scheme

Adjust the height parameter if adding more features so all content is captured.

Code in other languages

Node.js

const response = await fetch('https://app.html2img.com/api/html', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.HTML2IMG_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ html: pricingHtml, css: pricingCss, width: 1200, height: 800 }),
});
const { url } = await response.json();

Python

import os, requests
response = requests.post(
    'https://app.html2img.com/api/html',
    headers={'X-API-Key': os.environ['HTML2IMG_API_KEY']},
    json={'html': pricing_html, 'css': pricing_css, 'width': 1200, 'height': 800},
)
url = response.json()['url']

PHP

$ch = curl_init('https://app.html2img.com/api/html');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('HTML2IMG_API_KEY'), 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode(['html' => $pricingHtml, 'css' => $pricingCss, 'width' => 1200, 'height' => 800]),
]);
$url = json_decode(curl_exec($ch), true)['url'];

Common pitfalls

  • Currency formatting drifts. Pre-format prices for the buyer’s locale before sending. The renderer does not localize.
  • Plan column gets squashed. Use CSS Grid with explicit column widths rather than flex with flex: 1.
  • Feature lists overflow. Set fullpage to true when feature lists may grow beyond the configured height.

See also