Styles class. This approach gives you autocomplete, type checking, and eliminates typos in CSS property names.
Inline Styles
The most common way to style components is using theStyles class with inline styles:
import 'package:jaspr/jaspr.dart';
import 'package:jaspr/dom.dart';
div(
styles: Styles(
backgroundColor: Colors.blue,
padding: Padding.all(16.px),
margin: Margin.symmetric(
horizontal: 20.px,
vertical: 10.px,
),
border: Border.all(
BorderSide(
color: Colors.grey,
width: 1.px,
),
),
radius: BorderRadius.all(Radius.circular(8.px)),
),
[text('Styled content')],
)
The Styles Class
TheStyles class provides type-safe access to CSS properties:
Styles(
// Box Model
width: 200.px,
height: 100.px,
minWidth: 100.px,
maxWidth: 400.px,
padding: Padding.all(16.px),
margin: Margin.only(
top: 10.px,
bottom: 20.px,
),
// Display & Position
display: Display.flex,
position: Position.relative(),
// Colors
color: Colors.black,
backgroundColor: Colors.white,
// Text
fontSize: 16.px,
fontWeight: FontWeight.bold,
textAlign: TextAlign.center,
// Borders
border: Border.all(BorderSide(color: Colors.grey, width: 1.px)),
radius: BorderRadius.circular(8.px),
// Effects
opacity: 0.8,
shadow: BoxShadow(color: Colors.black.withAlpha(0.1)),
// Raw CSS for anything not covered
raw: {
'custom-property': 'value',
},
)
Units
Jaspr provides type-safe CSS units through extension methods on numbers:// Length units
width: 100.px, // pixels
height: 50.percent, // percentage
fontSize: 1.5.rem, // rem
margin: 2.em, // em
// Viewport units
width: 100.vw, // viewport width
height: 100.vh, // viewport height
// Other units
width: 10.cm, // centimeters
width: 5.inches, // inches
Colors
Define colors using theColor class:
// Named colors
Colors.red
Colors.blue
Colors.green
Colors.transparent
// Hex colors
Color.hex('#FF5733')
Color.hex('FF5733') // # is optional
// RGB
Color.rgb(255, 87, 51)
// RGBA (with opacity)
Color.rgba(255, 87, 51, 0.5)
// HSL
Color.hsl(9, 100, 60)
// Modify colors
Colors.blue.withAlpha(0.5)
Colors.red.withOpacity(0.8)
Layout
Flexbox
div(
styles: Styles(
display: Display.flex,
flexDirection: FlexDirection.row,
justifyContent: JustifyContent.spaceBetween,
alignItems: AlignItems.center,
gap: Gap.all(16.px),
),
[/* children */],
)
flexDirection- row, column, rowReverse, columnReverseflexWrap- wrap, nowrap, wrapReversejustifyContent- flexStart, center, spaceBetween, spaceAround, spaceEvenlyalignItems- flexStart, center, flexEnd, stretch, baselinealignContent- flexStart, center, flexEnd, spaceBetween, spaceAround, stretchgap- spacing between flex items
Grid
div(
styles: Styles(
display: Display.grid,
gridTemplate: GridTemplate(
columns: [1.fr, 1.fr, 1.fr],
rows: [200.px, Unit.auto],
),
gap: Gap.all(20.px),
),
[/* grid items */],
)
Positioning
// Relative positioning
Styles(
position: Position.relative(
top: 10.px,
left: 20.px,
),
)
// Absolute positioning
Styles(
position: Position.absolute(
top: 0.px,
right: 0.px,
),
)
// Fixed positioning
Styles(
position: Position.fixed(
bottom: 20.px,
right: 20.px,
),
)
// Sticky positioning
Styles(
position: Position.sticky(
top: 0.px,
),
)
Box Model
Padding
// All sides
padding: Padding.all(16.px)
// Symmetric
padding: Padding.symmetric(
horizontal: 20.px,
vertical: 10.px,
)
// Individual sides
padding: Padding.only(
top: 10.px,
right: 15.px,
bottom: 10.px,
left: 15.px,
)
Margin
// Same API as Padding
margin: Margin.all(16.px)
margin: Margin.symmetric(horizontal: 20.px, vertical: 10.px)
margin: Margin.only(top: 10.px, bottom: 20.px)
// Auto centering
margin: Margin.symmetric(horizontal: Unit.auto)
Borders
// All sides
border: Border.all(
BorderSide(
color: Colors.grey,
width: 2.px,
style: BorderStyle.solid,
),
)
// Individual sides
border: Border.only(
top: BorderSide(color: Colors.red, width: 1.px),
bottom: BorderSide(color: Colors.blue, width: 2.px),
)
// Border radius
radius: BorderRadius.all(Radius.circular(8.px))
radius: BorderRadius.circular(8.px) // shorthand
radius: BorderRadius.only(
topLeft: Radius.circular(10.px),
topRight: Radius.circular(10.px),
)
Typography
Styles(
// Font
fontFamily: FontFamily('Arial, sans-serif'),
fontSize: 16.px,
fontWeight: FontWeight.bold, // or FontWeight.w700
fontStyle: FontStyle.italic,
// Text layout
textAlign: TextAlign.center,
lineHeight: 1.5.em,
letterSpacing: 0.5.px,
wordSpacing: 2.px,
// Text decoration
textDecoration: TextDecoration.underline,
textTransform: TextTransform.uppercase,
// Text overflow
textOverflow: TextOverflow.ellipsis,
whiteSpace: WhiteSpace.nowrap,
// Color
color: Colors.black,
// Shadow
textShadow: TextShadow(
color: Colors.black.withAlpha(0.3),
offset: Offset(2.px, 2.px),
blur: 4.px,
),
)
Effects
Shadows
// Box shadow
shadow: BoxShadow(
color: Colors.black.withAlpha(0.2),
offset: Offset(0.px, 4.px),
blur: 8.px,
spread: 0.px,
)
// Multiple shadows
shadow: BoxShadow.multi([
BoxShadow(color: Colors.black.withAlpha(0.1)),
BoxShadow(color: Colors.blue.withAlpha(0.2), offset: Offset(4.px, 4.px)),
])
Opacity & Visibility
opacity: 0.5 // 0.0 to 1.0
visibility: Visibility.hidden
visibility: Visibility.visible
Transforms
transform: Transform.translate(x: 10.px, y: 20.px)
transform: Transform.scale(1.2)
transform: Transform.rotate(45.deg)
Filters
filter: Filter.blur(5.px)
filter: Filter.brightness(1.2)
filter: Filter.grayscale(0.5)
backdropFilter: Filter.blur(10.px)
Animations & Transitions
// Transitions
transition: Transition(
property: 'all',
duration: Duration(milliseconds: 300),
timingFunction: 'ease-in-out',
)
// Animations
animation: Animation(
name: 'fadeIn',
duration: Duration(seconds: 1),
timingFunction: 'ease-out',
fillMode: 'forwards',
)
CSS Style Rules
For more complex styling scenarios, useStyleRule to define CSS rules:
import 'package:jaspr/jaspr.dart';
class MyApp extends StatelessComponent {
@override
Component build(BuildContext context) {
return Document(
styles: [
// Global styles
css('body')
.text(color: Colors.black)
.box(margin: Margin.zero, padding: Padding.zero)
.raw({'font-family': 'system-ui'}),
// Class selector
css('.container')
.box(
maxWidth: 1200.px,
margin: Margin.symmetric(horizontal: Unit.auto),
padding: Padding.all(20.px),
),
// Hover state
css('button')
.background(color: Colors.blue)
.text(color: Colors.white)
.box(padding: Padding.symmetric(horizontal: 20.px, vertical: 10.px))
.hover(
background: Styles(color: Colors.blue700),
),
// Media queries
css('.responsive')
.box(width: 100.percent)
.media(
MediaQuery.screen(maxWidth: 768.px),
Styles(width: 50.percent),
),
],
body: MyComponent(),
);
}
}
Combining Styles
Combine multipleStyles objects:
final baseStyles = Styles(
padding: Padding.all(16.px),
border: Border.all(BorderSide(color: Colors.grey)),
);
final specialStyles = Styles(
backgroundColor: Colors.blue,
color: Colors.white,
);
// Combine them
final combined = Styles.combine([baseStyles, specialStyles]);
// Or use the combine method
final also = baseStyles.combine(specialStyles);
Complete Example
import 'package:jaspr/jaspr.dart';
import 'package:jaspr/dom.dart';
class StyledCard extends StatelessComponent {
const StyledCard({
required this.title,
required this.content,
this.highlighted = false,
super.key,
});
final String title;
final String content;
final bool highlighted;
@override
Component build(BuildContext context) {
return article(
styles: Styles(
display: Display.flex,
flexDirection: FlexDirection.column,
gap: Gap.all(12.px),
padding: Padding.all(24.px),
backgroundColor: highlighted ? Colors.blue50 : Colors.white,
border: Border.all(
BorderSide(
color: highlighted ? Colors.blue : Colors.grey300,
width: 2.px,
),
),
radius: BorderRadius.circular(12.px),
shadow: BoxShadow(
color: Colors.black.withAlpha(0.1),
offset: Offset(0.px, 2.px),
blur: 8.px,
),
transition: Transition(
property: 'all',
duration: Duration(milliseconds: 200),
),
),
[
h3(
styles: Styles(
margin: Margin.zero,
fontSize: 20.px,
fontWeight: FontWeight.bold,
color: highlighted ? Colors.blue900 : Colors.black,
),
[text(title)],
),
p(
styles: Styles(
margin: Margin.zero,
fontSize: 14.px,
lineHeight: 1.6.em,
color: Colors.grey700,
),
[text(content)],
),
],
);
}
}
Related
HTML Elements
Learn about rendering HTML
Components
Understand the component system
Theming
Implement app-wide themes