Skip to main content Home About the Design SystemRoadmap OverviewDesignersDevelopers OverviewColorGridIconographyInteractionsSpacingTypography Overview Global colorBox shadowTypographyBorderOpacitySpaceLengthIconBreakpointsMedia queries All elements Accordion Alert Announcement Audio player Avatar Back to top Badge Blockquote Breadcrumb Button Card Chip Code block Call to action Dialog Disclosure Footer Health index Icon Jump links Menu dropdown Navigation link Navigation (primary) Navigation (secondary) Navigation (vertical) Pagination PopoverPlanned Progress stepper Scheme toggle Site status Skeleton Skip link Spinner Statistic Subnavigation Surface Switch Table Tabs Tag Tile Timestamp Tooltip Video embed OverviewColor PalettesCustomizingDevelopers All PatternsAccordionCall to ActionCardFilterFormLink with iconLogo wallSearch barSticky bannerSticky cardTabsTagTile All Personalization PatternsAnnouncement FundamentalsAccessibility toolsAssistive technologiesCI/CDContentContributorsDesignDevelopmentManual testingResourcesScreen readers Design/code status Release notes Get support

Call to action

OverviewStyleGuidelinesCodeAccessibilityDemos
Call to actionAnalyticsBrickButtonColor Context With Lightdom CssColor ContextHref AttributeNo Cta JavascriptResizingRight To LeftVariantsCall to actionAnalyticsBrickButtonColor Context With Lightdom CssColor ContextHref AttributeNo Cta JavascriptResizingRight To LeftVariants

Call to action

import '@rhds/elements/rh-cta/rh-cta.js';
<rh-cta href="#">Call to Action</rh-cta>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <Cta href="#">Call to Action</Cta>
);

Analytics

rh-cta[variant="brick"] {
  /* for demo reviewer ergonomics, even though this is against style guidelines */
  width: auto;
}
json-viewer {
  --json-viewer-background: white;
  --json-viewer-boolean-color: #f76707;
  --json-viewer-color: black;
  --json-viewer-key-color: #f76707;
  --json-viewer-null-color: Light #e03131;
  --json-viewer-number-color: #0ca678;
  --json-viewer-string-color: #0c8599;
}
import '@rhds/elements/rh-cta/rh-cta.js';
import 'https://ga.jspm.io/npm:@power-elements/json-viewer@2.1.1/json-viewer.js';

customElements.define('slotted-link', class SlottedLinkElement extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' }).innerHTML = /* html */`
      <rh-cta><slot name="default"></slot></rh-cta>
      <rh-cta variant="primary"><slot name="primary"></slot></rh-cta>
      <rh-cta variant="secondary"><slot name="secondary"></slot></rh-cta>
      <rh-cta variant="brick" style="width:auto;"><slot name="brick"></slot></rh-cta>
    `;
  }
});

document.addEventListener('click', function(event) {
  const data = event.composedPath().reduceRight((acc, node) => {
    if (node instanceof HTMLElement) {
      for (const [datakey, value] of Object.entries(node.dataset)) {
        if (datakey.startsWith('analytics')) {
const key = datakey.replace(/^analytics(.)/, (_, m) => m.toLowerCase());
acc[key] = `${acc[key] ?? ''}|${value}`.replace(/^\|/,'');
        }
      }
    }
    return acc;
  }, {});
  if (data.linktype === 'cta') {
    document.querySelector('json-viewer').object = data;
  }
});
<p>In this demo, analytics events involving <code>&lt;rh-cta&gt;</code> elements are parsed by a
  document-level analytics event listener. Unlike <code>&lt;pfe-cta&gt;</code>, which implemented
  support for analytics internally, <code>&lt;rh-cta&gt;</code> users must implement their own
  analytics code, taking this demo as an example.</p>

<section data-analytics-category="simple">
  <h2>Simple Case: Light DOM</h2>
  <rh-cta data-analytics-linktype="cta" data-analytics-text="Default">
    <a href="#default">Default</a>
  </rh-cta>
  <rh-cta variant="primary" data-analytics-linktype="cta" data-analytics-text="Primary">
    <a href="#primary">Primary</a>
  </rh-cta>
  <rh-cta variant="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary">
    <a href="#secondary">Secondary</a>
  </rh-cta>
  <rh-cta variant="brick" data-analytics-linktype="cta" data-analytics-text="Brick">
    <a href="#brick">Brick</a>
  </rh-cta>

  <section data-analytics-category="href-attr">
    <h3>Using <code>href</code> attribute</h3>
    <rh-cta href="#default" data-analytics-linktype="cta" data-analytics-text="Default">Default</rh-cta>
    <rh-cta href="#primary" variant="primary" data-analytics-linktype="cta" data-analytics-text="Primary">Primary</rh-cta>
    <rh-cta href="#secondary" variant="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary">Secondary</rh-cta>
    <rh-cta href="#brick" variant="brick" data-analytics-linktype="cta" data-analytics-text="Brick">Brick</rh-cta>
  </section>
</section>

<section data-analytics-category="shadow">
  <h2>Advanced Case: Deep Shadow</h2>
  <shadow-root>
    <template shadowrootmode="open">
      <rh-cta data-analytics-linktype="cta" data-analytics-text="Default">
        <a href="#default">Default</a>
      </rh-cta>
      <rh-cta variant="primary" data-analytics-linktype="cta" data-analytics-text="Primary">
        <a href="#primary">Primary</a>
      </rh-cta>
      <rh-cta variant="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary">
        <a href="#secondary">Secondary</a>
      </rh-cta>
      <rh-cta variant="brick" style="width:auto;" data-analytics-linktype="cta" data-analytics-text="Brick">
        <a href="#brick">Brick</a>
      </rh-cta>
    </template>
  </shadow-root>
  <h3>Using <code>href</code> attribute</h3>
  <shadow-root data-analytics-category="href-attr">
    <template shadowrootmode="open">
      <rh-cta href="#default" data-analytics-linktype="cta" data-analytics-text="Default">Default</rh-cta>
      <rh-cta href="#primary" data-analytics-linktype="cta" data-analytics-text="Primary" variant="primary">Primary</rh-cta>
      <rh-cta href="#secondary" data-analytics-linktype="cta" data-analytics-text="Secondary" variant="secondary">Secondary</rh-cta>
      <rh-cta href="#brick" style="width:auto;" variant="brick" data-analytics-linktype="cta" data-analytics-text="Brick">Brick</rh-cta>
    </template>
  </shadow-root>
</section>

<section data-analytics-category="slotted">
  <h2>Complex Case: Slotted Link, Deep CTA</h2>
  <slotted-link>
    <a slot="default" data-analytics-linktype="cta" data-analytics-text="Default" href="#default">Default</a>
    <a slot="primary" data-analytics-linktype="cta" data-analytics-text="Primary" href="#primary">Primary</a>
    <a slot="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary" href="#secondary">Secondary</a>
    <a slot="brick" data-analytics-linktype="cta" data-analytics-text="Brick" href="#brick">Brick</a>
  </slotted-link>
</section>

<h2>Last CTA Analytics Event</h2>
<json-viewer>{}</json-viewer>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <p>
    In this demo, analytics events involving
    <code><rh-cta></code>
    elements are parsed by a
    document-level analytics event listener. Unlike
    <code><pfe-cta></code>
    , which implemented
    support for analytics internally,
    <code><rh-cta></code>
    users must implement their own
    analytics code, taking this demo as an example.
  </p>
  <section data-analytics-category="simple">
    <h2>Simple Case: Light DOM</h2>
    <Cta data-analytics-linktype="cta" data-analytics-text="Default"><a href="#default">Default</a></Cta>
    <Cta variant="primary" data-analytics-linktype="cta" data-analytics-text="Primary"><a href="#primary">Primary</a></Cta>
    <Cta variant="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary"><a href="#secondary">Secondary</a></Cta>
    <Cta variant="brick" data-analytics-linktype="cta" data-analytics-text="Brick"><a href="#brick">Brick</a></Cta>
    <section data-analytics-category="href-attr">
      <h3>
        Using
        <code>href</code>
        attribute
      </h3>
      <Cta href="#default" data-analytics-linktype="cta" data-analytics-text="Default">Default</Cta>
      <Cta href="#primary" variant="primary" data-analytics-linktype="cta" data-analytics-text="Primary">Primary</Cta>
      <Cta href="#secondary" variant="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary">Secondary</Cta>
      <Cta href="#brick" variant="brick" data-analytics-linktype="cta" data-analytics-text="Brick">Brick</Cta>
    </section>
  </section>
  <section data-analytics-category="shadow">
    <h2>Advanced Case: Deep Shadow</h2>
    <shadow-root>
      <template shadowrootmode="open" />
    </shadow-root>
    <h3>
      Using
      <code>href</code>
      attribute
    </h3>
    <shadow-root data-analytics-category="href-attr">
      <template shadowrootmode="open" />
    </shadow-root>
  </section>
  <section data-analytics-category="slotted">
    <h2>Complex Case: Slotted Link, Deep CTA</h2>
    <slotted-link>
      <a slot="default" data-analytics-linktype="cta" data-analytics-text="Default" href="#default">Default</a>
      <a slot="primary" data-analytics-linktype="cta" data-analytics-text="Primary" href="#primary">Primary</a>
      <a slot="secondary" data-analytics-linktype="cta" data-analytics-text="Secondary" href="#secondary">Secondary</a>
      <a slot="brick" data-analytics-linktype="cta" data-analytics-text="Brick" href="#brick">Brick</a>
    </slotted-link>
  </section>
  <h2>Last CTA Analytics Event</h2>
  <json-viewer>{}</json-viewer>
);

Brick

import '@rhds/elements/rh-cta/rh-cta.js';
#grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
<div id="grid">
  <rh-cta variant="brick"><a href="#">Link #1</a></rh-cta>
  <rh-cta variant="brick"><a href="#">Link #2</a></rh-cta>
  <rh-cta variant="brick"><a href="#">Link #3</a></rh-cta>
  <rh-cta variant="brick">
    <a href="#default">Supercalifragilisticexpialidocious</a>
  </rh-cta>
</div>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <div id="grid">
    <Cta variant="brick"><a href="#">Link #1</a></Cta>
    <Cta variant="brick"><a href="#">Link #2</a></Cta>
    <Cta variant="brick"><a href="#">Link #3</a></Cta>
    <Cta variant="brick"><a href="#default">Supercalifragilisticexpialidocious</a></Cta>
  </div>
);

Button

import '@rhds/elements/rh-cta/rh-cta.js';
<rh-cta>
  <button>Button</button>
</rh-cta>

<rh-cta variant="primary">
  <button>Button</button>
</rh-cta>

<rh-cta variant="secondary">
  <button>Button</button>
</rh-cta>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <Cta>
    <button>Button</button>
  </Cta>
  <Cta variant="primary">
    <button>Button</button>
  </Cta>
  <Cta variant="secondary">
    <button>Button</button>
  </Cta>
);

Color Context With Lightdom Css

import '@rhds/elements/rh-cta/rh-cta.js';
import '@rhds/elements/lib/elements/rh-context-demo/rh-context-demo.js';
<rh-context-demo>
  <rh-cta><a href="#default">Default</a></rh-cta>
  <rh-cta icon="play-circle"><a href="#default-video">Default Video</a></rh-cta>
  <rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
  <rh-cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></rh-cta>
  <rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
  <rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
  <rh-cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></rh-cta>
</rh-context-demo>

<link rel="stylesheet" href="../rh-cta-lightdom-shim.css">
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <rh-context-demo>
    <Cta><a href="#default">Default</a></Cta>
    <Cta icon="play-circle"><a href="#default-video">Default Video</a></Cta>
    <Cta variant="primary"><a href="#primary">Primary</a></Cta>
    <Cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></Cta>
    <Cta variant="secondary"><a href="#secondary">Secondary</a></Cta>
    <Cta variant="brick"><a href="#brick">Brick</a></Cta>
    <Cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></Cta>
  </rh-context-demo>
  <link rel="stylesheet" href="../rh-cta-lightdom-shim.css" />
);

Color Context

import '@rhds/elements/rh-cta/rh-cta.js';
import '@rhds/elements/lib/elements/rh-context-demo/rh-context-demo.js';
<rh-context-demo>
  <rh-cta><a href="#default">Default</a></rh-cta>
  <rh-cta icon="play-circle"><a href="#default-video">Default Video</a></rh-cta>
  <rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
  <rh-cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></rh-cta>
  <rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
  <rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
  <rh-cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></rh-cta>
</rh-context-demo>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <rh-context-demo>
    <Cta><a href="#default">Default</a></Cta>
    <Cta icon="play-circle"><a href="#default-video">Default Video</a></Cta>
    <Cta variant="primary"><a href="#primary">Primary</a></Cta>
    <Cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></Cta>
    <Cta variant="secondary"><a href="#secondary">Secondary</a></Cta>
    <Cta variant="brick"><a href="#brick">Brick</a></Cta>
    <Cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></Cta>
  </rh-context-demo>
);

Href Attribute

section {
  display: flex;
  gap: var(--rh-space-lg, 16px);
  flex-flow: row wrap;
  max-width: 750px;
  margin: var(--rh-space-2xl, 32px) auto;
}

#brick {
  display: flex;
  width: 100%;
  gap: var(--rh-space-lg, 16px);
}
import '@rhds/elements/rh-cta/rh-cta.js';
<section>
  <rh-cta href="#default">Default</rh-cta>
  <rh-cta href="#default-video" icon="play-circle">Default Video</rh-cta>
  <rh-cta href="#primary" variant="primary">Primary</rh-cta>
  <rh-cta href="#primary-video" variant="primary" icon="play-circle">Video</rh-cta>
  <rh-cta href="#secondary" variant="secondary">Secondary</rh-cta>
  <div id="brick">
    <rh-cta href="#brick" variant="brick">Brick</rh-cta>
    <rh-cta href="#brick-icon" variant="brick" icon="user">Brick Icon</rh-cta>
  </div>
</section>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <section>
    <Cta href="#default">Default</Cta>
    <Cta href="#default-video" icon="play-circle">Default Video</Cta>
    <Cta href="#primary" variant="primary">Primary</Cta>
    <Cta href="#primary-video" variant="primary" icon="play-circle">Video</Cta>
    <Cta href="#secondary" variant="secondary">Secondary</Cta>
    <div id="brick">
      <Cta href="#brick" variant="brick">Brick</Cta>
      <Cta href="#brick-icon" variant="brick" icon="user">Brick Icon</Cta>
    </div>
  </section>
);

No Cta Javascript

shadow-root:not(:defined) {
  display: block;
  opacity: 1;
}

header[lang="en"] {
  width: 100%;
}
import '@rhds/elements/rh-surface/rh-surface.js';

// import('/assets/dsd-polyfill.js');
// TODO: DSD poly wont load in local dev dynamically
// imported from /assets path loading inline here:
if (!('shadowRootMode' in HTMLTemplateElement.prototype)) {
  (function attachShadowRoots(root) {
    // find all templates with a shadowrootmode attribute
    root.querySelectorAll('template[shadowrootmode]').forEach(template => {
      // get the mode: open or closed
      const mode = template.getAttribute('shadowrootmode');
      // attach a shadow to the component
      const shadowRoot = template.parentNode.attachShadow({ mode });
      // append the content in the template
      shadowRoot.appendChild(template.content);
      // remove the template
      template.remove();
      attachShadowRoots(shadowRoot);
    });
  })(document);
}
document.body.removeAttribute('dsd-pending');

customElements.define('shadow-root', class ShadowRootElement extends HTMLElement { });
<link rel="stylesheet" href="../rh-cta-lightdom-shim.css">
<p>&lt;rh-cta&gt; where JavaScript is not loaded, while loading a `lightdom-shim.css`.</p>

<section id="variants">
  <h2>Variants</h2>
  <rh-cta><a href="#default">Default</a></rh-cta>
  <rh-cta icon="play-circle"><a href="#default-video">Default Video</a></rh-cta>
  <rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
  <rh-cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></rh-cta>
  <rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
  <rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
  <rh-cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></rh-cta>
</section>

<rh-surface color-palette="darkest">
  <h2>Dark Color Context</h2>
  <rh-cta><a href="#default">Default</a></rh-cta>
  <rh-cta icon="play-circle"><a href="#default-video">Default Video</a></rh-cta>
  <rh-cta variant="primary"><a href="#primary">Primary</a></rh-cta>
  <rh-cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></rh-cta>
  <rh-cta variant="secondary"><a href="#secondary">Secondary</a></rh-cta>
  <rh-cta variant="brick"><a href="#brick">Brick</a></rh-cta>
  <rh-cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></rh-cta>
</rh-surface>

<section dir="rtl" lang="he">
  <header lang="en" dir="ltr">
    <h2>Right-to-Left Languages</h2>
  </header>

  <div>
    <rh-cta>
      <a href="#default">ברירת מחדל</a>
    </rh-cta>

    <rh-cta icon="play-circle">
      <a href="#default-video">ברירת מחדל - וידאו</a>
    </rh-cta>

    <rh-cta variant="primary">
      <a href="#primary">ראשי</a>
    </rh-cta>

    <rh-cta variant="primary" icon="play-circle">
      <a href="#primary-video">ראשי - וידאו</a>
    </rh-cta>

    <rh-cta variant="secondary">
      <a href="#secondary">משני</a>
    </rh-cta>

    <rh-cta variant="brick">
      <a href="#brick">לבנה</a>
    </rh-cta>

    <rh-cta variant="brick" icon="user">
      <a href="#brick-icon">לבנה עם אייקון</a>
    </rh-cta>
  </div>
</section>

<section dir="rtl" lang="he">
  <header dir="ltr" lang="en">
    <h2>Deep Shadow RTL</h2>
    <p>
      When the CTA is found within the shadow root of an element which is itself within a RTL context,
      it's own contents should also be displayed right-to-left, including the various box models, the placement
      of the icon, and the direction of the arrow. Authors should not need to specify the direction with the
      <code>dir="rtl"</code> attribute if it is added to a containing element.
      In this demo, the shadow root's host element has a light blue background color, in order distinguish it from the document content.
    </p>
  </header>
  <shadow-root>
    <template shadowrootmode="open">
      <link rel="stylesheet" href="../rh-cta-lightdom-shim.css">
      <style>
        :host {
width: 100%;
padding: var(--rh-space-xl, 24px);
background-color: var(--rh-color-blue-50, #e7f1fa);
display: flex;
flex-flow: row wrap;
gap: 16px;
align-items: center;
        }
      </style>

      <rh-cta id="deep">
        <a href="#default">ברירת מחדל</a>
      </rh-cta>

      <rh-cta icon="play-circle">
        <a href="#default-video">ברירת מחדל - וידאו</a>
      </rh-cta>

      <rh-cta variant="primary">
        <a href="#primary">ראשי</a>
      </rh-cta>

      <rh-cta variant="primary" icon="play-circle">
        <a href="#primary-video">ראשי - וידאו</a>
      </rh-cta>

      <rh-cta variant="secondary">
        <a href="#secondary">משני</a>
      </rh-cta>

      <rh-cta variant="brick">
        <a href="#brick">לבנה</a>
      </rh-cta>

      <rh-cta variant="brick" icon="user">
        <a href="#brick-icon">לבנה עם אייקון</a>
      </rh-cta>
    </template>
  </shadow-root>
</section>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";
import { Surface } from "@rhds/elements/react/rh-surface/rh-surface.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <link rel="stylesheet" href="../rh-cta-lightdom-shim.css" />
  <p><rh-cta> where JavaScript is not loaded, while loading a `lightdom-shim.css`.</p>
  <section id="variants">
    <h2>Variants</h2>
    <Cta><a href="#default">Default</a></Cta>
    <Cta icon="play-circle"><a href="#default-video">Default Video</a></Cta>
    <Cta variant="primary"><a href="#primary">Primary</a></Cta>
    <Cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></Cta>
    <Cta variant="secondary"><a href="#secondary">Secondary</a></Cta>
    <Cta variant="brick"><a href="#brick">Brick</a></Cta>
    <Cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></Cta>
  </section>
  <Surface color-palette="darkest">
    <h2>Dark Color Context</h2>
    <Cta><a href="#default">Default</a></Cta>
    <Cta icon="play-circle"><a href="#default-video">Default Video</a></Cta>
    <Cta variant="primary"><a href="#primary">Primary</a></Cta>
    <Cta variant="primary" icon="play-circle"><a href="#primary-video">Video</a></Cta>
    <Cta variant="secondary"><a href="#secondary">Secondary</a></Cta>
    <Cta variant="brick"><a href="#brick">Brick</a></Cta>
    <Cta variant="brick" icon="play-circle"><a href="#brick-video">Brick Video</a></Cta>
  </Surface>
  <section dir="rtl" lang="he">
    <header lang="en" dir="ltr">
      <h2>Right-to-Left Languages</h2>
    </header>
    <div>
      <Cta><a href="#default">ברירת מחדל</a></Cta>
      <Cta icon="play-circle"><a href="#default-video">ברירת מחדל - וידאו</a></Cta>
      <Cta variant="primary"><a href="#primary">ראשי</a></Cta>
      <Cta variant="primary" icon="play-circle"><a href="#primary-video">ראשי - וידאו</a></Cta>
      <Cta variant="secondary"><a href="#secondary">משני</a></Cta>
      <Cta variant="brick"><a href="#brick">לבנה</a></Cta>
      <Cta variant="brick" icon="user"><a href="#brick-icon">לבנה עם אייקון</a></Cta>
    </div>
  </section>
  <section dir="rtl" lang="he">
    <header dir="ltr" lang="en">
      <h2>Deep Shadow RTL</h2>
      <p>
        When the CTA is found within the shadow root of an element which is itself within a RTL context,
        it's own contents should also be displayed right-to-left, including the various box models, the placement
        of the icon, and the direction of the arrow. Authors should not need to specify the direction with the
        <code>dir="rtl"</code>
        attribute if it is added to a containing element.
        In this demo, the shadow root's host element has a light blue background color, in order distinguish it from the document content.
      </p>
    </header>
    <shadow-root>
      <template shadowrootmode="open" />
    </shadow-root>
  </section>
);

Resizing

import '@rhds/elements/rh-cta/rh-cta.js';
#resize {
  display: flex;
  flex-flow: row wrap;
  gap: var(--rh-space-lg, 16px);
}

#resize > p {
  width: 100%;
}

#resize > div {
  resize: horizontal;
  overflow: auto;
  display: flex;
  width: 180px;
  flex-flow: row nowrap;
  border: 1px solid #dddddd;
  padding: 10px;
}
<section id="resize">
  <div>
    <rh-cta>
      <a href="#default">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta icon="play-circle">
      <a href="#default-video">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="primary">
      <a href="#primary">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="primary" icon="play-circle">
      <a href="#primary-video">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="secondary">
      <a href="#secondary">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="brick">
      <a href="#brick">Get product details</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="brick" icon="user">
      <a href="#brick-icon">Get product details</a>
    </rh-cta>
  </div>

  <p>No matter the container size, the arrow trailing the CTA message should never appear on a line by itself.</p>

  <div>
    <rh-cta><a href="#default">Default link cta with longer text</a></rh-cta>
  </div>

  <div dir="rtl">
    <rh-cta>
      <a href="#default">קריאה לפעולה בררית מחדל עם טקסט ארוך</a>
    </rh-cta>
  </div>

  <p>Long words should break in the middle</p>

  <div>
    <rh-cta>
      <a href="#default">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta icon="play-circle">
      <a href="#default-video">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="primary">
      <a href="#primary">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="primary" icon="play-circle">
      <a href="#primary-video">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="secondary">
      <a href="#secondary">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="brick">
      <a href="#brick">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>

  <div>
    <rh-cta variant="brick" icon="user">
      <a href="#brick-icon">Supercalifragilisticexpialidocious</a>
    </rh-cta>
  </div>
</section>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <section id="resize">
    <div>
      <Cta><a href="#default">Get product details</a></Cta>
    </div>
    <div>
      <Cta icon="play-circle"><a href="#default-video">Get product details</a></Cta>
    </div>
    <div>
      <Cta variant="primary"><a href="#primary">Get product details</a></Cta>
    </div>
    <div>
      <Cta variant="primary" icon="play-circle"><a href="#primary-video">Get product details</a></Cta>
    </div>
    <div>
      <Cta variant="secondary"><a href="#secondary">Get product details</a></Cta>
    </div>
    <div>
      <Cta variant="brick"><a href="#brick">Get product details</a></Cta>
    </div>
    <div>
      <Cta variant="brick" icon="user"><a href="#brick-icon">Get product details</a></Cta>
    </div>
    <p>No matter the container size, the arrow trailing the CTA message should never appear on a line by itself.</p>
    <div>
      <Cta><a href="#default">Default link cta with longer text</a></Cta>
    </div>
    <div dir="rtl">
      <Cta><a href="#default">קריאה לפעולה בררית מחדל עם טקסט ארוך</a></Cta>
    </div>
    <p>Long words should break in the middle</p>
    <div>
      <Cta><a href="#default">Supercalifragilisticexpialidocious</a></Cta>
    </div>
    <div>
      <Cta icon="play-circle">
        <a href="#default-video">Supercalifragilisticexpialidocious</a>
      </Cta>
    </div>
    <div>
      <Cta variant="primary"><a href="#primary">Supercalifragilisticexpialidocious</a></Cta>
    </div>
    <div>
      <Cta variant="primary" icon="play-circle">
        <a href="#primary-video">Supercalifragilisticexpialidocious</a>
      </Cta>
    </div>
    <div>
      <Cta variant="secondary"><a href="#secondary">Supercalifragilisticexpialidocious</a></Cta>
    </div>
    <div>
      <Cta variant="brick"><a href="#brick">Supercalifragilisticexpialidocious</a></Cta>
    </div>
    <div>
      <Cta variant="brick" icon="user">
        <a href="#brick-icon">Supercalifragilisticexpialidocious</a>
      </Cta>
    </div>
  </section>
);

Right To Left

shadow-root:not(:defined) {
  display: block;
  opacity: 1;
}

section>div {
  display: flex;
  flex-flow: row wrap;
  gap: var(--rh-space-lg, 16px);
  padding: var(--rh-space-xl, 24px);
  width: 100%;
}

header[lang="en"] {
  width: 100%;
}
import '@rhds/elements/rh-cta/rh-cta.js';
if (!('shadowRootMode' in HTMLTemplateElement.prototype)) {
  import('/assets/dsd-polyfill.js');
}
customElements.define('shadow-root', class ShadowRootElement extends HTMLElement { });
<section dir="rtl" lang="he">
  <header lang="en" dir="ltr">
    <h2>Right-to-Left Languages</h2>
  </header>

  <div>
    <rh-cta> href="#default"&gt;ברירת מחדל</rh-cta>
    <rh-cta icon="play-circle" href="#default-video">ברירת מחדל - וידאו</rh-cta>
    <rh-cta variant="primary" href="#primary">ראשי</rh-cta>
    <rh-cta variant="primary" icon="play-circle" href="#primary-video">ראשי - וידאו</rh-cta>
    <rh-cta variant="secondary" href="#secondary">משני</rh-cta>
    <rh-cta variant="brick" href="#brick">לבנה</rh-cta>
    <rh-cta variant="brick" icon="user" href="#brick-icon">לבנה עם אייקון</rh-cta>
  </div>
</section>

<section dir="rtl" lang="he">
  <header dir="ltr" lang="en">
    <h2>Deep Shadow RTL</h2>
    <p>
      When the CTA is found within the shadow root of an element which is itself within a RTL context,
      it's own contents should also be displayed right-to-left, including the various box models, the placement
      of the icon, and the direction of the arrow. Authors should not need to specify the direction with the
      <code>dir="rtl"</code> attribute if it is added to a containing element.
      In this demo, the shadow root's host element has a light blue background color, in order distinguish it from the document content.
    </p>
  </header>
  <shadow-root>
    <template shadowrootmode="open">
      <style>
        :host {
width: 100%;
padding: var(--rh-space-xl, 24px);
color-scheme: dark only;
background-color: var(--rh-color-surface-darkest, #151515);
display: flex;
flex-flow: row wrap;
gap: 16px;
        }
      </style>

      <rh-cta id="deep" href="#default">ברירת מחדל</rh-cta>
      <rh-cta icon="play-circle" href="#default-video">ברירת מחדל - וידאו</rh-cta>
      <rh-cta variant="primary" href="#primary">ראשי</rh-cta>
      <rh-cta variant="primary" icon="play-circle" href="#primary-video">ראשי - וידאו</rh-cta>
      <rh-cta variant="secondary" href="#secondary">משני</rh-cta>
      <rh-cta variant="brick" href="#brick">לבנה</rh-cta>
      <rh-cta variant="brick" icon="user" href="#brick-icon">לבנה עם אייקון</rh-cta>
    </template>
  </shadow-root>
</section>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <section dir="rtl" lang="he">
    <header lang="en" dir="ltr">
      <h2>Right-to-Left Languages</h2>
    </header>
    <div>
      <Cta>href="#default">ברירת מחדל</Cta>
      <Cta icon="play-circle" href="#default-video">ברירת מחדל - וידאו</Cta>
      <Cta variant="primary" href="#primary">ראשי</Cta>
      <Cta variant="primary" icon="play-circle" href="#primary-video">ראשי - וידאו</Cta>
      <Cta variant="secondary" href="#secondary">משני</Cta>
      <Cta variant="brick" href="#brick">לבנה</Cta>
      <Cta variant="brick" icon="user" href="#brick-icon">לבנה עם אייקון</Cta>
    </div>
  </section>
  <section dir="rtl" lang="he">
    <header dir="ltr" lang="en">
      <h2>Deep Shadow RTL</h2>
      <p>
        When the CTA is found within the shadow root of an element which is itself within a RTL context,
        it's own contents should also be displayed right-to-left, including the various box models, the placement
        of the icon, and the direction of the arrow. Authors should not need to specify the direction with the
        <code>dir="rtl"</code>
        attribute if it is added to a containing element.
        In this demo, the shadow root's host element has a light blue background color, in order distinguish it from the document content.
      </p>
    </header>
    <shadow-root>
      <template shadowrootmode="open" />
    </shadow-root>
  </section>
);

Variants

#cta-variants {
  display: flex;
  gap: var(--rh-space-lg, 16px);
  flex-flow: row wrap;
  max-width: 750px;
  margin: var(--rh-space-2xl, 32px) auto;
}

#brick {
  display: flex;
  width: 100%;
  gap: var(--rh-space-lg, 16px);
}
import '@rhds/elements/rh-cta/rh-cta.js';
<section id="cta-variants">
  <rh-cta href="#default">Default</rh-cta>

  <rh-cta icon="play-circle" href="#default-video">Default Video</rh-cta>

  <rh-cta variant="primary" href="#primary">Primary</rh-cta>

  <rh-cta variant="primary" icon="play-circle" href="#primary-video">Video</rh-cta>

  <rh-cta variant="secondary" href="#secondary">Secondary</rh-cta>

  <div id="brick">
    <rh-cta variant="brick" href="#brick">Brick</rh-cta>
    <rh-cta variant="brick" icon="users" href="#brick-icon">Brick Icon</rh-cta>
  </div>
</section>
import { Cta } from "@rhds/elements/react/rh-cta/rh-cta.js";

// NOTE: React 19+ does not require these wrapper imports.
// You can use the custom elements directly as-is.

export const Demo = () => (
  <section id="cta-variants">
    <Cta href="#default">Default</Cta>
    <Cta icon="play-circle" href="#default-video">Default Video</Cta>
    <Cta variant="primary" href="#primary">Primary</Cta>
    <Cta variant="primary" icon="play-circle" href="#primary-video">Video</Cta>
    <Cta variant="secondary" href="#secondary">Secondary</Cta>
    <div id="brick">
      <Cta variant="brick" href="#brick">Brick</Cta>
      <Cta variant="brick" icon="users" href="#brick-icon">Brick Icon</Cta>
    </div>
  </section>
);
© 2026 Red Hat Deploys by Netlify