Skip to content

bug: countdown and radial-progress break Content Security Policy (require 'unsafe-inline' in style-src) #4475

@eagle-head

Description

@eagle-head

Reproduction URL

https://github.com/eagle-head/drink_water (branch feat/csp-level3-strict)

What version of daisyUI are you using?

v5 (latest)

Which browsers are you seeing the problem on?

All browsers

Describe your issue

What happens

The countdown and radial-progress components require values to be passed via inline style attributes:

<span style="--value:99;">99</span>
<div class="radial-progress" style="--value:70;">70%</div>

When a Content Security Policy is active with style-src 'self' (without 'unsafe-inline'), these inline style attributes are blocked by the browser (MDN reference). This forces applications that use these components to add 'unsafe-inline' to style-src, weakening the CSP.

Why this is not a DaisyUI design flaw

DaisyUI is a CSS-only library, and style="--value:X" is the natural way to pass dynamic values to CSS custom properties today. The CSS specification simply doesn't yet offer a cross-browser alternative for reading arbitrary data from HTML attributes into custom properties.

The ideal solution — attr(data-value type(<number>)) from CSS Values Level 5 — would allow reading data-* attributes directly into CSS custom properties without inline styles. But browser support is very limited:

CSS Feature Chrome Firefox Safari
attr() with type (MDN) 133+ (Feb 2025) Not implemented (bug open since 2008, part of Interop 2026) No known support
@property (MDN) 85+ 128+ 15.4+

Until attr() with type is cross-browser, a pure-CSS solution isn't viable.

Proposed approach: data-value attribute with a small JS bridge

Add an optional data-value attribute that a small JavaScript snippet reads and applies via the DOM style API (element.style.setProperty()), which is explicitly allowed by CSP:

"Style properties that are set directly on the element's style property will not be blocked, allowing users to safely manipulate styles via JavaScript."

<!-- CSP-safe alternative (new) -->
<span class="countdown" data-value="99">99</span>
<div class="radial-progress" data-value="70" role="progressbar">70%</div>

The existing style="--value:X" API would remain for backward compatibility. When attr() with type reaches cross-browser support, the JS bridge can be replaced with pure CSS, and data-value would still work as-is.

Scope

Only 2 of 58 components are affected (countdown and radial-progress). All other DaisyUI components set custom properties internally via CSS classes — they are already CSP-compatible.

Why it matters

  • CSP Level 3 is a W3C security standard to mitigate XSS attacks
  • Compliance frameworks (PCI DSS, SOC 2, HIPAA) increasingly require strict CSP
  • Frameworks are adding built-in CSP support: Phoenix/Elixir (in progress), Rails, Django (already ship with nonce support)
  • Their ecosystems expect CSS libraries to be CSP-compatible

Reproduction steps

  1. Clone eagle-head/drink_water
  2. Checkout branch feat/csp-level3-strict
  3. Run mix phx.server
  4. Open /dashboard in the browser
  5. Check logs/csp_violations.log for style-src-attr violations from countdown/radial-progress

Source code references

I'd like to contribute

I'm happy to submit a PR with the data-value JS bridge if this approach sounds good. The change is small and backward-compatible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions