Core Directive
The [sj] directive is the heart of Super-JSS - a powerful CSS-in-JS system that lets you author styles as JavaScript objects directly in your Angular templates. This directive transforms how you write CSS, making it type-safe, theme-aware, and responsive.
Why the Directive Matters
Unlike traditional CSS or even other CSS-in-JS libraries, Super-JSS centers around the [sj] directive as its core primitive. Components are just convenient wrappers around directive usage. The directive gives you:
- Type Safety: Full TypeScript autocomplete for CSS properties
- Theme Integration: Automatic access to colors, spacing, and tokens
- Responsive Design: Built-in breakpoint system
- Performance: Atomic CSS generation with deduplication
- Flexibility: Mix plain CSS with theme values seamlessly
SJ Types: Objects & Arrays
The [sj] directive accepts two primary types:
Single SJ Object
// Type: SjStyle
{
padding: '16px',
backgroundColor: '#f7f7f7',
borderRadius: '8px'
}
Array of SJ Objects (Most Common)
// Type: SjStyle[]
[{ padding: "16px" }, { backgroundColor: "#f7f7f7" }, { borderRadius: "8px" }];
Why arrays? They allow composition, overrides, and logical separation of concerns.
Basic Usage
Inline Objects
<!-- Single object -->
<div
[sj]="{ padding: '24px', backgroundColor: '#f7f7f7', borderRadius: '8px' }"
>
Simple styling with plain CSS values
</div>
<!-- Array of objects -->
<div
[sj]="[
{ padding: '24px' },
{ backgroundColor: '#f7f7f7' },
{ borderRadius: '8px' }
]"
>
Same result, but more composable
</div>
Component Properties
import { SjStyle } from 'super-jss';
@Component({...})
export class MyComponent {
cardStyle: SjStyle = {
padding: '20px',
backgroundColor: '#ffffff',
borderRadius: '12px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
};
spacingStyle: SjStyle = {
margin: '16px',
gap: '12px'
};
}
<!-- Use in template -->
<div [sj]="cardStyle">
<h3>Card Title</h3>
<p>Card content</p>
</div>
<!-- Combine multiple styles -->
<div [sj]="[cardStyle, spacingStyle]">Multiple style objects merged</div>
Recommended Usage
For the best development experience, we recommend using SJ objects with the SJ Root API (sj.*). This approach provides:
- Full IDE autocomplete for CSS properties and theme tokens
- Type safety with TypeScript
- Quick access to theme values and utilities
- Consistent API across your entire application
Objects with sjApi (Recommended)
<!-- Using sj.* functions for autocomplete and theme integration -->
<div
[sj]="[
sj.padding('16px'),
sj.backgroundColor(sj.bg.options.primary.main),
sj.borderRadius('8px'),
sj.color(sj.c.options.primary.contrast)
]"
>
Recommended: sj.* functions with theme tokens
</div>
Why sjRoot Matters
The sj object is attached to your theme and provides:
- Theme-aware values: Access colors, spacing, and tokens via
.options - Quick property access:
sj.p()instead ofsj.padding() - Consistent theming: All values respect your theme configuration
- Autocomplete everywhere: Works inline in templates and in component logic
Plain Objects (Alternative)
<!-- Plain objects still work but lack autocomplete -->
<div
[sj]="[
{ padding: '16px', backgroundColor: '#007acc', borderRadius: '8px' }
]"
>
Alternative: Plain objects (no autocomplete)
</div>
Recommendation: Use sj.* functions for new code. Plain objects are fine for simple cases or when migrating existing styles.
Responsive Design
Super-JSS has built-in responsive breakpoints: xs, sm, md, lg, xl.
Responsive Objects
<div
[sj]="{
padding: { xs: '8px', sm: '16px', md: '24px', lg: '32px' },
fontSize: { xs: '14px', md: '16px' },
display: { xs: 'block', md: 'flex' }
}"
>
Responsive padding, font size, and layout
</div>
Responsive Arrays
<div
[sj]="[
{ padding: { xs: '8px', md: '16px' } },
{ backgroundColor: '#f7f7f7' },
{ borderRadius: { xs: '4px', md: '8px' } }
]"
>
Responsive properties in arrays
</div>
Shorthands & Shortcuts
Super-JSS provides convenient shorthands for common CSS properties:
Spacing Shorthands
<div
[sj]="{
p: '16px', // padding
px: '12px', // padding-left + padding-right
py: '8px', // padding-top + padding-bottom
m: '10px', // margin
mx: '20px', // margin-left + margin-right
my: '15px' // margin-top + margin-bottom
}"
>
Spacing shorthands
</div>
Layout Shorthands
<div
[sj]="{
d: 'flex', // display
fxDir: 'column', // flex-direction
fxJustify: 'center', // justify-content
fxAItems: 'center', // align-items
gap: '12px' // gap
}"
>
Layout shorthands
</div>
Other Common Shorthands
<div
[sj]="{
bg: '#f7f7f7', // background-color
c: '#333333', // color
brad: '8px', // border-radius
w: '100%', // width
h: '200px' // height
}"
>
Common property shorthands
</div>
SJ Root API Integration
The SJ Root API (sj.*) provides semantic, theme-aware values that work seamlessly with the directive:
Theme Colors
<div
[sj]="[
sj.color(sj.color.options.primary.main),
sj.backgroundColor(sj.backgroundColor.options.secondary.light),
sj.padding(sj.padding.options.default)
]"
>
Using theme colors and spacing
</div>
Live Example
If the embed doesn’t load, open it directly: Open on StackBlitz.
Semantic Spacing
<div
[sj]="[
sj.padding(sj.padding.options.compact), // 1 unit
sj.margin(sj.margin.options.default), // 2 units
sj.gap(sj.gap.options.comfortable) // 3 units
]"
>
Semantic spacing from theme
</div>
Border System
<div
[sj]="[
sj.borderWidth(sj.borderWidth.options.default),
sj.borderColor(sj.borderColor.options.primary.main),
sj.borderStyle('solid')
]"
>
Semantic border properties
</div>
Advanced Patterns
Conditional Styling
@Component({...})
export class MyComponent {
isActive = true;
get conditionalStyle(): SjStyle[] {
return this.isActive ? [
{ backgroundColor: '#e3f2fd' },
{ borderColor: '#2196f3' }
] : [
{ backgroundColor: '#f5f5f5' },
{ borderColor: '#cccccc' }
];
}
}
<div [sj]="conditionalStyle">Conditional styling based on component state</div>
Style Composition
@Component({...})
export class MyComponent {
baseCard: SjStyle = {
padding: '16px',
borderRadius: '8px',
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
};
primaryCard: SjStyle = {
backgroundColor: '#ffffff',
border: '1px solid #e0e0e0'
};
secondaryCard: SjStyle = {
backgroundColor: '#f8f9fa',
border: '1px solid #dee2e6'
};
}
<!-- Primary card -->
<div [sj]="[baseCard, primaryCard]">Primary card content</div>
<!-- Secondary card -->
<div [sj]="[baseCard, secondaryCard]">Secondary card content</div>
Dynamic Theming
<!-- Theme-aware button -->
<button
[sj]="[
sj.padding(sj.padding.options.default),
sj.borderRadius(sj.borderRadius.options.default),
sj.color(sj.color.options.primary.contrast),
sj.backgroundColor(sj.backgroundColor.options.primary.main),
sj.border('none'),
sj.cursor('pointer')
]"
>
Theme-aware button
</button>
Performance & Best Practices
✅ Do: Use Arrays for Composition
<!-- Good: Composable -->
<div [sj]="[baseStyles, themeStyles, responsiveStyles]">Content</div>
❌ Avoid: Monolithic Objects
<!-- Avoid: Hard to maintain -->
<div
[sj]="{ padding: '16px', backgroundColor: '#fff', borderRadius: '8px', /* ... 20 more properties */ }"
>
Content
</div>
✅ Do: Extract to Component Properties
// Good: Reusable and testable
export class CardComponent {
cardStyles: SjStyle[] = [
{ padding: "16px" },
{ backgroundColor: "#ffffff" },
{ borderRadius: "8px" },
];
}
✅ Do: Use Theme Values
<!-- Good: Theme-aware -->
<div [sj]="sj.color(sj.color.options.primary.main)">Themed text</div>
❌ Avoid: Hardcoded Colors
<!-- Avoid: Not theme-aware -->
<div [sj]="{ color: '#1976d2' }">Hardcoded color</div>
TypeScript Integration
Super-JSS provides full TypeScript support:
import { SjStyle, SjResponsiveStyle } from "super-jss";
interface MyComponent {
// Single style object
cardStyle: SjStyle;
// Array of styles
combinedStyles: SjStyle[];
// Responsive style
responsiveStyle: SjResponsiveStyle;
// Method returning styles
getDynamicStyles(): SjStyle[];
}
Migration from CSS
Before (Traditional CSS)
/* styles.css */
.card {
padding: 16px;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
@media (min-width: 768px) {
.card {
padding: 24px;
}
}
<div class="card">Card content</div>
After (Super-JSS)
// component.ts
export class CardComponent {
cardStyles: SjStyle = {
padding: { xs: "16px", md: "24px" },
backgroundColor: "#ffffff",
borderRadius: "8px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
};
}
<!-- template.html -->
<div [sj]="cardStyle">Card content</div>
Next Steps
Now that you understand the core directive, explore:
- Directive Basics - Plain CSS usage examples
- Directive Shortcuts - Shorthand properties for common patterns
- SJ Root API - The
sj.*functions for semantic values - Theming - How themes and tokens work
- Components - Pre-built components using the directive
- Quick Start - Put it all together