Chapter 04 — Styling & Flexbox

Chapter 04 — Styling & Flexbox

Hey everyone! Welcome back to Namaste React Native!

On the web you write CSS in .css files. In React Native there are no CSS files — styles are plain JavaScript objects. Layout is done entirely with Flexbox, but with a few important differences from the web. Let's make styling feel natural.

What we will cover:

  • StyleSheet.create — how styling works
  • Styles are JS objects (camelCase, numbers)
  • Flexbox in RN — and the default that surprises everyone
  • Dimensions & responsive layout
  • Platform-specific styles
  • Common gotchas
  • Interview Questions

1. Styles Are JavaScript Objects

┌─────────────────────────────────────────────────────────────┐
│   WEB CSS                    REACT NATIVE                    │
├─────────────────────────────────────────────────────────────┤
│   background-color: red;  →  backgroundColor: 'red'         │
│   font-size: 16px;        →  fontSize: 16   (number, no px) │
│   margin-top: 10px;       →  marginTop: 10                  │
│                                                             │
│   • camelCase property names                                │
│   • values are numbers (pixels) or strings                  │
│   • no units — numbers are density-independent pixels       │
└─────────────────────────────────────────────────────────────┘
import { StyleSheet, View, Text } from 'react-native';

function Card() {
    return (
        <View style={styles.card}>
            <Text style={styles.title}>Hello</Text>
        </View>
    );
}

const styles = StyleSheet.create({
    card: {
        padding: 16,
        backgroundColor: '#fff',
        borderRadius: 8,
    },
    title: {
        fontSize: 18,
        fontWeight: 'bold',
        color: '#333',
    },
});

Why StyleSheet.create? It validates your styles and is slightly optimized, but a plain object works too. You can also combine styles with an array: style={[styles.card, styles.active]}.


2. Flexbox — The Default That Surprises Everyone

React Native uses Flexbox for ALL layout. But there's one big difference from the web:

┌─────────────────────────────────────────────────────────────┐
│   WEB Flexbox default:   flexDirection: 'row'    (→)        │
│   RN  Flexbox default:   flexDirection: 'column' (↓)        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   On mobile, things stack VERTICALLY by default —          │
│   which makes sense for tall phone screens!                 │
│                                                             │
│   column (default ↓)          row (→)                       │
│   ┌───────┐                   ┌───┬───┬───┐                 │
│   │   A   │                   │ A │ B │ C │                 │
│   ├───────┤                   └───┴───┴───┘                 │
│   │   B   │                                                 │
│   ├───────┤                                                 │
│   │   C   │                                                 │
│   └───────┘                                                 │
└─────────────────────────────────────────────────────────────┘

The key Flexbox properties (same names as the web):

PropertyControlsCommon values
flexDirectionMain axis direction'column' (default), 'row'
justifyContentAlign along main axisflex-start, center, space-between
alignItemsAlign along cross axisflex-start, center, stretch
flexHow much space to take1 (fill available space)
gapSpace between childrenany number
// Center a child both ways — the classic pattern:
const styles = StyleSheet.create({
    container: {
        flex: 1,                    // fill the whole screen
        justifyContent: 'center',   // center vertically (main axis)
        alignItems: 'center',       // center horizontally (cross axis)
    },
});

3. flex: 1 — "Take All Available Space"

flex: 1 is the most-used property in RN. It tells a component to grow and fill the available space. flex: 1 on the root view = "use the whole screen."

   Two views, both flex: 1 → they split space 50/50:
   ┌──────────────┐
   │   View A     │  flex: 1
   │  (50%)       │
   ├──────────────┤
   │   View B     │  flex: 1
   │  (50%)       │
   └──────────────┘

   flex: 2 vs flex: 1 → 2/3 and 1/3 split.

4. Dimensions & Responsive Layout

import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

// Use percentages for responsive widths:
const styles = StyleSheet.create({
    half: { width: '50%' },
    full: { width: '100%' },
    box:  { width: width * 0.9 },   // 90% of screen width
});

Prefer percentages and flex over hard-coded pixel widths so your layout adapts to different screen sizes.


5. Platform-Specific Styles

Sometimes iOS and Android need different values (e.g. shadows work differently). Use the Platform module.

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
    box: {
        padding: 16,
        // shadow: iOS uses shadow*, Android uses elevation
        ...Platform.select({
            ios:     { shadowColor: '#000', shadowOpacity: 0.2, shadowRadius: 4 },
            android: { elevation: 4 },
        }),
    },
});

6. Common Gotchas

✗ No cascading! Styles do NOT inherit (except some Text props).
  Each component needs its own style.

✗ No shorthand like "margin: 10px 20px". Use marginVertical /
  marginHorizontal, or set each side.

✗ No display: grid. Flexbox only.

✗ Shadows: iOS uses shadowColor/Opacity/Radius; Android uses
  elevation. Handle both.

✗ Numbers are unitless (density-independent pixels), not "px".

Interview Questions — Quick Fire!

Q: How is styling different in React Native vs the web?

"There are no CSS files — styles are JavaScript objects with camelCase properties and unitless numbers, typically created with StyleSheet.create. There's no cascade or inheritance, so each component needs its own styles, and layout is done entirely with Flexbox rather than the full CSS box model."

Q: What's the default flexDirection in React Native and why?

"It's column, not row like the web. That means children stack vertically by default, which suits tall mobile screens. Beginners coming from the web often forget this and wonder why items aren't side by side."

Q: What does flex: 1 do?

"It tells a component to grow and take all the available space along the main axis. Putting flex: 1 on the root view makes it fill the whole screen. Sibling views with flex values share space proportionally — two flex: 1 views split it 50/50."

Q: How do you center a component both horizontally and vertically?

"On the container, set flex: 1 to fill the space, justifyContent: 'center' to center along the main axis, and alignItems: 'center' to center along the cross axis. That's the standard centering pattern."

Q: How do you handle iOS vs Android style differences?

"Use the Platform module — Platform.OS to branch, or Platform.select to provide per-platform style objects. A common case is shadows: iOS uses shadowColor/Opacity/Radius while Android uses elevation."


Quick Recap

ConceptKey Takeaway
StylesJS objects, camelCase, unitless numbers.
StyleSheet.createValidates & organizes styles.
flexDirectionDefaults to 'column' (not 'row').
flex: 1Fill available space.
No cascadeStyles don't inherit.
PlatformBranch styles for iOS vs Android.

What's Next?

Chapter 05: Handling Touches & Input — mobile is touch-first. We'll wire up Pressable buttons, controlled TextInputs, and handle the on-screen keyboard.

Keep coding, keep shipping! See you in the next one!