Skip to main content Home
About About the Design SystemRoadmap
Get started OverviewDesignersDevelopers
Foundations OverviewColorGridIconographyInteractionsSpacingTypography
Tokens Overview Global colorbox shadowTypographyborderopacityspacelengthIconBreakpointsMedia Queries
Elements 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 Navigation (primary) Navigation (secondary) Pagination PopoverPlanned Progress stepsPlanned Site status Skip link Spinner Statistic Subnavigation Surface Switch Table Tabs Tag Tile Timestamp Tooltip Video embed
Theming OverviewColor PalettesCustomizingDevelopers
Patterns All PatternsCardTabsFilterFormLinkLink with iconLogo wallSearch barSkip navigationSticky bannerSticky cardTileVideo thumbnail
Personalization All Personalization PatternsAnnouncement
Accessibility 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>
```

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>
```

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>
```

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>
```

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">
```

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>
```

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>
```

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 Colour 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 colour, 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>
```

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>
```

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 colour, 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>
```

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>
```
© 2021-2025 Red Hat, Inc. Deploys by Netlify