Turret CSS is just CSS, so on paper CSP should be easy: allow your stylesheet, block the weird stuff, move on.
In practice, teams still break production layouts with CSP all the time.
I’ve seen the same pattern over and over: someone tightens style-src, the app ships, and suddenly Turret CSS “doesn’t work.” Usually Turret isn’t the problem. The policy is. More specifically, the policy was written with JavaScript in mind and nobody checked how styles are actually loaded, injected, or modified across the app.
Here are the mistakes I see most often, and how to fix them without giving up on a sane CSP.
Mistake #1: Assuming default-src covers styles correctly
A lot of developers start with something like this:
Content-Security-Policy: default-src 'self';
Then they load Turret CSS from a CDN or a separate asset domain and wonder why the styles are blocked.
default-src is a fallback, not a good long-term strategy. Once you care about CSP, you should be explicit.
Broken example
Content-Security-Policy: default-src 'self';
Fix
If Turret CSS is hosted on your own origin:
Content-Security-Policy: default-src 'self'; style-src 'self';
If you load it from a CDN:
Content-Security-Policy: default-src 'self'; style-src 'self' https://cdn.example.com;
If you need a refresher on directive behavior, csp-guide.com is a good reference without too much fluff.
Mistake #2: Blocking inline styles without realizing your app uses them
This is probably the biggest one.
Turret CSS itself may be delivered as a normal external stylesheet, but your app, CMS, framework, or component library may still inject inline styles. That includes things like:
- framework-generated
<style>tags - WYSIWYG editors
- animation libraries
- runtime theme switching
- third-party consent banners
- old templates with
style=""attributes sprinkled everywhere
Then somebody sets this:
Content-Security-Policy: style-src 'self';
And layout pieces quietly break.
Typical symptoms
- the page loads, but spacing or utility classes look wrong
- a cookie banner loses styling
- modal positioning breaks
- dark mode/theme styles disappear
- console shows CSP violations for inline style blocks or attributes
Fix options
Best fix: remove inline styles
If you control the code, move inline styles into stylesheet classes.
Instead of this:
<div style="margin-top: 1rem; color: red;">Alert</div>
Do this:
<div class="alert alert-danger mt-4">Alert</div>
That’s cleaner and CSP-friendly.
Practical fix: allow inline styles temporarily
If you have legacy code and need the app working today:
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline';
Yes, unsafe-inline weakens CSP. I don’t love it, but sometimes it’s the honest transitional step.
A real-world example is the CSP used by headertest.com, which currently includes:
style-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://*.cookiebot.com https://consent.cookiebot.com;
That’s not unusual. Plenty of otherwise well-secured sites still need unsafe-inline in style-src because of consent tools, tag managers, or legacy frontend behavior.
Before changing anything blindly, I’d test the live headers and violations with HeaderTest. It’s a quick way to spot whether style directives are the thing actually breaking your page.
Mistake #3: Forgetting fonts used by Turret CSS or your design system
Turret CSS may be fine, but the fonts it references are often not.
You lock down CSP, styles load, and then the page suddenly falls back to Arial because font-src is too strict.
Broken example
Content-Security-Policy: default-src 'self'; style-src 'self' https://cdn.example.com; font-src 'self';
If your stylesheet loads fonts from another host, those font requests will fail.
Fix
Allow the actual font origin:
Content-Security-Policy:
default-src 'self';
style-src 'self' https://cdn.example.com;
font-src 'self' https://fonts.examplecdn.com;
Better yet, self-host fonts whenever possible. That keeps CSP simpler and reduces third-party dependencies.
Mistake #4: Allowing the stylesheet host, but not related asset hosts
This one trips people up with CDNs.
They allow the domain serving turret.min.css, but the CSS file itself references:
- fonts from another domain
- background images from another domain
- SVG assets from another domain
So style-src looks right, but the page still looks half-broken.
Example
Content-Security-Policy:
default-src 'self';
style-src 'self' https://cdn.example.com;
img-src 'self';
font-src 'self';
If Turret CSS or your custom theme pulls assets from static.examplecdn.com, CSP will block them.
Fix
Audit what the CSS actually loads.
Content-Security-Policy:
default-src 'self';
style-src 'self' https://cdn.example.com;
img-src 'self' https://static.examplecdn.com data:;
font-src 'self' https://static.examplecdn.com;
This is where browser DevTools helps a lot. Open the Network tab and console, reload the page, and watch for CSP violations tied to fonts, images, or SVGs.
Mistake #5: Using a CDN for Turret CSS when self-hosting would simplify everything
I’m not anti-CDN, but a lot of teams reach for one by default and then spend time poking holes in CSP to support it.
If you self-host Turret CSS, your policy is cleaner:
Content-Security-Policy:
default-src 'self';
style-src 'self';
font-src 'self';
img-src 'self' data:;
That’s easier to reason about than this kind of sprawl:
Content-Security-Policy:
default-src 'self';
style-src 'self' https://cdn1.example.com https://cdn2.example.com;
font-src 'self' https://fonts.example.com;
img-src 'self' data: https://img.example.com;
If you’re already building and deploying your own frontend assets, self-hosting Turret CSS is usually the better call.
Mistake #6: Copy-pasting a JavaScript-heavy CSP and assuming it fits CSS
I see policies copied from blog posts that obsess over script-src nonces, hashes, and strict-dynamic, while style-src gets barely any thought.
For example, this is a real CSP header pattern from a production site:
content-security-policy: default-src 'self' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com; script-src 'self' 'nonce-MzdlNzhjODUtZWE2Ni00OTNjLWI4OWUtZWFiMzFjNTI0MDUw' 'strict-dynamic' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com; style-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://*.cookiebot.com https://consent.cookiebot.com; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.headertest.com https://tallycdn.com https://or.headertest.com wss://or.headertest.com https://*.google-analytics.com https://*.googletagmanager.com https://*.cookiebot.com; frame-src 'self' https://consentcdn.cookiebot.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'
There’s nothing inherently wrong with that header, but notice the reality: styles often need different allowances than scripts. Don’t design CSS policy as an afterthought.
For Turret CSS, ask simple questions:
- Where is the CSS served from?
- Does anything inject
<style>blocks? - Are there inline
styleattributes in templates? - Are fonts local or remote?
- Do background images or SVGs come from other origins?
That gets you to a working policy much faster than cargo-culting a “strict CSP” snippet from somewhere.
Mistake #7: Shipping enforcement without using Report-Only first
If you’re changing CSP around styles, don’t go straight to blocking mode unless you enjoy emergency rollbacks.
Use Content-Security-Policy-Report-Only first:
Content-Security-Policy-Report-Only:
default-src 'self';
style-src 'self';
font-src 'self';
img-src 'self' data:;
That lets you see what would break without actually breaking it.
This matters a lot for Turret CSS in larger apps, because the stylesheet is only one part of the picture. The real mess is usually old templates, third-party widgets, and frontend code that nobody realized was injecting styles.
Mistake #8: Treating unsafe-inline as either pure evil or totally fine
Developers tend to get weirdly absolutist here.
My take: for style-src, unsafe-inline is often a temporary compromise, not a moral failure. But if you leave it there forever without a cleanup plan, your policy is weaker than it needs to be.
Better path
- Start with what works:
style-src 'self' 'unsafe-inline';
-
Inventory inline styles and injected
<style>blocks. -
Move what you control into static CSS.
-
Re-test.
-
Remove
unsafe-inlinewhen the app can handle it.
That’s a lot more realistic than pretending every production app can jump straight to a pristine policy.
A solid starting CSP for Turret CSS
If you self-host Turret CSS and assets, this is a good baseline:
Content-Security-Policy:
default-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
If you still depend on inline styles during migration:
Content-Security-Policy:
default-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
If Turret CSS is on a CDN:
Content-Security-Policy:
default-src 'self';
style-src 'self' https://cdn.example.com;
img-src 'self' data: https://cdn.example.com;
font-src 'self' https://cdn.example.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
The main thing is to write the policy for how your app really behaves, not how you wish it behaved.
Turret CSS usually isn’t hard to support under CSP. The mistakes come from everything wrapped around it: CMS output, third-party tools, inline legacy code, and asset sprawl. Fix those, and the CSP gets a lot less painful.