HTML Email Button Generator

A button that works in Outlook too: table markup with VML behind a conditional comment, because Outlook renders through Word and ignores padding on a link.

Enable JavaScript to customise; default output below.

Say what happens next. "Click here" tells a screen reader user nothing, and it tells everyone else nothing either.

Absolute and https. A relative link in an email has nothing to be relative to.

Hex only: the Outlook fallback is VML and VML wants a hex value.

VML needs a fixed size, so the Outlook version uses this.

44 or more. Below that it is hard to hit on a phone.

Outlook squares the corners whatever this is: VML rounding is not worth the markup.

16 or more. iOS zooms text under 13px and the layout goes with it.

Alignment
Live preview email-button.html
<!--
	Email button. The table is not nostalgia: Outlook on Windows renders through
	Word, which ignores padding on an <a>, so a styled link collapses to plain
	text there. The cell provides the box and the VML behind the conditional
	comment provides it for Outlook.
-->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" align="center" style="margin:0 auto;">
	<tr>
		<td class="bwp-button-cell" align="center" bgcolor="#1e56ec" style="border-radius:6px;">
			<!--[if mso]>
			VML for Outlook 2007 to 2019: a fixed-size rectangle with the text
			centred in it. Outlook ignores the <a> that follows and everything
			else ignores this.
			<![endif]-->
			<!--[if mso]>
			<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="https://swiftplugins.pro/changelog" style="height:48px;v-text-anchor:middle;width:260px;" arcsize="0%" stroke="f" fillcolor="#1e56ec">
				<w:anchorlock/>
				<center style="color:#ffffff;font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:bold;">Read the release notes</center>
			</v:roundrect>
			<![endif]-->
			<!--[if !mso]><!-- -->
			<a class="bwp-button" href="https://swiftplugins.pro/changelog" style="display:inline-block;width:260px;line-height:48px;background:#1e56ec;color:#ffffff;font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:bold;text-align:center;text-decoration:none;border-radius:6px;mso-hide:all;">Read the release notes</a>
			<!--<![endif]-->
		</td>
	</tr>
</table>

<style>
/*
	Gmail's app and Apple Mail honour this; several clients strip <style>
	entirely, which is why every rule above is inline and this is only an
	improvement rather than a requirement.
*/
@media screen and (max-width: 480px) {
	.bwp-button {
		width: 100% !important;
		max-width: 100% !important;
	}

	.bwp-button-cell {
		display: block !important;
		width: 100% !important;
	}
}
</style>

Output is valid and updates as you type.

A styled <a> is a button on the web and plain blue text in Outlook on Windows. Outlook renders email through Word, and Word ignores padding on an inline element, so the box collapses and the button disappears.

The way round it is the one the email industry settled on years ago: a table cell provides the box for everything else, and a VML rectangle inside a conditional comment provides it for Outlook. It is ugly markup and it is the markup that works.

How to use

  1. Set the text and an absolute https link.
  2. Set the colours in hex. VML needs hex, so named colours are out.
  3. Set a width and a height. VML needs a fixed size and takes both from these.
  4. Paste it into your email template where the button goes.

Example

<table role="presentation" cellpadding="0" cellspacing="0" border="0" align="center" style="margin:0 auto;">
	<tr>
		<td class="bwp-button-cell" align="center" bgcolor="#1e56ec" style="border-radius:6px;">
			<!--[if mso]>
			<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="https://swiftplugins.pro/changelog" style="height:48px;v-text-anchor:middle;width:260px;" arcsize="0%" stroke="f" fillcolor="#1e56ec">
				<w:anchorlock/>
				<center style="color:#ffffff;font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:bold;">Read the release notes</center>
			</v:roundrect>
			<![endif]-->
			<!--[if !mso]><!-- -->
			<a class="bwp-button" href="https://swiftplugins.pro/changelog" style="display:inline-block;width:260px;line-height:48px;background:#1e56ec;color:#ffffff;font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:bold;text-align:center;text-decoration:none;border-radius:6px;mso-hide:all;">Read the release notes</a>
			<!--<![endif]-->
		</td>
	</tr>
</table>

Outlook reads the VML and ignores the anchor; everything else ignores the VML and reads the anchor. The role="presentation" on the table stops a screen reader announcing a one-cell data table.

Pitfalls

Outlook on Windows is Word. Not a browser. It ignores padding on inline elements, background images, flex, grid, most pseudo-elements and anything modern. It also still has most of the corporate market.

Outlook squares the corners. VML rounding exists and it is more markup than the effect is worth. The generated code uses arcsize="0%" and accepts square corners there.

Links must be absolute and https. There is no page for a relative link to be relative to, and some clients refuse plain http outright.

Inline every style. Several clients strip <style> blocks entirely, Gmail among them in some contexts, so the media query here is an improvement rather than a mechanism. If the button only works with the <style> block, it does not work.

44 pixels minimum. Both Apple and Google put the minimum comfortable tap target at around 44 to 48 pixels. A 32-pixel-high button on a phone is a missed tap and a lost click.

Do not put the label in an image. Images are blocked by default in a lot of clients, and an image-only button is an invisible button. Text plus a background colour is always visible.

Say what happens. “Click here” is announced with no context by a screen reader and gives a skimming reader nothing. “Read the release notes” is the same length and does the job.

Test in the client, not in a browser. A browser preview tells you nothing about Outlook. Litmus and Email on Acid exist for this; sending it to yourself in the actual client is free.

Compatibility

Everything runs in the browser: nothing is uploaded and nothing is stored.

The VML block works in Outlook 2007 through 2019 and the Windows desktop client, which is what the conditional comment targets. Outlook on macOS uses WebKit and reads the ordinary anchor. Outlook.com in a browser reads the anchor. New Outlook for Windows, the one rolling out to replace the desktop client, also uses a web engine, so the VML matters less over time and still matters now.

mso-hide:all on the anchor keeps Outlook from rendering both the VML and the link. The downlevel-revealed comment around the anchor is the standard pattern for exactly this: the first comment closes itself so non-Outlook clients see the content.

role="presentation" on a layout table is what stops assistive technology announcing “table with one row and one column”. It costs nothing and it is the difference between a button and a puzzle.

Text in the output is escaped for HTML, so a label containing an ampersand or angle brackets comes out as characters rather than as markup, in both the VML and the anchor.

Frequently asked questions

Do I still need VML in 2026?
If your list includes corporate Windows users, yes. The new Outlook uses a web engine and the old desktop client is still widely deployed inside companies. The VML is twelve lines and it is inside a comment, so it costs nothing anywhere else.
Why a table for one button?
Because the table cell is the only box Outlook will honour. Everything else about the table is an artefact of that, which is why it carries role="presentation".
Can I use a border radius?
Everywhere except Outlook on Windows, where the corners are square. That is a visual difference rather than a broken button, and most senders accept it.
What about dark mode?
Some clients invert colours, some respect prefers-color-scheme, and Outlook.com rewrites them by its own rules. A mid-saturation background with white text survives inversion better than black on white does. Test the specific pair you are using.
Should the button be full width on mobile?
It reads well and it is a media query, so it depends on the client honouring one. The generated CSS includes it as an enhancement; the fixed width in the inline style is what every client gets.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.