When working with SEO-driven or CMS-based content in React / Next.js, we often rely on
dangerouslySetInnerHTML to render HTML strings.
Everything looks fine… until you add CSS classes inside the HTML content and realize:
❌ Styles are not being applied at all.
Let’s break down why this happens and how to fix it properly.
🧩 The Problem
Example content:
ts
const content = `
You can consult <span class="highlight">certified nutritionists</span>
from home.
`;
Rendered like this:
tsx
<p dangerouslySetInnerHTML={{ __html: content }} />
And styled using styled-jsx:
tsx
<style jsx>{`
.highlight {
color: #0a7cff;
font-weight: 600;
}
`}</style>
❌ Result
The .highlight styles do not apply.
🤔 Why This Happens
Next.js uses styled-jsx, which scopes CSS to JSX-rendered elements.
However:
HTML injected via dangerouslySetInnerHTML is outside the styled-jsx scope
So class selectors like:
css
.highlight { ... }
get transformed into:
css
.highlight.jsx-123456 { ... }
But your injected HTML doesn’t receive that hash, so styles never match.
✅ Solution (Recommended): Use :global() in styled-jsx
Wrap your class selectors with :global().
tsx
<style jsx>{`
:global(.highlight) {
color: #0a7cff;
font-weight: 600;
}
:global(.link) {
color: #0070f3;
text-decoration: underline;
}
`}</style>
✅ Now your injected HTML works correctly.
Top comments (0)