---
title: Customize
description: Change the c15t script tag banner on a plain HTML site with theme
  tokens, extra CSS, layout, copy and legal links, or replace it with your own
  HTML.
group: frameworks
lastModified: "2026-10-10T16:01:45+01:00"
---
## See the designs

See the [design gallery](/docs/customization/recipes) 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:

```html title="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](/docs/customization/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:

```html
<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](/docs/customization/class-names) and
[Tailwind CSS](/docs/customization/tailwind) show both, and
[component parts](/docs/customization/slots) 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:

```css
[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:

```html
<script>
  window.c15t = window.c15t || [];
  c15t.push(['config', {
    presentation: { prompt: { variant: 'bar', position: 'bottom' } },
  }]);
</script>
```

|`variant`|Positions|
|--|--|
|`floating` (default)|`bottom-left` (default), `bottom-right`, `top-left`, `top-right`, `bottom-center`, `top-center`|
|`bar`|`bottom` (default), `top`|
|`widget`|`bottom-right` (default), `bottom-left`, `top-left`, `top-right`|
|`wall`|`center`|

The [banner](/docs/frameworks/html/components/banner#change-the-layout) 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](/docs/customization/overview#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](/docs/frameworks/html/components/banner#change-the-text)
page lists them. For wording shared by the banner and the dialog, and for other
languages, see [translations](/docs/frameworks/html/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.

## Show legal links

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](/docs/customization/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](/docs/customization/motion) 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](/docs/frameworks/html/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.
