{"id":"l-fig-2-2","courseId":"figma-ui-design","lang":"en","kind":"lesson","summary":"Control how auto layout frames and their children size themselves with Hug contents, Fill container and Fixed, set min and max limits, wrap chips onto new lines, and pull badges out of the flow.","html":"<p>Your habit row now stacks itself, but test it the way Sofia does: drag the Today frame wider. The rows stay at their old width, leaving a strip of empty screen on the right. Drag it narrower and the check buttons fall off the edge. Stacking is solved; sizing is not.</p>\n<p>In auto layout every layer has two sizing behaviours, one for width and one for height. Get those right and the same row works on any phone, in any language, with any habit name.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Hug, Fill and Fixed</h2>\n<p>You set sizing in the width and height controls of the right sidebar. There are three options.</p>\n<p><strong>Hug contents</strong> makes a frame exactly as big as its children plus padding. A chip that hugs grows when its label changes from “Daily” to “Weekends”. Only frames and text can hug, because only they have contents.</p>\n<p><strong>Fill container</strong> makes a child take all the available space in its auto layout parent along that axis. If two siblings both fill, they share the space equally.</p>\n<p><strong>Fixed</strong> sets an exact size that never changes. Icons and the check button are fixed at 32 × 32 because a check target should not grow or shrink with the text next to it.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 270\" role=\"img\" aria-labelledby=\"l-fig-2-2-t1\"><defs><marker id=\"arrow-l-fig-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-fig-2-2-t1\">Three versions of a row. With the text stack on Hug, the check button sits right after the text. On Fill, the stack stretches and the button sits at the right edge. On Fixed, the stack is a set width and a long name is cut off.</title>\n  <text class=\"d-label-strong\" x=\"20\" y=\"32\">Hug</text>\n  <rect class=\"d-box\" x=\"100\" y=\"12\" width=\"560\" height=\"36\" rx=\"8\"/>\n  <rect class=\"d-box-primary\" x=\"110\" y=\"18\" width=\"24\" height=\"24\" rx=\"6\"/>\n  <rect class=\"d-box-accent\" x=\"144\" y=\"18\" width=\"120\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label\" x=\"152\" y=\"35\">Read</text>\n  <circle class=\"d-dot\" cx=\"286\" cy=\"30\" r=\"12\"/>\n  <text class=\"d-label-strong\" x=\"20\" y=\"122\">Fill</text>\n  <rect class=\"d-box\" x=\"100\" y=\"102\" width=\"560\" height=\"36\" rx=\"8\"/>\n  <rect class=\"d-box-primary\" x=\"110\" y=\"108\" width=\"24\" height=\"24\" rx=\"6\"/>\n  <rect class=\"d-box-accent\" x=\"144\" y=\"108\" width=\"470\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label\" x=\"152\" y=\"125\">Read</text>\n  <circle class=\"d-dot\" cx=\"636\" cy=\"120\" r=\"12\"/>\n  <text class=\"d-label-strong\" x=\"20\" y=\"212\">Fixed</text>\n  <rect class=\"d-box\" x=\"100\" y=\"192\" width=\"560\" height=\"36\" rx=\"8\"/>\n  <rect class=\"d-box-primary\" x=\"110\" y=\"198\" width=\"24\" height=\"24\" rx=\"6\"/>\n  <rect class=\"d-box-warn\" x=\"144\" y=\"198\" width=\"160\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label\" x=\"152\" y=\"215\">Read 20 pages be…</text>\n  <circle class=\"d-dot\" cx=\"326\" cy=\"210\" r=\"12\"/>\n  <text class=\"d-label-muted\" x=\"380\" y=\"260\" text-anchor=\"middle\">Fill pushes the button to the edge; Fixed truncates long names.</text>\n</svg><figcaption>The same habit row with three sizing choices for the text stack</figcaption></figure>\n<p>For Steady’s habit row the settings are:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"Scrollable table\" tabindex=\"0\"><table><thead>\n<tr>\n<th>Layer</th>\n<th>Width</th>\n<th>Height</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Habit row</td>\n<td>Fill container</td>\n<td>Hug contents</td>\n</tr>\n<tr>\n<td>Icon, Check button</td>\n<td>Fixed 32</td>\n<td>Fixed 32</td>\n</tr>\n<tr>\n<td>Text stack</td>\n<td>Fill container</td>\n<td>Hug contents</td>\n</tr>\n<tr>\n<td>Habit name, Streak</td>\n<td>Fill container</td>\n<td>Hug contents</td>\n</tr>\n</tbody>\n</table></div><p>Read it from the outside in. The row fills the list’s width. Inside it, the text stack fills whatever the icon and button leave, which pushes the button to the right edge. The habit name fills the stack’s width and hugs its height, so a long name wraps onto a second line and the row grows taller to fit. That is exactly the behaviour you want on a 375 px phone.</p>\n<p>Figma enforces one rule for you: a parent cannot hug a child that fills it on the same axis. Each would be waiting to measure the other. If you set a child to Fill container, Figma switches the parent from Hug to Fixed on that axis.</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>Fixed widths everywhere</span></p>\n<p>Designing at 393 px and typing 353 into every width works perfectly at 393 px and nowhere else. Before you type a fixed number, ask whether the thing should really never change size. Icons and avatars, yes. Rows, buttons in sheets and text, almost never.</p>\n</aside>\n<h2 id=\"sec-2\" tabindex=\"-1\">Min and max</h2>\n<p>Fill and Hug can produce silly sizes at the extremes. A full-width button looks fine on a phone and ridiculous at 1,000 px wide on a tablet. A chip that hugs a one-letter label can become narrower than a fingertip.</p>\n<p>Min and max width and height (found in the width and height dropdowns) set the limits. Steady uses:</p>\n<ul>\n<li><strong>Save habit</strong> button: Fill container, <strong>max width 480</strong>, so it stops growing on tablets.</li>\n<li><strong>Chip</strong>: Hug contents, <strong>min width 64</strong>, so short labels still make a comfortable target.</li>\n<li><strong>Text field</strong>: Fill container, <strong>min width 200</strong>, so it never collapses in a narrow layout.</li>\n</ul>\n<h2 id=\"sec-3\" tabindex=\"-1\">Wrap</h2>\n<p>The frequency chips in the New habit sheet sit in a horizontal row. “Daily, Weekdays, Weekends, Custom” fits at 393 px but not at 320 px or in German. Turn on <strong>wrap</strong> for the row and chips that do not fit flow onto a new line instead of overflowing. At the time of writing, a wrapping frame lets you set the space between lines separately from the gap between items; use the same 8 px so the chips form an even grid.</p>\n<p>Wrap is for collections of similar items such as chips, tags or avatars. Do not wrap a habit row: on a narrow screen its check button would drop onto its own line.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Pulling a layer out of the flow</h2>\n<p>Sometimes one child should not take part in the flow at all: a small flame badge on the corner of a habit icon, or a dot that marks an unread reminder. Select it and turn on <strong>Ignore auto layout</strong> (it was called <em>absolute position</em> until recently, so older tutorials use that name). The layer stays inside the frame but stops affecting its siblings, and you place it with constraints, here Right and Top, so it sticks to the corner when the icon resizes.</p>\n<aside class=\"callout callout-tip\" 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=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Test with ugly content</span></p>\n<p>Replace one habit name with “Practise Spanish vocabulary with flashcards for fifteen minutes”, set one streak to “1,245-day streak”, and resize the frame from 320 to 430 wide. If nothing overlaps, truncates by accident or floats, your sizing is right.</p>\n</aside>\n<p>Your rows now adapt to width and content. Next you give all those gaps and paddings a system, so 12, 16 and 24 are decisions instead of guesses.</p>\n","toc":[{"id":"sec-1","text":"Hug, Fill and Fixed","level":2},{"id":"sec-2","text":"Min and max","level":2},{"id":"sec-3","text":"Wrap","level":2},{"id":"sec-4","text":"Pulling a layer out of the flow","level":2}],"takeaways":["Every layer in auto layout has a width and a height behaviour; Hug contents follows the children, Fill container takes the parent’s available space, Fixed never changes.","A parent cannot hug a child that fills it on the same axis, so Figma switches that parent to Fixed.","Min and max width stop components from becoming absurdly narrow or wide on unusual screens.","Wrap lets horizontal content such as chips flow onto a new line instead of overflowing.","Ignore auto layout takes one child out of the flow so you can position it with constraints, which suits badges and floating dots."],"further":[{"title":"Guide to auto layout (resizing, wrap, min and max)","url":"https://help.figma.com/hc/en-us/articles/360040451373-Guide-to-auto-layout"},{"title":"Create a responsive card with auto layout and constraints","url":"https://help.figma.com/hc/en-us/articles/18894664907287-Create-a-responsive-card-with-auto-layout-and-constraints"}],"quiz":[{"q":"<p>The primary “Save habit” button should stretch across the sheet on any phone, but stay its natural height. Which settings fit?</p>","options":[{"text":"Width Hug contents, height Fill container.","why":"Hug width makes the button only as wide as its label, and Fill height would stretch it down the sheet."},{"text":"Width Fixed 353, height Fixed 48.","why":"A fixed width breaks on any phone that is not exactly the width you designed for."},{"text":"Width Fill container, height Hug contents.","why":"Correct. Fill takes the sheet’s width; Hug keeps the height equal to the label plus padding."},{"text":"Width Fill container, height Fill container.","why":"Fill height in a vertical sheet would make the button grow into all leftover vertical space."}],"answer":2},{"q":"<p>Inside the habit row, the text stack is set to Hug contents. On a wide phone the check button sits right next to a short name instead of at the right edge. What fixes it?</p>","options":[{"text":"Set the text stack’s width to Fill container so it takes the remaining space and pushes the button to the edge.","why":"Correct. Fill container makes the stack absorb the leftover width, so the button lands at the right padding."},{"text":"Set the check button’s width to Fill container.","why":"The button would stretch into a wide pill instead of staying a 32 px circle."},{"text":"Add a flexible spacer rectangle between text and button.","why":"Spacers hide intent. The stack itself should take the space."},{"text":"Set the row’s gap to auto spacing.","why":"Auto spacing could push the button right, but the text would then not wrap at a predictable width. Fill on the stack is clearer."}],"answer":0},{"q":"<p>You set a card’s width to Hug contents, then set a child inside it to Fill container on the same axis. What does Figma do?</p>","options":[{"text":"It keeps both and the card grows forever.","why":"Figma prevents this loop. The parent cannot measure its children while a child measures the parent."},{"text":"It switches the card’s width to Fixed.","why":"Correct. A child that fills its parent needs a parent with a definite size, so Figma changes Hug to Fixed on that axis."},{"text":"It ignores the child’s Fill setting.","why":"Figma resolves the conflict on the parent’s side, not the child’s."},{"text":"It turns on wrap for the card.","why":"Wrap is unrelated. It only changes how children flow onto new lines."}],"answer":1},{"q":"<p>Steady shows a small flame badge overlapping the top-right corner of a habit’s icon. How do you build it inside the auto layout icon frame?</p>","options":[{"text":"Add the badge as a normal child and set a negative gap.","why":"Negative gap overlaps all siblings in the flow, not just one badge at one corner."},{"text":"Put the badge in a separate frame above the whole row.","why":"It would not move with the icon when the row reflows, so it would drift on other screens."},{"text":"Draw it on top using a group and nudge it into place.","why":"Groups inside auto layout still join the flow; nudging is lost on the next re-layout."},{"text":"Add the badge as a child, turn on Ignore auto layout, and pin it with Right and Top constraints.","why":"Correct. Ignore auto layout takes it out of the flow, and constraints keep it at the corner as the icon resizes."}],"answer":3}],"exercise":{"kind":"choice","multiple":true,"options":["wrap-chips","max-button","fill-label","hug-sheet","fill-chips","ignore-toggle"],"correct":["wrap-chips","max-button","fill-label"],"title":"Make the New habit sheet survive any screen","prompt":"<p>QA filed three bugs against the New habit sheet: on a 320 px phone the chips run off the edge (below), the Reminder toggle hugs its label instead of sitting at the right edge, and on an iPad the Save habit button stretches to 900 px wide.</p>\n<p>:::figure The New habit sheet on a 320 px phone\n<svg viewBox=\"0 0 420 380\" role=\"img\" aria-labelledby=\"ex1\"></p>\n  <title id=\"ex1\">A narrow bottom sheet. The name field fits. The four frequency chips run past the right edge of the sheet. The Reminder label is followed immediately by its toggle instead of the toggle sitting at the right edge. The Save habit button fits.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"20\" width=\"300\" height=\"340\" rx=\"20\"/>\n  <text class=\"d-label-strong\" x=\"40\" y=\"56\">New habit</text>\n  <rect class=\"d-box\" x=\"40\" y=\"76\" width=\"260\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-label-muted\" x=\"52\" y=\"101\">Habit name</text>\n  <rect class=\"d-box-accent\" x=\"40\" y=\"136\" width=\"64\" height=\"30\" rx=\"15\"/>\n  <text class=\"d-label\" x=\"72\" y=\"156\" text-anchor=\"middle\">Daily</text>\n  <rect class=\"d-box-accent\" x=\"112\" y=\"136\" width=\"96\" height=\"30\" rx=\"15\"/>\n  <text class=\"d-label\" x=\"160\" y=\"156\" text-anchor=\"middle\">Weekdays</text>\n  <rect class=\"d-box-accent\" x=\"216\" y=\"136\" width=\"96\" height=\"30\" rx=\"15\"/>\n  <text class=\"d-label\" x=\"264\" y=\"156\" text-anchor=\"middle\">Weekends</text>\n  <rect class=\"d-box-warn\" x=\"320\" y=\"136\" width=\"84\" height=\"30\" rx=\"15\"/>\n  <text class=\"d-label\" x=\"362\" y=\"156\" text-anchor=\"middle\">Custom</text>\n  <text class=\"d-label\" x=\"40\" y=\"210\">Reminder</text>\n  <rect class=\"d-box-primary\" x=\"120\" y=\"194\" width=\"44\" height=\"24\" rx=\"12\"/>\n  <rect class=\"d-box-primary\" x=\"40\" y=\"290\" width=\"260\" height=\"48\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"170\" y=\"320\" text-anchor=\"middle\">Save habit</text>\n</svg>\n:::\n<p>The sheet is a vertical auto layout frame set to Fill container width. Select <strong>every</strong> change that fixes one of these bugs properly.</p>\n","hints":["Match each bug to one sizing tool: wrap, min/max, or Fill container.","For the toggle, the leftover space has to go somewhere. Which child should absorb it?","Wrap the chips row, cap the button with a max width, and make the label fill."],"explanation":"<p>Turning on <strong>wrap</strong> for the chips row lets “Custom” flow onto a second line instead of overflowing. A <strong>max width</strong> on the Save habit button (Steady uses 480) keeps Fill container from producing a 900 px bar on tablets. Setting the <strong>Reminder label to Fill container</strong> makes it absorb the leftover width, which pushes the toggle to the row’s right padding on every screen. Making the sheet hug its contents would shrink it to its widest child instead of filling the screen; filling every chip stretches them into uneven pills; and nudging the toggle out of the flow with Ignore auto layout fixes one width and breaks the rest.</p>\n","checkLabels":{},"optionText":{"wrap-chips":{"text":"Turn on wrap for the frequency chips row.","why":"Correct. Chips that do not fit flow onto a new line, which is exactly what wrap is for."},"max-button":{"text":"Give the Save habit button a max width, such as 480.","why":"Correct. The button keeps Fill container on phones but stops growing on large screens."},"fill-label":{"text":"Set the Reminder label’s width to Fill container.","why":"Correct. The label takes the spare width, so the toggle lands at the right edge at every size."},"hug-sheet":{"text":"Set the sheet’s width to Hug contents.","why":"A hugging sheet sizes to its widest child, so it would no longer span the screen and the bugs would move rather than disappear."},"fill-chips":{"text":"Set every chip to Fill container.","why":"The chips would stretch to share the row width equally and still not fit on a 320 px screen. Chips should hug their labels."},"ignore-toggle":{"text":"Turn on Ignore auto layout for the toggle and drag it to the right edge.","why":"You could pin it with constraints, but taking it out of the flow means the label can now run under it. Fill on the label is simpler and robust."}}},"words":801,"readMinutes":4}