{"id":"l-rn-2-2","courseId":"react-native-apps","lang":"en","kind":"lesson","summary":"Lay out Trailhead’s list rows and screens with flexbox, knowing the mobile defaults (column direction, no shrinking, stretch) that explain most squashed or overflowing layouts.","html":"<p>Here’s a layout bug every web developer hits in their first week of React Native: a row with an icon, a title and a chevron looks perfect with “Ridge Loop” and breaks with “Old Mill Creek Trail to Eagle Point Lookout”. The chevron vanishes off the right edge. Nothing is wrong with your flexbox knowledge; React Native’s flexbox simply starts from different defaults.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Same flexbox, different defaults</h2>\n<p>React Native lays out every View with flexbox (via Yoga, a layout engine that implements the spec). There’s no <code dir=\"ltr\">display: block</code> or <code dir=\"ltr\">inline</code>; every View is a flex container. Four defaults differ from the web:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"Scrollable table\" tabindex=\"0\"><table><thead>\n<tr>\n<th>Property</th>\n<th>Web default</th>\n<th>React Native default</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code dir=\"ltr\">flexDirection</code></td>\n<td><code dir=\"ltr\">row</code></td>\n<td><code dir=\"ltr\">column</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">flexShrink</code></td>\n<td><code dir=\"ltr\">1</code></td>\n<td><code dir=\"ltr\">0</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">alignContent</code></td>\n<td><code dir=\"ltr\">normal</code></td>\n<td><code dir=\"ltr\">flex-start</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">flex</code></td>\n<td>a shorthand</td>\n<td>a single number</td>\n</tr>\n</tbody>\n</table></div><p>The first two explain most surprises. Children stack vertically unless you say <code dir=\"ltr\">flexDirection: 'row'</code>, and they <strong>don’t shrink</strong> when space runs out, which is why that long title pushed the chevron away.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 260\" role=\"img\" aria-labelledby=\"l-rn-2-2-t1\"><defs><marker id=\"arrow-l-rn-2-2-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-rn-2-2-t1\">In a column, the main axis runs top to bottom and justifyContent works vertically while alignItems works horizontally. In a row, the main axis runs left to right and the roles swap.</title>\n  <text class=\"d-label-strong\" x=\"160\" y=\"24\" text-anchor=\"middle\">flexDirection: 'column' (default)</text>\n  <rect class=\"d-box\" x=\"70\" y=\"40\" width=\"180\" height=\"200\" rx=\"12\"/>\n  <rect class=\"d-box-primary\" x=\"90\" y=\"58\" width=\"140\" height=\"36\" rx=\"8\"/>\n  <rect class=\"d-box-primary\" x=\"90\" y=\"104\" width=\"140\" height=\"36\" rx=\"8\"/>\n  <rect class=\"d-box-primary\" x=\"90\" y=\"150\" width=\"140\" height=\"36\" rx=\"8\"/>\n  <path class=\"d-arrow\" d=\"M40 50 L40 225\" marker-end=\"url(#arrow-l-rn-2-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"30\" y=\"140\" text-anchor=\"middle\" transform=\"rotate(-90 30 140)\">main: justifyContent</text>\n  <path class=\"d-arrow d-dashed\" d=\"M80 225 L240 225\" marker-end=\"url(#arrow-l-rn-2-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"160\" y=\"214\" text-anchor=\"middle\">cross: alignItems</text>\n  <text class=\"d-label-strong\" x=\"500\" y=\"24\" text-anchor=\"middle\">flexDirection: 'row'</text>\n  <rect class=\"d-box\" x=\"370\" y=\"40\" width=\"270\" height=\"140\" rx=\"12\"/>\n  <rect class=\"d-box-accent\" x=\"386\" y=\"60\" width=\"56\" height=\"56\" rx=\"8\"/>\n  <rect class=\"d-box-accent\" x=\"454\" y=\"60\" width=\"130\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-label\" x=\"519\" y=\"93\" text-anchor=\"middle\">flex: 1</text>\n  <rect class=\"d-box-accent\" x=\"596\" y=\"60\" width=\"30\" height=\"56\" rx=\"8\"/>\n  <path class=\"d-arrow\" d=\"M380 205 L630 205\" marker-end=\"url(#arrow-l-rn-2-2-1)\"/>\n  <text class=\"d-label-muted\" x=\"505\" y=\"228\" text-anchor=\"middle\">main: justifyContent</text>\n  <path class=\"d-arrow d-dashed\" d=\"M655 50 L655 170\" marker-end=\"url(#arrow-l-rn-2-2-1)\"/>\n</svg><figcaption>Main axis and cross axis in a column and a row</figcaption></figure>\n<p>The rules you know still hold: <code dir=\"ltr\">justifyContent</code> works along the main axis, <code dir=\"ltr\">alignItems</code> across it. In a column (the default), <code dir=\"ltr\">justifyContent: 'center'</code> centers vertically and <code dir=\"ltr\">alignItems: 'center'</code> centers horizontally. Switch to a row and the two swap.</p>\n<p><code dir=\"ltr\">alignItems</code> defaults to <code dir=\"ltr\">stretch</code>, so a child in a column fills the full width unless you give it a width or change <code dir=\"ltr\">alignItems</code>. That’s why a <code dir=\"ltr\">Text</code> with a background color in a plain column stretches edge to edge.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">flex: 1, the property you’ll type most</h2>\n<p>In React Native, <code dir=\"ltr\">flex</code> takes a single number. <code dir=\"ltr\">flex: 1</code> means “grow to fill the remaining space along the main axis, and you may shrink”. Two places need it almost always:</p>\n<ol>\n<li><strong>The root View of every screen</strong>, so it fills the screen instead of hugging its content.</li>\n<li><strong>Every parent of a ScrollView or FlatList</strong>, because a scroll container scrolls within the height it’s given. If no ancestor bounds that height, it grows to its full content and the bottom gets cut off without ever scrolling.</li>\n</ol>\n<p>When a screen renders as a thin strip at the top, or a list won’t scroll, walk up the tree and look for the missing <code dir=\"ltr\">flex: 1</code>.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">Building the hike row</h2>\n<p>Here’s the row that broke, fixed:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"tsx\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">src/components/HikeRow.tsx</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { Image, StyleSheet, Text, View } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'react-native'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">export</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> HikeRow</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ </span><span style=\"color:#953800;--shiki-dark:#FFA657\">hike</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#953800;--shiki-dark:#FFA657\">hike</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#953800;--shiki-dark:#FFA657\">name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> string</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#953800;--shiki-dark:#FFA657\">distanceKm</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> number</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#953800;--shiki-dark:#FFA657\">date</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> string</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; </span><span style=\"color:#953800;--shiki-dark:#FFA657\">thumbUrl</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> string</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } }) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.row</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Image</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> source</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{ uri: hike.thumbUrl }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.thumb</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> /></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.body</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">        &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.title</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> numberOfLines</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">hike.name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">        &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.meta</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">hike.distanceKm</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> km · </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">hike.date</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      &#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.chevron</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>›&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    &#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  );</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> styles</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> StyleSheet.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">create</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  row: { flexDirection: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'row'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, alignItems: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'center'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, gap: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, padding: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  thumb: { width: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">56</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, height: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">56</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, borderRadius: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">8</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  body: { flex: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  title: { fontSize: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">17</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, fontWeight: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'600'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  meta: { fontSize: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">14</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, color: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'#5c6b62'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, marginTop: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  chevron: { fontSize: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">24</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, color: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'#9aa79f'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">});</span></span></code></pre></div>\n<p>Read it axis by axis. The row’s main axis is horizontal; <code dir=\"ltr\">alignItems: 'center'</code> centers the three children vertically against the tallest one (the thumbnail). The thumbnail and chevron have fixed sizes. The body has <code dir=\"ltr\">flex: 1</code>, so it takes whatever width is left, and <code dir=\"ltr\">numberOfLines={1}</code> truncates a long name with an ellipsis instead of pushing the chevron off screen.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Fixing overflow with a fixed width</span></p>\n<p>Setting <code dir=\"ltr\">width: 220</code> on the title fits your test phone and breaks on a small Android phone, in landscape, and for users with larger text. Let flex distribute the space: fixed sizes for things that really are fixed (icons, thumbnails), <code dir=\"ltr\">flex: 1</code> for the part that should absorb the difference.</p>\n</aside>\n<p>Two more tools round out everyday layout. <code dir=\"ltr\">alignSelf</code> lets one child break from its parent’s <code dir=\"ltr\">alignItems</code>: a “Log a hike” button in a stretched column can use <code dir=\"ltr\">alignSelf: 'flex-end'</code> to sit on the right at its natural width. And <code dir=\"ltr\">aspectRatio</code> sizes a box from one dimension, which is ideal for photos: give the trail photo <code dir=\"ltr\">width: '100%'</code> and <code dir=\"ltr\">aspectRatio: 4 / 3</code>, and its height follows the screen width on every phone without you calculating anything.</p>\n<p>When a layout misbehaves, the fastest debugging trick is still the oldest one: give the suspect Views a temporary bright background color. You’ll see at once which box is too small, which one stretched, and which one never got its <code dir=\"ltr\">flex: 1</code>.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Absolute positioning and wrapping</h2>\n<p>Every View is <code dir=\"ltr\">position: 'relative'</code> by default, so <code dir=\"ltr\">position: 'absolute'</code> places a child relative to its parent. That’s how you put a “New” badge on the corner of a thumbnail:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"tsx\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">TSX</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Image</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> source</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{ uri: hike.thumbUrl }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">styles.thumb</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> /></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{ position: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'absolute'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, top: </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, right: </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, backgroundColor: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'#e8590c'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, borderRadius: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">8</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, paddingHorizontal: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">6</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{ color: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'white'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, fontSize: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">11</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, fontWeight: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'700'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>NEW&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  &#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span></code></pre></div>\n<p>For a row of tag chips (“steep”, “lake”, “dog-friendly”) that should flow onto a second line when they run out of room, combine <code dir=\"ltr\">flexDirection: 'row'</code>, <code dir=\"ltr\">flexWrap: 'wrap'</code> and <code dir=\"ltr\">gap: 8</code>. Absolute positioning takes the child out of the flex flow entirely, so use it for overlays only, never to fake a layout that flex can express.</p>\n<p>Next you’ll make these layouts hold up across phone sizes, notches, rounded corners and the two platforms’ differences.</p>\n","toc":[{"id":"sec-1","text":"Same flexbox, different defaults","level":2},{"id":"sec-2","text":"flex: 1, the property you’ll type most","level":2},{"id":"sec-3","text":"Building the hike row","level":2},{"id":"sec-4","text":"Absolute positioning and wrapping","level":2}],"takeaways":["Every View is a flex container, and the main axis runs top to bottom by default (<code dir=\"ltr\">flexDirection: 'column'</code>).","<code dir=\"ltr\">justifyContent</code> positions children along the main axis; <code dir=\"ltr\">alignItems</code> positions them across it and defaults to <code dir=\"ltr\">stretch</code>.","Children don’t shrink by default in React Native, so a long title pushes its siblings off screen until you give it <code dir=\"ltr\">flex: 1</code>.","<code dir=\"ltr\">flex: 1</code> means take the remaining space; a screen’s root View and every parent of a ScrollView need it.","Use <code dir=\"ltr\">position: 'absolute'</code> for overlays like badges, and <code dir=\"ltr\">flexWrap: 'wrap'</code> with <code dir=\"ltr\">gap</code> for chip rows."],"further":[{"title":"Layout with Flexbox","url":"https://reactnative.dev/docs/flexbox"},{"title":"Layout Props","url":"https://reactnative.dev/docs/layout-props"}],"quiz":[{"q":"<p>A row has a 56-point thumbnail, a title and a chevron. Long hike names push the chevron off the right edge. What’s the fix?</p>","options":[{"text":"Add <code dir=\"ltr\">flexWrap: 'wrap'</code> to the row.","why":"Wrapping moves the chevron to a second line, which is a different broken layout."},{"text":"Give the title’s container <code dir=\"ltr\">flex: 1</code> so it takes only the space left over and its text wraps or truncates.","why":"Correct. Children don’t shrink by default, and <code dir=\"ltr\">flex</code> set to 1 makes the middle column absorb the remaining width instead of demanding its full text width."},{"text":"Set <code dir=\"ltr\">overflow: 'hidden'</code> on the row.","why":"That clips the chevron instead of making room for it."},{"text":"Give the chevron <code dir=\"ltr\">flex: 1</code>.","why":"That makes the chevron grow to fill space, which is the opposite of what you want."}],"answer":1},{"q":"<p>In a View with default styles, you set <code dir=\"ltr\">justifyContent: 'center'</code>. Where do the children go?</p>","options":[{"text":"Centered horizontally, in a row.","why":"That’s the web default, where <code dir=\"ltr\">flex-direction</code> is <code dir=\"ltr\">row</code>. React Native defaults to <code dir=\"ltr\">column</code>."},{"text":"Nowhere different, because <code dir=\"ltr\">justifyContent</code> needs <code dir=\"ltr\">display: 'flex'</code> first.","why":"Every View is already a flex container, so there’s nothing to turn on."},{"text":"Centered vertically, stacked in a column.","why":"Correct. The main axis is vertical by default, so <code dir=\"ltr\">justifyContent</code> centers along it."}],"answer":2},{"q":"<p>Trailhead’s detail screen is a ScrollView inside a View, and it won’t scroll; the content is simply cut off. What’s the likely cause?</p>","options":[{"text":"The outer View has no <code dir=\"ltr\">flex: 1</code>, so the ScrollView has no bounded height to scroll within.","why":"Correct. A ScrollView scrolls inside the space its parent gives it; without a bounded height it grows to its content and gets cut off by the screen."},{"text":"ScrollView needs <code dir=\"ltr\">scrollEnabled={true}</code> to scroll.","why":"It’s already <code dir=\"ltr\">true</code> by default. You’d set it to <code dir=\"ltr\">false</code> to disable scrolling."},{"text":"ScrollView can only scroll horizontally on Android.","why":"It scrolls vertically on both platforms by default; <code dir=\"ltr\">horizontal</code> switches the direction."}],"answer":0}],"exercise":{"kind":"fill","language":"tsx","template":"const styles = StyleSheet.create({\n  screen: { {{0}}: 1, backgroundColor: '#f6f8f6' },\n  row: {\n    flexDirection: '{{1}}',\n    alignItems: '{{2}}',\n    gap: 12,\n    padding: 12,\n  },\n  thumb: { width: 56, height: 56, borderRadius: 8 },\n  body: { flex: {{3}} },\n  chips: { flexDirection: 'row', flexWrap: '{{4}}', gap: 8 },\n  badge: { position: '{{5}}', top: -4, right: -4 },\n});","blanks":[{"answers":["flex"]},{"answers":["row"]},{"answers":["center"]},{"answers":["1"]},{"answers":["wrap"]},{"answers":["absolute"]}],"title":"Style the hike row","prompt":"<p>Complete Trailhead’s list styles so that:</p>\n<ol>\n<li>the screen fills the whole display,</li>\n<li>each row lays out the thumbnail, text and chevron <strong>side by side</strong>, vertically centered,</li>\n<li>the text column takes the leftover width so long names don’t push the chevron away,</li>\n<li>difficulty chips flow onto a second line when they run out of room,</li>\n<li>the “NEW” badge sits on the thumbnail’s corner without affecting layout.</li>\n</ol>\n","hints":["React Native’s default direction is a column. Which value puts children side by side?","The property that makes a View take the remaining space takes a single number.","Chips that should flow onto the next line need a wrap value; an overlay is taken out of the flex flow by its position value."],"explanation":"<p><code dir=\"ltr\">flex: 1</code> on the screen fills the display. The row switches the main axis with <code dir=\"ltr\">flexDirection: 'row'</code>, and <code dir=\"ltr\">alignItems: 'center'</code> centers children across it (vertically). <code dir=\"ltr\">flex: 1</code> on the body absorbs the leftover width, which matters because children don’t shrink by default. <code dir=\"ltr\">flexWrap: 'wrap'</code> lets chips flow, and <code dir=\"ltr\">position: 'absolute'</code> places the badge relative to its parent without taking up space.</p>\n","checkLabels":{}},"words":717,"readMinutes":3}