Hi everyone,
I’m trying to understand how CSS priority and override rules work inside OutSystems (Reactive Web). I know CSS normally follows browser rules like specificity and load order, but in OutSystems there are multiple places where styles can be added:
Module Theme
Screen styles
Web Block styles
Global CSS files inside Resources
Inline styles
OutSystems UI default theme
My questions are:
What is the actual priority order of these CSS layers in OutSystems?
If I define the same selector in the Theme and also in a Screen, which one wins?
Do Web Block styles override the Screen or the Theme?
Is there a recommended best practice for where to put custom CSS?
When should !important be used (or avoided) in OutSystems projects?
I want to structure my app so that styling is predictable and easy to maintain, but right now I’m not sure how OutSystems compiles and merges all the CSS.
Any clarification would be greatly appreciated!
Thanks!
Hi @Hieu Le ,
OutSystems follows standard browser CSS rules (cascade, specificity, and load order), but the platform also has its own structure for defining CSS. These different layers load in a predictable order.
Theme CSS (lowest priority)
This includes the styles defined inside your module’s Theme:
OutSystems UI
CustomTheme
Layout styles
Global CSS is defined at the theme level
Since the Theme loads first, all other CSS layers can override it.
Screen CSS
CSS written directly inside a Screen has higher priority than the Theme.
If you define the same selector in both:
/* Theme */
.button { color: blue }/* Screen */.button { color: red }
→ The Screen CSS wins, because it is injected later in the DOM.
Web Block CSS (higher priority than Screen)
When you place a Web Block on a Screen, the Block’s CSS is loaded after the Screen CSS, so it takes priority.
Example:
/* Theme */.title { font-size: 18px }/* Screen */.title { font-size: 20px }/* Web Block */.title { font-size: 24px }
âž¡ The Web Block CSS wins.
This surprises many developers, but it's the expected behavior because OutSystems injects Block CSS last.
Inline Styles (highest priority)
Inline styles always override:
OutSystems recommends avoiding inline styles unless necessary.
CSS Priority Summary (lowest → highest)
Theme CSS
Web Block CSS
If two selectors are equal, CSS specificity still applies (IDs > classes > tags).
Hope this helps,
Peter Hieu.
Thank for your answear.
@Peter Hieu ,
"This surprises many developers, but it's the expected behavior because OutSystems injects Block CSS last. "
That sure surprised me, but that's because it is incorrect. A block css gets loaded even before the theme CSS, and so same selector in either a theme or a screen will override your block selector.
"If two selectors are equal, CSS specificity still applies (IDs > classes > tags)."
This sentence doesn't make sense to me, if they are equal, they have the same CSS specificity. You probably mean if they target the same element ?
@David Le ,
it is also worth knowing
Oh and, I guess these rules are not specific for OutSystems:
- inline styles are to be avoided
- !important even more so
Thanks for the clarification — this helps clear up the confusion.
You're right: Block CSS does not load last. In OutSystems, the loading order is:
1. Base Theme
2. Child Theme / Application Theme
3. Screen CSS
4. Block CSS is actually loaded before the Theme CSS
So if a Theme or a Screen uses the same selector, it will override the Block CSS simply because it is loaded later in the cascade.
Also thanks for the extra notes on theme hierarchy and the two sections inside an Application Theme. That explains why custom CSS (left section) overrides the Theme Editor section (right).
And absolutely agree on avoiding inline styles and using !important only when strictly necessary — that’s standard best practice, not just OutSystems-specific.
Hi David,
Adding to what Peter said, here are a few links that might help you:
Styles Loading Order
Cascading Style Sheets - CSS