StreamElements has two completely different chat widgets, and they use
different CSS class names. CSS written for one does nothing when pasted
into the other — that's the #1 cause of “I pasted the CSS and nothing changed.”
Use the toggle in the top bar to generate CSS for the widget you actually added.
1 — Chat Box widget (recommended)
Added in the SE overlay editor via ADD WIDGET → Chat Box. Select the widget,
then in the left settings panel click the Custom CSS button and paste the generated
CSS into the editor (the popup with Example 1 / 2 / 3 and an
Available classes list). Click Save in the top-right of the editor.
Its classes look like .chat__item, .chat__message, and every
message carries the chatter's Twitch color as CSS variables
(--line-user-color, --line-user-color-rgb) — so this widget can
tint rows in each user's own color.
2 — Native “Your stream's chat” widget
Added via ADD WIDGET → Stream Tools → Your stream's chat.
Important: this widget has no CSS box in the StreamElements editor at all —
its “Theme: Custom” option only reveals a background-color picker
(verified against SE's production code, July 2026). The CSS goes into
OBS instead:
1) In SE, set the widget's Theme → Custom (removes built-in backgrounds).
2) In OBS, right-click your overlay Browser Source → Properties.
3) Paste the generated CSS into the Custom CSS field and click OK.
Because the CSS lives in OBS, the SE editor preview will not show your styling —
check it in OBS. Also keep the widget's “Show messages permanently”
setting ON — the generated CSS has its own “Hide after” fade-out
(Animation & lifetime panel), and two competing timers would fight. Its classes are .chat-line, .username,
.message, with badges as img.badge.moderator etc. Usernames are
inline-colored per user, so recoloring them requires !important (this studio
handles that). There is no per-user color variable — row tinting can only be fixed
or role-based.
Capability differences — per-user row tinting (“each chatter's own color”
on Role Cards) only works on the Chat Box widget. Role detection on the Chat Box widget is
best-effort: its DOM isn't publicly documented, so the generated CSS matches badges by
both alt and src. If role colors/chips don't show on your real
overlay, open DevTools on the overlay URL, inspect a badge <img>, and
adjust the selectors (see docs/RESEARCH.md in the project).
Getting it into OBS
Your SE overlay URL never changes. For the Chat Box widget the CSS is saved inside SE;
for the native widget it lives in the OBS browser source (see above). After saving,
right-click the browser source in OBS → Refresh if it doesn't update on its own.
Role-based styling uses the CSS :has() selector, supported by OBS 31+
(OBS 28–30 ship an older Chromium and will ignore the role rules — names then keep
their normal Twitch colors) and by the SE editor preview.
Testing
In the SE overlay editor use Emulate Chat Message (bottom bar) to see styled messages
without going live. The preview in this studio is a faithful mock of each widget's real DOM,
but always sanity-check in the SE editor before streaming.
Filtering — already built into StreamElements
Hiding !commands, ignoring bots (StreamElements, Nightbot, Streamer.bot…),
and per-user ignore lists are native SE widget settings, not CSS — find them in the
widget's settings panel (Chat Box: “hide command messages” + ignored-users list).
Set them there; this studio deliberately doesn't duplicate them.
Wheel chat & the widget box
The wheel bends your chat around an off-screen hub — and it happens inside the
widget box you draw (in the SE editor for the Chat Box widget; the native widget
fills its box the same way). Two rules of thumb:
1) Draw the box big — at least 600×500. The curve needs sideways room;
in a narrow column (250–350px) the cars get squeezed thin and the fan can't
spread. Use the preview's Box selector to see exactly how your box size behaves
before you commit.
2) Wheel messages are fixed-size “cars”: at most 2 lines each
(longer messages get an ellipsis), roughly 3–5 visible depending on radius —
a bigger Wheel curve radius fits more cars. This is what keeps the wheel from
ever stacking on itself.
3) Cars dissolve as they ride up the rim — the deepest one is a faint ghost
before it ever reaches the edge of the box, so messages fade away rather than getting
chopped mid-sentence at a border.
OBS tips
Keep the browser source's “Shutdown source when not visible” OFF (hidden
scenes throttle JS timers; overlays resync when shown, but shutdown resets them entirely).
A browser-source FPS of 30 is plenty for chat. Fewer, bigger browser sources (one SE overlay
with several widgets) perform better than many small ones.
Custom images — badge art & bubble images
Both take a direct image link (the URL opens the bare image, not a page
around it — i.imgur.com/….png works; Discord attachment links expire and will
quietly break). Ideal sizes: badge art — square transparent PNG,
72×72 px or larger (128×128 is a safe pick; badges render at
~18–36 px, bigger art just means crisper edges). Bubble image —
transparent PNG around 800×200 px (row-shaped at double size), then
pick a fit: Stretch for bubble/frame art, Fill for photos,
Tile for patterns. Keep files under ~100 KB — they load every time chat
renders. The full walkthrough is in the How to use tab, section 4.
Saving your work
Save preset stores your current settings in this browser (localStorage).
Presets can be re-applied, renamed via re-save, or deleted. The generated CSS itself is
always visible in the right panel — you can also keep a copy anywhere you like.
Browser storage can be wiped (clearing browsing data, a new computer, another browser) —
so the Backups button in the top bar saves everything you've made in the whole
studio (chat styles, rotator designs, QR settings, all saved presets) as one file, and
restores it anywhere. On Chrome and Edge you can also link a vault file that
auto-saves itself on every change — set it once and never think about it again.