{"id":"l-fig-2-4","courseId":"figma-ui-design","lang":"en","kind":"lesson","summary":"Combine constraints for fixed elements with auto layout for content so one Steady screen adapts from a small phone to a large one, and test it with resized copies and stress content.","html":"<p>Steady will run on phones from roughly 360 to 440 points wide, and heights vary even more. Designing a separate screen for each size is a maintenance trap: change the habit row on one and you must remember to change it on four others. The goal is one screen that adapts, built from the pieces you already have.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Two kinds of things on a screen</h2>\n<p>Look at the Today screen and sort its parts into two kinds.</p>\n<p><strong>Things pinned to the screen</strong>: the tab bar at the bottom, the floating add button in the corner. They should stay attached to an edge no matter what the content does. That is the job of <strong>constraints</strong> (Lesson 1.4).</p>\n<p><strong>Things that flow</strong>: the header, the progress block and the habit list. They stack one after another, and the list grows with every habit. That is the job of <strong>auto layout</strong> (Lessons 2.1 and 2.2).</p>\n<p>The structure that follows is simple and works for most app screens:</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 300\" role=\"img\" aria-labelledby=\"l-fig-2-4-t1\"><defs><marker id=\"arrow-l-fig-2-4-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-4-t1\">The Today screen frame is a regular frame. Inside it, a Content frame uses vertical auto layout and holds header, progress and habit list; it is constrained left and right, top and bottom. The tab bar is constrained left and right plus bottom, and the add button right plus bottom.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"20\" width=\"300\" height=\"260\" rx=\"16\"/>\n  <text class=\"d-label-strong\" x=\"36\" y=\"44\">Today (frame, no auto layout)</text>\n  <rect class=\"d-box-primary\" x=\"36\" y=\"56\" width=\"268\" height=\"150\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"48\" y=\"78\">Content: vertical auto layout</text>\n  <rect class=\"d-box\" x=\"48\" y=\"88\" width=\"244\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"105\">Header</text>\n  <rect class=\"d-box\" x=\"48\" y=\"118\" width=\"244\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"135\">Progress</text>\n  <rect class=\"d-box\" x=\"48\" y=\"148\" width=\"244\" height=\"48\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"176\">Habit list</text>\n  <circle class=\"d-dot\" cx=\"286\" cy=\"226\" r=\"12\"/>\n  <rect class=\"d-box-accent\" x=\"36\" y=\"244\" width=\"268\" height=\"28\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"170\" y=\"263\" text-anchor=\"middle\">Tab bar</text>\n  <text class=\"d-label\" x=\"360\" y=\"90\">Content</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"110\">constraints: L+R, Top+Bottom</text>\n  <text class=\"d-label\" x=\"360\" y=\"160\">Add button</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"180\">constraints: Right, Bottom</text>\n  <text class=\"d-label\" x=\"360\" y=\"230\">Tab bar</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"250\">constraints: L+R, Bottom</text>\n  <path class=\"d-arrow\" d=\"M352 98 L308 120\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M352 168 L300 222\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M352 238 L306 254\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n</svg><figcaption>One screen frame, two layout systems</figcaption></figure>\n<p>The screen frame itself has no auto layout. Inside it, the <code dir=\"ltr\">Content</code> frame uses vertical auto layout and has constraints <strong>Left and right, Top and bottom</strong>, so it always fills the space between status bar and tab bar. The tab bar and add button are siblings of <code dir=\"ltr\">Content</code> with edge constraints. Inside <code dir=\"ltr\">Content</code>, everything uses Fill container width, so rows stretch with the 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>Putting everything in one auto layout stack</span></p>\n<p>Wrapping the whole screen, tab bar included, in one vertical auto layout frame feels tidy. But in a flow, the tab bar sits right after the last habit. With three habits on a tall phone it floats mid-screen. Pinned things belong outside the flow, controlled by constraints.</p>\n</aside>\n<h2 id=\"sec-2\" tabindex=\"-1\">Respect the system areas</h2>\n<p>Modern phones reserve space at the top for the status bar and camera cutout, and at the bottom for the home indicator. Content under them is hard to read or impossible to tap. Pad your <code dir=\"ltr\">Content</code> frame’s top and the tab bar’s bottom so nothing important sits there. The exact sizes differ between devices, so take them from the official Apple or Google UI kits in the Figma Community rather than guessing.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">Two-dimensional content: grid flow</h2>\n<p>The Habit detail screen shows four stat cards: current streak, best streak, completion rate and total check-ins. On a phone they sit in two columns; on a tablet, four across.</p>\n<p>At the time of writing, auto layout has a <strong>Grid</strong> flow for exactly this. A grid auto layout frame has a number of columns and rows, gaps between them, and children that can span more than one cell. Set the stats frame to 2 columns with 16 px gaps (matching the layout guide’s gutter) on the phone; on the tablet copy, change it to 4 columns. The same four cards rearrange without being redrawn.</p>\n<p>Wrap (Lesson 2.2) would also put cards on new lines, but with wrap each card keeps its own width, so you get ragged leftovers. Grid keeps columns equal, which is what a dashboard of stats needs.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">The resize ritual</h2>\n<p>Before Sofia accepts a screen, she runs the same test, and you should too:</p>\n<ol>\n<li>Duplicate the screen frame twice.</li>\n<li>Resize one copy to 360 wide and the other to 440 wide, and adjust heights to a short and a tall phone.</li>\n<li>Read every copy top to bottom. Look for overlaps, truncation you did not intend, things floating mid-screen and gaps that grew strangely.</li>\n<li>Fix the original, not the copies. Delete the copies when the original passes.</li>\n</ol>\n<p>Then stress the content, because content breaks more layouts than widths do. Use a 40-character habit name, a four-digit streak and an empty list (“No habits yet”). Finally, increase every text style by about 30% on a copy. Many people set larger text in their phone’s settings, and a row that only works at 17 px will break for them first.</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>Breakpoints are content decisions</span></p>\n<p>When a layout stops working as the frame widens, that width is your breakpoint, not a number from a device list. If the habit list gets uncomfortably long-lined at 600 px, that is where a tablet layout with a side panel should begin.</p>\n</aside>\n<p>Section 2 is done: your screens stack, stretch, wrap and pin correctly. In Section 3 you stop rebuilding the habit row on every screen and turn it into a component.</p>\n","toc":[{"id":"sec-1","text":"Two kinds of things on a screen","level":2},{"id":"sec-2","text":"Respect the system areas","level":2},{"id":"sec-3","text":"Two-dimensional content: grid flow","level":2},{"id":"sec-4","text":"The resize ritual","level":2}],"takeaways":["Use constraints for things pinned to the screen edges (tab bar, floating button) and auto layout for the content that flows.","Design at one mid-size width, then prove the screen at the smallest and largest widths you support.","Keep content clear of the status bar and home indicator areas, and use a platform UI kit for their exact sizes.","Grid auto layout handles two-dimensional content such as stat cards, and the column count can change between breakpoints.","Stress-test with long text, larger text sizes and empty states, because real content breaks layouts more often than screen widths do."],"further":[{"title":"Combine vertical, horizontal, and grid auto layout flows","url":"https://help.figma.com/hc/en-us/articles/31441443713047-Combine-vertical-horizontal-and-grid-auto-layout-flows"},{"title":"Use the grid auto layout flow","url":"https://help.figma.com/hc/en-us/articles/31289469907863-Use-the-grid-auto-layout-flow"},{"title":"Layout (Apple Human Interface Guidelines)","url":"https://developer.apple.com/design/human-interface-guidelines/layout"}],"quiz":[{"q":"<p>Steady’s Today screen is one big vertical auto layout frame containing header, list and tab bar. On a tall phone the tab bar ends up halfway down the screen, right under the last habit. Why?</p>","options":[{"text":"Auto layout places the tab bar directly after its siblings, so it follows the content instead of the screen’s bottom edge.","why":"Correct. In a flow the tab bar’s position depends on what comes before it. Pinning to an edge is a constraint’s job."},{"text":"The tab bar needs the Scale constraint.","why":"Scale would resize the bar proportionally and still not anchor it to the bottom."},{"text":"Tall phones need a separate design file.","why":"One screen can serve many heights. Separate files multiply maintenance."},{"text":"The layout guide has too few rows.","why":"Layout guides never move layers. They are visual aids only."}],"answer":0},{"q":"<p>What is the most efficient way to check that a screen works across phone sizes?</p>","options":[{"text":"Redraw the screen from scratch at each width.","why":"Redrawing tests nothing about whether your one design adapts, and it creates copies that drift apart."},{"text":"Zoom the canvas in and out.","why":"Zoom changes your view, not the frame’s size, so constraints and resizing never run."},{"text":"Ask developers to tell you if it breaks.","why":"Finding layout bugs after build costs far more than resizing a frame now."},{"text":"Duplicate the frame and resize the copies to your narrowest and widest supported widths.","why":"Correct. Resizing runs every constraint and auto layout rule, so bugs show up immediately."}],"answer":3},{"q":"<p>On Habit detail, four stat cards sit in two columns on phones. On tablets you want four in one row. Which tool fits best?</p>","options":[{"text":"A horizontal auto layout with wrap and fixed-width cards.","why":"Wrap can work, but fixed-width cards leave ragged gaps at most widths. Grid keeps columns even."},{"text":"Grid auto layout, with 2 columns on the phone frame and 4 on the tablet frame.","why":"Correct. Grid places items in even rows and columns, and changing the column count rearranges the same cards."},{"text":"Four separate frames placed by hand with constraints.","why":"Manual placement must be redone for every size and every new card."},{"text":"A vertical auto layout with a negative gap.","why":"Negative gaps overlap items; they do not create columns."}],"answer":1}],"exercise":{"kind":"order","items":["design-mid","content-frame","fill-children","constraints","resize-copies","stress","fix-original"],"title":"Make the Today screen responsive","prompt":"<p>You have a static Today screen with everything placed by hand. Put these steps in the order you would follow to make it adapt from a 360 px to a 440 px phone, the way Sofia does it.</p>\n","hints":["You cannot set Fill container until the children sit inside an auto layout frame.","Testing comes after the structure is in place, and fixes go into the original, not the test copies.","Design, wrap content, set fills, pin edges and check the rows stretch, then test widths, then stress content, then fix."],"explanation":"<p>Start from one well-made <strong>mid-size design</strong> so you have something worth adapting. Wrap the flowing parts in a <strong>vertical auto layout content frame</strong>, because Fill container only exists for children of auto layout. Then set rows and text to <strong>Fill container</strong> width so they stretch. Next, add <strong>constraints</strong> in the screen frame for the content frame and the pinned elements; the quick drag check only shows rows stretching because their fills are already set. Only now do you <strong>resize copies</strong> to the narrowest and widest widths, then <strong>stress the content</strong> with long names, empty lists and larger text. Finally <strong>fix the original</strong> and delete the copies, so there is still one source of truth.</p>\n","checkLabels":{},"itemText":{"design-mid":"Design the screen at a mid-size width such as 393 px.","content-frame":"Wrap header, progress and habit list in a vertical auto layout Content frame.","fill-children":"Set the rows and text inside Content to Fill container width.","constraints":"Set constraints (Content: Left and right, Top and bottom; tab bar: Left and right, Bottom; add button: Right, Bottom), then drag the screen wider to check the rows stretch with it.","resize-copies":"Duplicate the screen and resize the copies to 360 and 440 px wide.","stress":"Stress-test the copies with a long habit name, an empty list and text about 30% larger.","fix-original":"Fix what broke in the original screen, then delete the test copies."}},"words":727,"readMinutes":3}