Skip to main content

HTML Customization

Customize

See the designs

See the design gallery for five banner designs, including a custom bottom bar built on the headless script tag.

Change colors, radius and fonts

Queue a config call with ui.theme before the script tag. This block turns the buttons purple and rounds the cards:

index.html
<script>
	window.c15t = window.c15t || [];
	c15t.push([
		'config',
		{
			ui: {
				theme: {
					colors: {
						primary: '#6943a3',
						primaryHover: '#533285',
						textOnPrimary: '#ffffff',
					},
					radius: { lg: '18px' },
				},
			},
		},
	]);
</script>

Put the block in the same <head> as the tag. The tag has defer, so any inline script above or below it runs first. theme takes the same token object as the other c15t packages; theme tokens lists every token and what it changes. The banner, the preference dialog and the trigger button all read the same tokens.

Add CSS inside the shadow root

The banner renders in a shadow root with its own copy of the stylesheet, so a theme's global button {} rule cannot reach it and the banner cannot restyle your page. To target one part, pass CSS in ui.css. c15t adds it after the bundled stylesheet, inside the shadow root:

<script>
  window.c15t = window.c15t || [];
  c15t.push(['config', {
    ui: { css: '[data-testid="consent-banner-card"] { border: 3px solid #6943a3; }' },
  }]);
</script>

Select parts by their data-testid attributes, which match the other c15t packages. Inspect the banner in the browser's element panel to find a part's data-testid.

To style parts with classes from your own stylesheet, such as a Tailwind build, put the classes on parts with ui.theme.slots and link the stylesheet into the shadow root with ui.stylesheetURLs. Page CSS can also reach a part by its slot key with [data-c15t-ui]::part(consentBannerCard). Class names and CSS-in-JS and Tailwind CSS show both, and component parts lists the slot keys.

Style it with your own stylesheet

Add data-shadow="false" to the script tag, or set ui: { shadow: false }, and c15t renders the UI into the page. c15t still adds its stylesheet, and your page's CSS now applies too:

[data-c15t-ui] [data-testid="consent-banner-card"] {
  border: 3px solid #6943a3;
}

Your theme's global rules reach the banner in this mode, so check buttons and headings after you switch. In the page, c15t's rules sit in @layer components, and any CSS outside a layer beats them whatever its specificity. That includes a theme's global button {} rule and Tailwind 3's preflight, which removes the button padding and card borders. On a site with Tailwind 3 or such global rules, keep the default shadow root. To write every rule yourself, set ui: { shadow: false, noStyle: true }. c15t then renders unstyled markup with the same data-testid attributes.

c15t puts its stylesheet in a <style> element next to the UI. To serve the stylesheet as a file instead, set ui: { shadow: false, styles: false } and link dist/c15t.css from the same package version as the script.

Change the banner's shape and position

presentation.prompt sets the banner's shape and position:

<script>
  window.c15t = window.c15t || [];
  c15t.push(['config', {
    presentation: { prompt: { variant: 'bar', position: 'bottom' } },
  }]);
</script>
variantPositions
floating (default)bottom-left (default), bottom-right, top-left, top-right, bottom-center, top-center
barbottom (default), top
widgetbottom-right (default), bottom-left, top-left, top-right
wallcenter

The banner page lists the button layout options. The policy still wins. A notice never blocks the page, a choice wall always does, and a policy's required buttons stay visible. Keep behavior and appearance separate explains the split.

Change the copy and language

For one-off wording, set ui.banner.title, description, acceptButtonText, rejectButtonText or customizeButtonText; the banner page lists them. For wording shared by the banner and the dialog, and for other languages, see translations.

The bundle only carries English. Other languages come from your Inth project, the policy manifest or your i18n messages. Your i18n messages for the language in use override the project's or manifest's copy key by key, and keys you leave out keep that copy. data-language="de" on the tag forces a language instead of the browser's.

Add data-privacy-policy-url, data-cookie-policy-url or data-terms-url to the tag and the banner and dialog show those links. To show different links on each surface, set legalLinks in config, then list the links for each surface in ui.banner.legalLinks and ui.dialog.legalLinks. An empty list or null hides links on that surface.

data-hide-branding removes the "Secured by c15t" tag from both surfaces.

Set dark mode and animation

data-color-scheme picks light, dark or system, the default. Set it to none to follow a dark or c15t-dark class on your page's <html> instead. Dark mode covers dark tokens in ui.theme.dark.

data-disable-animation turns off the banner and dialog animations. Without it, c15t skips them for visitors who ask for reduced motion. Motion and animation covers per-surface settings and the duration tokens.

Build your own banner

Load c15t.headless.js instead of c15t.js and write the banner in your own HTML. The runtime still resolves the policy, stores choices and gates scripts, and data-c15t-action buttons work without code. Headless walks through a complete bottom bar.

Check it works

  1. Open the page in a private window. The banner uses your colors and radius.
  2. Open the preference dialog and turn on the floating trigger, if you use it. Both use the same tokens as the banner.
  3. Switch your system between light and dark mode. With data-color-scheme="system", the banner follows it.