Skip to main content

Creating Rounded Buttons in Outlook with VML roundrect

Fix square email buttons in Outlook 2007-2021 with v:roundrect, arcsize, fillcolor, and w:anchorlock wrapped in MSO conditionals and hidden from other clients.

Rounded call-to-action buttons render with hard square corners in Outlook 2007 through 2021 on Windows because the Word engine ignores border-radius entirely. The fix is a <v:roundrect> with an arcsize percentage, wrapped in an <!--[if mso]> conditional and hidden from every other client, so Outlook draws the rounded shape while modern clients keep the CSS button. This deep-dive is scoped to Windows Outlook and assumes the dual-path foundation from Bulletproof email buttons.

VML roundrect versus a square Outlook button Without VML the Word engine renders square corners; v:roundrect with arcsize restores the rounded shape. Square vs VML roundrect Word engine, no fix Confirm border-radius ignored v:roundrect arcsize Confirm arcsize draws the radius
Outlook ignores border-radius and draws square corners; a v:roundrect with an arcsize percentage restores the rounded button.

Root Cause: border-radius Is a No-Op in the Word Engine

Outlook 2007-2021 on Windows parses HTML through Microsoft Word's layout engine, which has no rounded-rectangle primitive in CSS. A border-radius:10px declaration is read and discarded, so the button's background box renders with 90-degree corners no matter what value you set. There is no CSS property — vendor-prefixed or otherwise — that the Word engine maps to rounded corners. The only rounded-shape primitive it understands is VML's <v:roundrect>, the same vector format Office uses internally. So you draw the rounded button as a VML shape for Outlook and reveal a normal CSS button to everyone else.

Exact Fix: A roundrect Hidden From Non-Outlook Clients

<!--[if mso]>
<!-- Outlook 2007-2021: Word engine ignores border-radius; draw the rounded shape in VML -->
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml"
             xmlns:w="urn:schemas-microsoft-com:office:word"
             href="https://example.com/activate"   /* the link target for the whole shape */
             style="height:48px;width:240px;v-text-anchor:middle;"  /* v-text-anchor:middle centers label vertically */
             arcsize="21%"          /* % of the SHORTER side: 21% of 48px ≈ 10px corner radius */
             fillcolor="#A53860"    /* button background; Outlook has no CSS background here */
             strokecolor="#A53860"  /* border color; match fill for a borderless look */
             stroke="false">        /* false = no visible 1px outline */
  <w:anchorlock/>                   <!-- makes the ENTIRE shape the click target, not just glyphs -->
  <center style="color:#ffffff;font-family:Arial,sans-serif;font-size:16px;font-weight:bold;">
    Activate Account
  </center>
</v:roundrect>
<![endif]-->

<!--[if !mso]><!-->
<!-- Apple Mail, iOS Mail, Gmail, Samsung: standard CSS button with real border-radius -->
<a href="https://example.com/activate"
   style="display:block;width:240px;background-color:#A53860;color:#ffffff;
          font-family:Arial,sans-serif;font-size:16px;font-weight:bold;
          line-height:48px;text-align:center;text-decoration:none;border-radius:10px;
          -webkit-text-size-adjust:none;">  <!-- iOS Mail: prevent auto text resizing -->
  Activate Account
</a>
<!--<![endif]-->

Every attribute explained:

  • arcsize — a percentage of the button's shorter dimension, not a pixel value. To match a CSS border-radius:Npx, compute N / shorter_side: a 10px radius on a 48px-tall button is 10/48 ≈ 21%. A fully pill-shaped button uses arcsize="50%".
  • v-text-anchor:middle — vertically centers the <center> label inside the shape; without it the text sits at the top.
  • <w:anchorlock/> — locks the text and makes the whole roundrect a single hyperlink. Omit it and Outlook makes only the text clickable, reproducing the original collapse problem.
  • fillcolor / strokecolor / stroke="false" — the Word engine ignores CSS background-color and border on the shape, so color is set through these VML attributes; stroke="false" removes the default outline.
  • <center> tag — required for the VML label; it both centers horizontally and carries the font styling Outlook applies to the text.
  • <!--[if !mso]><!--> ... <!--<![endif]--> — the downlevel-revealed comment that hides the CSS anchor from Outlook (which sees it as a comment) while showing it to all other clients.

Variant: Gradient, Transparent, and Outlook 365 Builds

Gradient buttons. The Word engine cannot render a CSS gradient, but VML can. Replace the flat fillcolor with a nested <v:fill>:

<v:roundrect ... arcsize="21%" stroke="false">
  <!-- Outlook 2007-2021: VML gradient since CSS linear-gradient is ignored -->
  <v:fill type="gradient" color="#A53860" color2="#DA627D" angle="90"/>
  <w:anchorlock/>
  <center style="color:#fff;font-family:Arial,sans-serif;font-size:16px;font-weight:bold;">Upgrade</center>
</v:roundrect>

Transparent / outline buttons. Set fillcolor to the email background color and give strokecolor a contrasting value with stroke="true" so only the outlined ring shows.

Outlook 365 build split. Outlook 2016 and 2019 are always Word-engine and require the roundrect. Outlook 365 is split: older Windows builds use the Word engine (take the VML branch), while newer WebView2/Edge-based builds read the CSS anchor and ignore VML. Because both branches coexist, you do not detect the build — keep the [if mso] roundrect and the [if !mso] CSS button aligned in color, size, and radius so either engine produces the same button.

Pipeline Integration

When the template passes through inline CSS automation, the inliner must leave the conditional comments and the VML attributes untouched. Configure Juice to preserve comments (or run the PostHTML MSO step before inlining) so neither the [if mso] roundrect nor the [if !mso] reveal comment is rewritten. After the build, grep the compiled HTML for v:roundrect and w:anchorlock to confirm survival, and send a real test message — some ESPs strip HTML comments in transit, which silently deletes one of the two branches and leaves you with either a square button or no button at all.

Validation Checklist

  • arcsize percentage computed from the radius and the shorter side (e.g. 21% for 10px on 48px).
  • <w:anchorlock/> present so the whole shape is clickable.
  • v-text-anchor:middle and a <center> label centering the text.
  • fillcolor/strokecolor set (not CSS background), with stroke="false" for borderless.
  • <!--[if !mso]><!--> reveal comment well-formed; no doubled button in Outlook.
  • VML namespaces (xmlns:v, xmlns:w) declared on the shape or <html>.
  • Conditional comments and VML attributes verified after inlining and after ESP transit.
  • Corners and color match the CSS button in Outlook 2016/2019/365, Apple Mail, iOS Mail, Gmail, Samsung Email.

The arcsize Math in Full

arcsize is the one VML attribute people consistently set wrong, because it is a percentage of the button's shorter side, not a pixel radius. The conversion is mechanical:

arcsize (%) = desired_radius_px / shorter_side_px

For a button that is taller than it is wide the shorter side is the width; for the usual wide CTA the shorter side is the height. Worked examples for a 48px-tall button:

Desired CSS border-radius Shorter side arcsize value
6px (subtle) 48px 13%
8px 48px 17%
10px (common) 48px 21%
12px 48px 25%
24px (very round) 48px 50%
Full pill 48px 50% (caps here)

Two facts that trip people up. First, arcsize caps at 50% — once the radius reaches half the shorter side the shape is a full pill, and any higher value is clamped, so you cannot over-round. Second, the percentage tracks the height, not the width, on a wide button, so a 48px button and a 60px button with the same visual radius need different arcsize values: 10px is 21% on 48px but only 17% on 60px. When the height changes, recompute. To match a CSS border-radius:10px exactly, set the VML height and the CSS line-height to the same number, then derive arcsize from that shared height so both engines draw the same corner.

Variant: Gradient and Transparent Buttons, Expanded

Gradient fill. The Word engine ignores CSS linear-gradient, but VML draws gradients natively through <v:fill type="gradient">. The angle is measured in VML's coordinate convention (90 = top-to-bottom), so to mirror a CSS linear-gradient(to right, ...) you use angle="0", and for to bottom you use angle="90":

<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
             href="https://example.com/upgrade"
             style="height:48px;width:240px;v-text-anchor:middle;" arcsize="21%" stroke="false">
  <!-- Outlook 2007-2021: CSS linear-gradient is ignored; VML draws the gradient -->
  <v:fill type="gradient" color="#A53860" color2="#DA627D" angle="90"/>  <!-- 90 = top→bottom, matches CSS to-bottom -->
  <w:anchorlock/>
  <center style="color:#fff;font-family:Arial,sans-serif;font-size:16px;font-weight:bold;">Upgrade</center>
</v:roundrect>
<![endif]-->

In the [if !mso] branch, give the modern anchor the matching background-image:linear-gradient(...) plus a solid background-color fallback for Gmail webmail, which historically dropped gradients on some accounts.

Transparent / outline (ghost) button. A ghost button shows only an outlined ring over the email background. In VML, set fillcolor to the surrounding background color, enable the stroke, and give it a contrasting strokecolor and a strokeweight:

<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
             href="https://example.com/learn"
             style="height:46px;width:220px;v-text-anchor:middle;" arcsize="22%"
             fillcolor="#ffffff"        <!-- Outlook: match the email canvas so only the ring shows -->
             strokecolor="#A53860" strokeweight="2px" stroke="true">  <!-- visible 2px outline ring -->
  <w:anchorlock/>
  <center style="color:#A53860;font-family:Arial,sans-serif;font-size:16px;font-weight:bold;">Learn more</center>
</v:roundrect>
<![endif]-->

The catch: a true fillcolor="transparent" is unreliable in the Word engine, so ghost buttons over a photographic background image do not work in Outlook — VML cannot let the underlying image show through the roundrect. For a ghost button on a flat color, match fillcolor to that color; for one over an image, fall back to a solid-fill button in the Outlook branch only.

Outlook 365 vs Outlook 2016/2019, in Detail

Outlook 2016 and 2019 are unambiguous: every Windows build renders through the Word engine, so they always take the [if mso] VML branch and always need the roundrect. Outlook 365 is the moving target. It ships two rendering paths on Windows:

  • Word-engine 365 builds behave exactly like 2016/2019 — border-radius ignored, VML required. These follow the [if mso] branch.
  • WebView2 (Edge/Chromium) 365 builds, rolling out in the "new Outlook," read CSS border-radius directly and ignore VML entirely. These follow the [if !mso] branch.

You do not, and cannot reliably, detect which 365 build a recipient runs. The dual-path block resolves this automatically: the Word build picks up the roundrect, the WebView2 build picks up the CSS anchor, and as long as the two branches share color, width, height, and corner radius (arcsize derived from that height), both produce a visually identical button. The failure mode is letting the branches drift — a 10px CSS radius with a 13% arcsize gives a noticeably squarer button on Word-engine 365 than on WebView2 365 of the same inbox. Keep them in sync via a generated partial, as covered in the bulletproof buttons guide.

Deeper Pipeline Integration

Beyond preserving comments through the inliner, treat the VML branch as a build-time invariant you assert on, not a thing you eyeball:

  1. Author once. Generate the dual-path block from a partial so arcsize is computed from the shared height, never typed by hand.
  2. Inline with comment preservation. Run inline CSS automation configured to leave conditional comments and VML attributes opaque — with Juice keep comment preservation on; with PostHTML run the MSO step before inlining.
  3. Assert in CI. Add a grep step that fails the build if the compiled HTML is missing v:roundrect, w:anchorlock, or v-text-anchor:middle, or if an arcsize is present without a matching height — this catches a dropped branch before it reaches an ESP.
  4. Send a real test. Some ESPs strip HTML comments in transit, silently deleting one branch; only a real send through the ESP proves the comments survived end to end.
  5. Render-check both engines. Verify against a Word-engine Outlook and a WebView2 Outlook 365, not just one, since they take different branches of the same markup.

Validation Checklist (Extended)

  • arcsize recomputed from the actual height (not copied from a different-height button).
  • VML height equals the CSS line-height so both engines draw the same box.
  • Gradient buttons use <v:fill type="gradient"> with an angle matching the CSS direction.
  • Ghost buttons set fillcolor to the canvas color (not transparent) and stroke="true".
  • CI greps for v:roundrect, w:anchorlock, and a height/arcsize pairing.
  • Verified on a Word-engine Outlook and a WebView2 Outlook 365.

← Back to Bulletproof Email Buttons