Skip to content

Cookie Consent Banner

Tailwind CSS cookie consent banner with accept, reject and a settings dialog with category switches, saved to localStorage with a consent event.

Tailwind CSS Cookie Banners Responsive Dark #banner #consent #cookie #gdpr #modal

Live preview

Open in new tab

Code

A GDPR-style cookie consent banner built with Tailwind CSS and vanilla JavaScript. A dark card slides up from the bottom of the screen with Accept all, Reject all and Settings buttons; Settings opens a dialog with per-category switches. The choice is saved in localStorage, and a small round button lets visitors change it later. Use it on marketing sites, shops and blogs that load analytics or advertising scripts.

How it works

The root is .tcb-root. It contains the .tcb-banner section (data-tcb-banner), the .tcb-dialog overlay (data-tcb-dialog) with the #tcb-dialog panel, and the floating data-tcb-reopen button. All three start hidden.

On DOMContentLoaded the script reads the stored record under data-tcb-storage-key. If no record exists, or its version differs from data-tcb-version, the banner is shown; otherwise the saved switches are restored and only the reopen button appears. One delegated click listener on the root handles every action: data-tcb-accept turns every category on, data-tcb-reject turns optional ones off, and data-tcb-save stores the current state of the data-tcb-category switches. Saving writes { version, date, categories }, hides the banner and dialog and dispatches a bubbling tcb:consent event whose detail holds the categories, so you can load scripts only after consent.

The dialog locks page scrolling, traps Tab inside the panel, closes on Escape, on the backdrop and on the close icon (data-tcb-close), and returns focus to the button that opened it.

Customization

  • data-tcb-storage-key on .tcb-root: the localStorage key, useful when several sites share a domain.
  • data-tcb-version on .tcb-root: increase it when your cookie policy changes to ask every visitor again.
  • Add a category by copying a list item in the dialog and giving its switch a new data-tcb-category value, for example social.
  • bg-neutral-900 on the banner card and #tcb-dialog: use bg-white with dark text for a light theme.
  • bg-amber-400 and peer-checked:bg-amber-400: swap amber for your brand color on buttons and switches.
  • max-w-5xl on the banner card: use max-w-md and add sm:left-auto to .tcb-banner for a compact corner popup.
  • Listen for tcb:consent on document and check event.detail.analytics before injecting a tracking script.

Accessibility

The banner is a labelled section and does not steal focus. The settings panel uses role="dialog", aria-modal="true", aria-labelledby and aria-describedby; the Settings and reopen buttons expose aria-haspopup="dialog" and aria-controls. Each switch is a native checkbox with role="switch", labelled and described by its category text, with a visible focus ring drawn on the track. The reopen icon has an aria-label, and a role="status" region confirms that preferences were saved. Accept and Reject have equal visual weight, and animations are disabled under prefers-reduced-motion: reduce.

Usage notes

Without JavaScript the banner stays hidden, which is safe as long as optional scripts are only loaded from the tcb:consent handler. To test the banner again, delete the tcb-consent entry from local storage in your browser's developer tools.

Requirements

Add these to your page (already included in the download):

  • <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

The Tailwind browser build is for prototyping. In production, compile Tailwind with its CLI or your bundler.

Cookie Consent Banner – Tailwind CSS cookie banners component screenshot
Cookie Consent Banner · Tailwind CSS Cookie Banners

More Cookie Banners

Cookie Preferences Modal – Bootstrap 5 cookie banners preview

Cookie Preferences Modal

Bootstrap 5 cookie consent banner with a preferences modal: category switches, collapsible cookie tables, accept, reject and save actions, stored safely in localStorage.