Styling with Tailwind
You can style an overlay with Tailwind utility classes and never write a stylesheet. But Overlabels does not load Tailwind the way a website does, and knowing how the classes actually become CSS explains every surprise you might hit - including the one where your borders are invisible.
Write class="flex items-center gap-3" in a template and it just works. Underneath, there is no
Tailwind script running in your overlay, and knowing what happens instead is worth two minutes of
your time.
What actually happens when you save
When you save a template, the editor scans everything you wrote - the html field, the head field and the css field - for anything that looks like a utility class. It then compiles only the rules you actually used into a small stylesheet and stores it with the template. When your overlay loads in OBS, that pre-compiled stylesheet is injected and that is the whole story. Nothing is parsed or generated in the browser source.
A typical overlay compiles to a few kilobytes of CSS. The old way of doing this - shipping the entire Tailwind library to the browser and letting it work things out at runtime - made overlays noticeably slower to paint, which matters when the overlay in question is a follower alert that needs to be on screen now.
Three practical consequences:
- Classes compile when you save through the editor. The scan runs on the text you authored, so
a class inside an
[[[if:]]]branch or a[[[foreach:]]]loop compiles fine whether or not that branch renders today. But HTML that arrives any other way is never scanned - there is no runtime compiler to catch it. - A typo'd class silently does nothing.
felxcompiles to no rule and no error, the same philosophy as a typo'd[[[tag]]]rendering as nothing. If a class seems dead, spell-check it first. - Your own CSS always wins. The compiled utilities are injected before your css field's stylesheet, so anything you write by hand overrides a utility class on the same element. The two are meant to mix - utilities for layout, your own CSS for the fancy parts.
It speaks Tailwind v3, not v4
The compiler understands Tailwind v3 class names. If you are pasting from a tutorial, an AI assistant or your own muscle memory, aim for v3 syntax. Everything you would expect works:
- The full core vocabulary:
flex,grid,p-5,mt-4,rounded-xl,text-2xl,font-bold,truncate,uppercase, and so on. - Arbitrary values:
w-[380px],text-[13px],tracking-[0.08em],bg-[rgba(10,10,16,0.72)],border-l-[#a970ff]. - Opacity shorthand:
bg-white/5,border-white/10,text-black/60. - Variants:
hover:,first:,last:,odd:and friends, likelast:border-b-0to drop the divider under the final row of a list. - Fractional spacing:
gap-3.5,py-2.5,mt-0.5.
What does not work:
- Tailwind v4-only syntax. New v4 utility names and v4 CSS conventions will not compile.
- Stylesheet directives.
@apply,@tailwindandtheme()are features of Tailwind's own build tooling, not of class scanning. In your css field, write plain CSS. - A config file. There is no
tailwind.configto extend. The default scale, colors and breakpoints are what you get - and arbitrary values cover everything the defaults do not.
The border gotcha
This is the one that catches people. Tailwind normally ships a "preflight" stylesheet that, among other things, sets every element's border style to solid with zero width. Overlabels deliberately injects no global reset into your overlay - your overlay is your canvas, and a framework reaching in to restyle every element would be rude.
The consequence: border utilities like border, border-2 and border-b set a border width and
color, but browsers default every border's style to none. Width times none is invisible. Your
classes compiled fine, and nothing paints.
Two fixes, pick one:
Add the border-style utility next to your width utilities:
<div class="border border-solid border-white/10">...</div>
Or put Tailwind's own reset line at the top of your css field once, and forget about it:
* { border-style: solid; border-width: 0; }
The second one is what Tailwind itself does, and it makes every border utility in the template
behave exactly as the Tailwind docs describe. Keep both properties together: border-style: solid
alone would give every element a visible default-width border.
Divider lines under list rows are the classic victim. If your border-b border-white/5 rows show
no lines, this is why.
When to just write CSS
Always a fine answer. The css field is plain CSS with no compiler in the way, and several things belong there rather than in classes:
- Font families for a font you loaded in the head field.
- Keyframe animations and anything with
@keyframes. - The transparent-page basics most overlays start with:
html, body { margin: 0; background: transparent; }
Utilities and hand-written CSS coexist happily in one template - and because your stylesheet is injected after the compiled one, you never have to fight the framework to win an argument.
One thing to keep out of the css field: [[[tag]]] values and ?? defaults. A stylesheet with no
tags in it is injected once and left alone, which is the fast path described in
How an overlay renders.