siliconrelay.com

HTML5 ads

The HTML5 creative standard, one self-contained file, the clickTag clickthrough, and the sandbox your ad runs in.


Besides image banners and text ads, a campaign can run an HTML5 ad: a page-like creative built from HTML, CSS, and JavaScript that renders live in the browser. HTML5 ads can animate, respond to hover, and stay perfectly crisp on every screen, they are resolution-independent, so there's no separate Retina upload. They occupy the same slots as banners: your file names one standard size and competes for zones set up at that size.

Upload them in the same drop zone as your images. Drag images and .html files in together, in any mix. There's nothing to choose first: we read each file to see what it is.

The standard, in one paragraph

Your ad is one self-contained .html file, 512 KB or smaller, that makes no network requests. Every image, font, and script it uses is inlined in the file, that says what size it is, and that reads its clickthrough URL from the clickTag query parameter. That's the whole spec. Each rule is checked or enforced automatically, so an ad that follows them works the first time.

Say what size it is

An image tells us its size just by being an image. An .html file has no pixels to measure, so it has to say. Two ways, either is enough:

  1. A meta tag in the <head>, the convention Google Web Designer and DoubleClick Studio already export:

    <meta name="ad.size" content="width=300,height=250">
    
  2. The size in the filename, like banner-cannabis-300x250-dark.html.

If the file has both, the meta tag wins (it travels with the file, the name doesn't). If it has neither, or names a size we don't run, the upload is rejected with a message telling you exactly which file and how to mark it. The other files in the same drop still land.

Always give the plain 1× size. Because HTML5 ads are resolution-independent there is no doubled Retina size for them: a file marked 600x500 is a rejection, not a 2× 300×250. (That doubling rule applies to image banners only.)

One file, everything inlined

Upload exactly one .html file. There is no zip upload and no way for the ad to load assets from your server or a CDN. The browser itself blocks every external request when the ad serves (images, fonts, scripts, tracking pixels, everything).

  • Images go in as data: URIs (base64). Any build tool or online converter can inline them and keep them small, because the whole file must stay under 512 KB.
  • CSS and JavaScript go in <style> and <script> tags in the same file.
  • SVG and CSS animation are your friends here, being tiny, sharp at any resolution, and need no assets at all.
  • Avoid eval() / new Function(). The serving policy doesn't allow them, and a few animation libraries use them, but most (including GSAP) do not.

Why so strict? It's a trust guarantee that benefits you too: the file we review is exactly what every reader gets, nothing can be swapped after approval, and no third party can piggyback tracking on your media spend.

The clickthrough: clickTag

Clicks inside an HTML5 ad can't be tracked from the outside, so your ad handles its own clickthrough. When we serve your file we append the tracking URL as a query parameter, and your ad reads it:

<a id="cta" target="_blank" rel="noopener">Shop now</a>
<script>
  document.getElementById('cta').href =
    new URLSearchParams(location.search).get('clickTag');
</script>

Use it as the href of your ad's link (or in window.open). Don't hard-code your landing page URL. The clickTag URL is what records the click and then forwards the visitor to the landing page you set on the campaign, so a hard-coded link would cost you your click stats. An upload that never mentions clickTag is rejected at upload with a message saying exactly that.

The sandbox your ad runs in

HTML5 ads execute inside a locked-down frame on the publisher's page. Inside it, your ad cannot read cookies, use local storage, or see or touch the page around it, and the same is true for every other advertiser, which is why publishers can accept the format at all. Your clickthrough still opens normally: the landing page itself is not sandboxed in any way.

Practically: build the ad as a self-contained animation with a clear call to action. Anything that tries to fingerprint, store state, or phone home simply won't run, so don't spend your file budget on it.

A minimal working ad

A complete, valid 300×250 ad. Replace the middle with your design:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="ad.size" content="width=300,height=250">
  <style>
    body { margin: 0; width: 300px; height: 250px; overflow: hidden;
           font-family: system-ui, sans-serif; }
    a { display: flex; width: 100%; height: 100%; text-decoration: none;
        align-items: center; justify-content: center; background: #14532d;
        color: #fff; font-size: 20px; font-weight: 600; }
  </style>
</head>
<body>
  <a id="cta" target="_blank" rel="noopener">Your message here</a>
  <script>
    document.getElementById('cta').href =
      new URLSearchParams(location.search).get('clickTag');
  </script>
</body>
</html>

Exporting from an ad builder

Tools like Google Web Designer export a folder of files with a clickTag already wired and an <meta name="ad.size"> tag already in the head. Both carry over as-is, so an export needs no size marking from you. You'll need to flatten the export into a single file: inline the images as data: URIs and paste the CSS/JS into the HTML. Ask your tool for a "single file" or "inline assets" option, or run any HTML inliner over the export. If the result is over 512 KB, compress the images before inlining, which is nearly always where the weight is.

Before it goes live

HTML5 ads go through the same review as banners, and a campaign can't activate while its ad is pending or rejected. Once approved, your ad serves, bills, and reports exactly like a banner at the same size, a served impression is counted when the ad actually renders, see what counts as a served impression.