Styling & Theming
This page covers comprehensive styling standards for Decentraland web UIs using styled-components with Material UI's styling solution.
Core Principles
Object syntax only - Use object notation for strong TypeScript support
Theme-first - All values come from the UI2 theme
No inline styles - Use styled components for all styling
Typed everything - Leverage TypeScript for props and theme
Responsive by default - Use theme breakpoints
Object Syntax Standard
UI2 components MUST use the object syntax. This ensures strong TypeScript support, csstype validation, and direct theme integration.
Template literal syntax is not allowed. Always use object notation.
Basic Example
// ✅ Good: Object syntax
const Button = styled('button')({
color: 'turquoise',
padding: '8px 16px',
});
// ❌ Bad: Template literal syntax
const Button = styled.button`
color: turquoise;
padding: 8px 16px;
`;With Theme and Props
Rule: Values MUST always come from the UI2 theme. Arbitrary hex codes or pixel values are not allowed.
Element Syntax
When styling native HTML elements, always use the function call form styled('tag').
Correct Syntax
Incorrect Syntax
No Inline Styles
Inline styles (style={...}) MUST NOT be used in UI2 components.
Why Not Inline Styles?
Bypass theme typing
Harder to maintain
Prevent reusability
Can't be optimized
No TypeScript validation
The Right Way
Breakpoints
Use theme.breakpoints helpers instead of hardcoded pixel values.
Breakpoint Helpers
up(key)
theme.breakpoints.up('md')
Min-width and up
down(key)
theme.breakpoints.down('md')
Max-width and down
between(start, end)
theme.breakpoints.between('sm', 'lg')
Between two breakpoints
only(key)
theme.breakpoints.only('md')
Only at this breakpoint
Examples
Multiple Breakpoints
Spacing Scale
Use theme.spacing exclusively for margins, paddings, and gaps.
Spacing Convention
theme.spacing(n)wherenis a numberBase unit is typically 8px
spacing(1)= 8px,spacing(2)= 16px, etc.Decimals allowed:
spacing(1.5)= 12px
Common Spacing Patterns
Z-Index and Stacking
Follow the theme's z-index scale. Never use arbitrary z-index values.
Theme Z-Index Values
Correct Usage
Stacking Context Best Practices
Be conscious of creating new stacking contexts
Avoid unnecessary
position: relativeon parentsDocument why a z-index is needed
If you need a new layer, add it to the theme first
Color Tokens
Always consume colors from theme.palette and dclColors. No ad-hoc hex values.
Palette Structure
Decentraland Colors
Examples
Interactive States
All interactive controls MUST show visible states for hover, focus, active, and disabled.
Complete Interactive Component
Focus-Visible Pattern
Always use :focus-visible instead of :focus to avoid showing focus rings on mouse clicks:
Typography
Use theme typography variants instead of custom font properties.
Performance Optimization
Don't Create Styled Components in Render
Memoize Derived Props
Naming Conventions
Component Names
PascalCase for components
Descriptive names
File Structure
Next Steps
Review Custom Components for component creation guidelines
See Migration Guide for UI1 to UI2 migrations
Check Process Overview for the complete workflow
Last updated