or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accessibility.mdanimation.mdcore-utilities.mdform-controls.mdhooks.mdindex.mdinteractive-components.mdlayout-components.mdlist-components.mdmedia-components.mdplatform-apis.mdstylesheet.mdsystem-integration.mdtext-input.md

stylesheet.mddocs/

0

# StyleSheet

1

2

React Native's styling system adapted for web with CSS-in-JS compilation, atomic CSS generation, RTL support, and comprehensive performance optimizations.

3

4

## StyleSheet

5

6

The main StyleSheet API that provides style creation, composition, and optimization utilities with automatic CSS generation and browser compatibility.

7

8

```javascript { .api }

9

const StyleSheet: {

10

create: <T>(styles: T) => T;

11

flatten: (...styles: any[]) => ComputedStyle;

12

compose: (style1: any, style2: any) => any[];

13

absoluteFill: ViewStyle;

14

absoluteFillObject: ViewStyle;

15

hairlineWidth: number;

16

getSheet: () => { id: string, textContent: string };

17

};

18

```

19

20

**Core Methods:**

21

22

### create()

23

Creates and optimizes style objects, generating atomic CSS classes for performance.

24

25

```javascript { .api }

26

StyleSheet.create<T>(styles: T): T

27

```

28

29

**Usage:**

30

```javascript

31

import { StyleSheet } from "react-native-web";

32

33

const styles = StyleSheet.create({

34

container: {

35

flex: 1,

36

backgroundColor: '#f5f5f5',

37

padding: 20

38

},

39

header: {

40

fontSize: 24,

41

fontWeight: 'bold',

42

marginBottom: 16,

43

color: '#333'

44

},

45

button: {

46

backgroundColor: '#007AFF',

47

paddingHorizontal: 20,

48

paddingVertical: 12,

49

borderRadius: 8,

50

alignItems: 'center'

51

},

52

buttonText: {

53

color: 'white',

54

fontSize: 16,

55

fontWeight: '600'

56

}

57

});

58

59

// Usage in components

60

function MyComponent() {

61

return (

62

<View style={styles.container}>

63

<Text style={styles.header}>Welcome</Text>

64

<TouchableOpacity style={styles.button}>

65

<Text style={styles.buttonText}>Press me</Text>

66

</TouchableOpacity>

67

</View>

68

);

69

}

70

71

// Advanced patterns

72

const createThemedStyles = (theme) => StyleSheet.create({

73

container: {

74

backgroundColor: theme.backgroundColor,

75

flex: 1

76

},

77

text: {

78

color: theme.textColor,

79

fontSize: theme.fontSize

80

},

81

// Raw styles (no atomic compilation)

82

'gradient$raw': {

83

background: `linear-gradient(45deg, ${theme.primary}, ${theme.secondary})`

84

}

85

});

86

```

87

88

### flatten()

89

Flattens an array of style objects into a single style object, resolving overrides and conflicts.

90

91

```javascript { .api }

92

StyleSheet.flatten(...styles: any[]): ComputedStyle

93

```

94

95

**Usage:**

96

```javascript

97

// Flatten multiple styles

98

const baseStyle = { color: 'blue', fontSize: 16 };

99

const overrideStyle = { color: 'red' };

100

const flattenedStyle = StyleSheet.flatten([baseStyle, overrideStyle]);

101

console.log(flattenedStyle); // { color: 'red', fontSize: 16 }

102

103

// Conditional style flattening

104

function ConditionalComponent({ isActive, disabled }) {

105

const computedStyle = StyleSheet.flatten([

106

styles.base,

107

isActive && styles.active,

108

disabled && styles.disabled

109

]);

110

111

return <View style={computedStyle} />;

112

}

113

114

// Style composition utility

115

function createComposedStyle(...styleArrays) {

116

return StyleSheet.flatten(styleArrays.flat());

117

}

118

```

119

120

### compose()

121

Composes two styles into an array (deprecated, use array syntax instead).

122

123

```javascript { .api }

124

StyleSheet.compose(style1: any, style2: any): any[]

125

```

126

127

**Usage:**

128

```javascript

129

// Deprecated approach

130

const composed = StyleSheet.compose(styles.base, styles.variant);

131

132

// Preferred approach

133

const composed = [styles.base, styles.variant];

134

```

135

136

## Constants

137

138

### absoluteFill & absoluteFillObject

139

Pre-defined styles for absolute positioning that fills the parent container.

140

141

```javascript { .api }

142

StyleSheet.absoluteFill: ViewStyle;

143

StyleSheet.absoluteFillObject: {

144

position: 'absolute';

145

left: 0;

146

right: 0;

147

top: 0;

148

bottom: 0;

149

};

150

```

151

152

**Usage:**

153

```javascript

154

// Using the pre-compiled style

155

<View style={StyleSheet.absoluteFill} />

156

157

// Using the object for composition

158

const overlayStyle = StyleSheet.create({

159

overlay: {

160

...StyleSheet.absoluteFillObject,

161

backgroundColor: 'rgba(0,0,0,0.5)',

162

justifyContent: 'center',

163

alignItems: 'center'

164

}

165

});

166

167

// Custom absolute positioning

168

const customAbsolute = StyleSheet.create({

169

positioned: {

170

...StyleSheet.absoluteFillObject,

171

top: 50, // Override top

172

bottom: 50 // Override bottom

173

}

174

});

175

```

176

177

### hairlineWidth

178

The thinnest possible line width (always 1 on web).

179

180

```javascript { .api }

181

StyleSheet.hairlineWidth: 1;

182

```

183

184

**Usage:**

185

```javascript

186

const styles = StyleSheet.create({

187

separator: {

188

height: StyleSheet.hairlineWidth,

189

backgroundColor: '#e0e0e0',

190

marginVertical: 8

191

},

192

border: {

193

borderBottomWidth: StyleSheet.hairlineWidth,

194

borderBottomColor: '#ccc'

195

}

196

});

197

```

198

199

## Advanced Features

200

201

### Dynamic Styling

202

Create responsive and conditional styles efficiently.

203

204

```javascript

205

// Responsive styles

206

function createResponsiveStyles(screenWidth) {

207

const isTablet = screenWidth >= 768;

208

const isDesktop = screenWidth >= 1024;

209

210

return StyleSheet.create({

211

container: {

212

padding: isDesktop ? 32 : isTablet ? 24 : 16,

213

maxWidth: isDesktop ? 1200 : '100%',

214

marginHorizontal: isDesktop ? 'auto' : 0

215

},

216

grid: {

217

flexDirection: isTablet ? 'row' : 'column',

218

flexWrap: isTablet ? 'wrap' : 'nowrap'

219

}

220

});

221

}

222

223

// Theme-based styling

224

function createThemedStyles(isDark) {

225

return StyleSheet.create({

226

container: {

227

backgroundColor: isDark ? '#1a1a1a' : '#ffffff',

228

flex: 1

229

},

230

text: {

231

color: isDark ? '#ffffff' : '#000000'

232

},

233

surface: {

234

backgroundColor: isDark ? '#2d2d2d' : '#f8f9fa',

235

borderColor: isDark ? '#444' : '#e9ecef',

236

borderWidth: 1

237

}

238

});

239

}

240

241

// Usage with hooks

242

function ThemedComponent() {

243

const { width } = useWindowDimensions();

244

const isDark = useColorScheme() === 'dark';

245

246

const styles = useMemo(() => ({

247

...createResponsiveStyles(width),

248

...createThemedStyles(isDark)

249

}), [width, isDark]);

250

251

return (

252

<View style={styles.container}>

253

<Text style={styles.text}>Themed content</Text>

254

</View>

255

);

256

}

257

```

258

259

### Performance Optimization

260

Leverage atomic CSS and compilation for optimal performance.

261

262

```javascript

263

// Atomic class generation

264

const atomicStyles = StyleSheet.create({

265

// Each property becomes an atomic class

266

flex1: { flex: 1 },

267

row: { flexDirection: 'row' },

268

column: { flexDirection: 'column' },

269

center: { alignItems: 'center', justifyContent: 'center' },

270

271

// Colors

272

primaryBg: { backgroundColor: '#007AFF' },

273

secondaryBg: { backgroundColor: '#34C759' },

274

275

// Spacing

276

p4: { padding: 16 },

277

m2: { margin: 8 },

278

mt3: { marginTop: 12 }

279

});

280

281

// Composition for complex layouts

282

const layoutStyles = StyleSheet.create({

283

centeredContainer: {

284

...atomicStyles.flex1,

285

...atomicStyles.center,

286

...atomicStyles.p4

287

}

288

});

289

290

// Raw styles for CSS that can't be atomized

291

const rawStyles = StyleSheet.create({

292

'gradient$raw': {

293

background: 'linear-gradient(45deg, #ff6b6b, #4ecdc4)'

294

},

295

'animation$raw': {

296

'@keyframes fadeIn': {

297

from: { opacity: 0 },

298

to: { opacity: 1 }

299

},

300

animation: 'fadeIn 0.3s ease-in-out'

301

}

302

});

303

```

304

305

### RTL Support

306

Handle right-to-left layouts automatically.

307

308

```javascript

309

// RTL-aware styles

310

const rtlStyles = StyleSheet.create({

311

container: {

312

paddingStart: 16, // Becomes paddingLeft in LTR, paddingRight in RTL

313

paddingEnd: 8, // Becomes paddingRight in LTR, paddingLeft in RTL

314

marginStart: 12 // Auto-flips based on text direction

315

},

316

textAlign: {

317

textAlign: 'start' // Becomes 'left' in LTR, 'right' in RTL

318

}

319

});

320

321

// Manual RTL handling

322

function RTLAwareComponent() {

323

const isRTL = I18nManager.isRTL;

324

325

const styles = StyleSheet.create({

326

container: {

327

paddingLeft: isRTL ? 8 : 16,

328

paddingRight: isRTL ? 16 : 8,

329

flexDirection: isRTL ? 'row-reverse' : 'row'

330

}

331

});

332

333

return <View style={styles.container} />;

334

}

335

```

336

337

### Custom Style Functions

338

Create reusable style generators and utilities.

339

340

```javascript

341

// Style generator functions

342

const createShadow = (elevation = 2) => ({

343

shadowColor: '#000',

344

shadowOffset: {

345

width: 0,

346

height: elevation

347

},

348

shadowOpacity: 0.25,

349

shadowRadius: elevation * 2,

350

elevation // Android

351

});

352

353

const createBorder = (color = '#ccc', width = 1) => ({

354

borderColor: color,

355

borderWidth: width

356

});

357

358

// Usage in StyleSheet

359

const componentStyles = StyleSheet.create({

360

card: {

361

backgroundColor: 'white',

362

borderRadius: 8,

363

padding: 16,

364

...createShadow(3),

365

...createBorder('#e0e0e0')

366

},

367

button: {

368

paddingVertical: 12,

369

paddingHorizontal: 20,

370

borderRadius: 6,

371

...createShadow(1)

372

}

373

});

374

375

// Advanced composition utilities

376

class StyleBuilder {

377

constructor(baseStyle = {}) {

378

this.style = { ...baseStyle };

379

}

380

381

background(color) {

382

this.style.backgroundColor = color;

383

return this;

384

}

385

386

padding(value) {

387

this.style.padding = value;

388

return this;

389

}

390

391

shadow(elevation) {

392

Object.assign(this.style, createShadow(elevation));

393

return this;

394

}

395

396

build() {

397

return this.style;

398

}

399

}

400

401

// Usage

402

const dynamicStyle = new StyleBuilder()

403

.background('#007AFF')

404

.padding(16)

405

.shadow(2)

406

.build();

407

```

408

409

## Server-Side Rendering

410

411

Extract generated CSS for SSR applications.

412

413

```javascript

414

// Get generated CSS

415

const sheet = StyleSheet.getSheet();

416

console.log(sheet.id); // CSS sheet ID

417

console.log(sheet.textContent); // Generated CSS content

418

419

// SSR implementation

420

function renderWithStyles(App) {

421

// Render app

422

const appHtml = ReactDOMServer.renderToString(<App />);

423

424

// Extract styles

425

const { id, textContent } = StyleSheet.getSheet();

426

427

// Include in HTML

428

return `

429

<!DOCTYPE html>

430

<html>

431

<head>

432

<style id="${id}">${textContent}</style>

433

</head>

434

<body>

435

<div id="root">${appHtml}</div>

436

</body>

437

</html>

438

`;

439

}

440

```

441

442

## Best Practices

443

444

```javascript

445

// ✅ Good: Use StyleSheet.create

446

const styles = StyleSheet.create({

447

container: { flex: 1 }

448

});

449

450

// ❌ Avoid: Inline styles (no optimization)

451

<View style={{ flex: 1 }} />

452

453

// ✅ Good: Conditional styles with arrays

454

<View style={[

455

styles.base,

456

isActive && styles.active,

457

{ opacity: isVisible ? 1 : 0 }

458

]} />

459

460

// ✅ Good: Memoize dynamic styles

461

const dynamicStyles = useMemo(() => StyleSheet.create({

462

container: {

463

backgroundColor: theme.background

464

}

465

}), [theme]);

466

467

// ✅ Good: Use constants for reusable values

468

const COLORS = {

469

primary: '#007AFF',

470

secondary: '#34C759',

471

background: '#f8f9fa'

472

};

473

474

const SPACING = {

475

xs: 4,

476

sm: 8,

477

md: 16,

478

lg: 24,

479

xl: 32

480

};

481

482

const styles = StyleSheet.create({

483

container: {

484

backgroundColor: COLORS.background,

485

padding: SPACING.md

486

}

487

});

488

```

489

490

## Types

491

492

```javascript { .api }

493

interface StyleSheetStatic {

494

create: <T extends Record<string, ViewStyle | TextStyle | ImageStyle>>(styles: T) => T;

495

flatten: (...styles: any[]) => ComputedStyle;

496

compose: (style1: any, style2: any) => any[];

497

absoluteFill: ViewStyle;

498

absoluteFillObject: {

499

position: 'absolute';

500

left: 0;

501

right: 0;

502

top: 0;

503

bottom: 0;

504

};

505

hairlineWidth: 1;

506

getSheet: () => { id: string; textContent: string };

507

}

508

509

interface ViewStyle {

510

// Layout

511

flex?: number;

512

flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';

513

justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';

514

alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';

515

516

// Positioning

517

position?: 'absolute' | 'relative' | 'static' | 'fixed' | 'sticky';

518

top?: number | string;

519

right?: number | string;

520

bottom?: number | string;

521

left?: number | string;

522

zIndex?: number;

523

524

// Dimensions

525

width?: number | string;

526

height?: number | string;

527

minWidth?: number | string;

528

maxWidth?: number | string;

529

minHeight?: number | string;

530

maxHeight?: number | string;

531

532

// Spacing

533

margin?: number | string;

534

marginTop?: number | string;

535

marginRight?: number | string;

536

marginBottom?: number | string;

537

marginLeft?: number | string;

538

marginHorizontal?: number | string;

539

marginVertical?: number | string;

540

padding?: number | string;

541

paddingTop?: number | string;

542

paddingRight?: number | string;

543

paddingBottom?: number | string;

544

paddingLeft?: number | string;

545

paddingHorizontal?: number | string;

546

paddingVertical?: number | string;

547

548

// Background

549

backgroundColor?: ColorValue;

550

551

// Border

552

borderWidth?: number;

553

borderTopWidth?: number;

554

borderRightWidth?: number;

555

borderBottomWidth?: number;

556

borderLeftWidth?: number;

557

borderColor?: ColorValue;

558

borderTopColor?: ColorValue;

559

borderRightColor?: ColorValue;

560

borderBottomColor?: ColorValue;

561

borderLeftColor?: ColorValue;

562

borderRadius?: number;

563

borderTopLeftRadius?: number;

564

borderTopRightRadius?: number;

565

borderBottomLeftRadius?: number;

566

borderBottomRightRadius?: number;

567

borderStyle?: 'solid' | 'dotted' | 'dashed';

568

569

// Shadow

570

shadowColor?: ColorValue;

571

shadowOffset?: { width: number; height: number };

572

shadowOpacity?: number;

573

shadowRadius?: number;

574

575

// Transform

576

transform?: Transform[];

577

578

// Other

579

opacity?: number;

580

overflow?: 'visible' | 'hidden' | 'scroll';

581

}

582

583

interface TextStyle extends ViewStyle {

584

color?: ColorValue;

585

fontFamily?: string;

586

fontSize?: number | string;

587

fontWeight?: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';

588

fontStyle?: 'normal' | 'italic';

589

lineHeight?: number | string;

590

letterSpacing?: number | string;

591

textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify';

592

textDecorationLine?: 'none' | 'underline' | 'line-through' | 'underline line-through';

593

textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase';

594

}

595

596

interface ImageStyle extends ViewStyle {

597

resizeMode?: 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';

598

tintColor?: ColorValue;

599

}

600

601

type ComputedStyle = { [key: string]: any };

602

type ColorValue = string;

603

type Transform = { [key: string]: any };

604

```