{"id":"l-css-2-4","courseId":"css-mastery","lang":"en","kind":"lesson","summary":"Size elements from their content with min-content, max-content and fit-content, and replace breakpoint pairs with min(), max() and clamp().","html":"<p>Waypoint’s session abstracts had the classic pair of rules: <code dir=\"ltr\">width: 100%</code> plus <code dir=\"ltr\">max-width: 40ch</code>, and then a media query to add side padding on phones, and another for big screens. Three rules and two breakpoints to say one thing: “be as wide as is comfortable to read, but never wider than the space you have”.</p>\n<p>CSS can say that directly now. This lesson covers two tools: the intrinsic size keywords, which let content decide how big an element is, and the math functions <code dir=\"ltr\">min()</code>, <code dir=\"ltr\">max()</code> and <code dir=\"ltr\">clamp()</code>, which let you describe a range instead of picking breakpoints.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Let the content decide: intrinsic keywords</h2>\n<p>Most sizes you write are <em>extrinsic</em>: 300px, 50%, 1fr. The browser can also size an element from its content, and three keywords expose that:</p>\n<ul>\n<li><strong><code dir=\"ltr\">min-content</code></strong>: the narrowest the element can be without overflowing, which is usually the width of its longest word.</li>\n<li><strong><code dir=\"ltr\">max-content</code></strong>: the width the content would take if it never wrapped.</li>\n<li><strong><code dir=\"ltr\">fit-content</code></strong>: <code dir=\"ltr\">max-content</code>, but never wider than the available space. When space runs out, it wraps like a normal block.</li>\n</ul>\n<p><code dir=\"ltr\">fit-content</code> is the one you’ll use most. A block-level badge or button normally stretches to fill its container; <code dir=\"ltr\">width: fit-content</code> makes it hug its label like an inline element while staying a block, so margins and stacking still behave. Add <code dir=\"ltr\">margin-inline: auto</code> and it centers.</p>\n<p>In grid tracks, the keywords give you content-driven columns. Waypoint’s agenda uses <code dir=\"ltr\">grid-template-columns: max-content 1fr</code>: the time column is exactly as wide as the longest time (“10:15–11:00”), and the session title takes the rest.</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>Using max-content for user text</span></p>\n<p><code dir=\"ltr\">max-content</code> never wraps. It’s perfect for short, controlled labels like times, and a disaster for a session title someone can edit, which will happily run off the screen. For text you don’t control, use <code dir=\"ltr\">fit-content</code> or a <code dir=\"ltr\">minmax()</code> track.</p>\n</aside>\n<h2 id=\"sec-2\" tabindex=\"-1\">min(), max() and clamp()</h2>\n<p>The math functions take a list of values, in any mix of units, and resolve to one length at layout time:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"css\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">sizing.css</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:#0550AE;--shiki-dark:#79C0FF\">.abstract</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  width</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">min</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">100</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">%</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">40</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">ch</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">/* ceiling: never wider than 40ch */</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:#0550AE;--shiki-dark:#79C0FF\">.page</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  padding-inline</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">max</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">rem</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">vw</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">/* floor: never less than 1rem */</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:#0550AE;--shiki-dark:#79C0FF\">.session-card</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  padding</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">clamp</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">px</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">%</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">32</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">px</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">/* between 12px and 32px, 4% in the middle */</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:#0550AE;--shiki-dark:#79C0FF\">.content</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  width</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">min</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">100</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">%</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> -</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">rem</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">60</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">rem</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">/* arithmetic works without calc() */</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  margin-inline</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">auto</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><strong><code dir=\"ltr\">min()</code> returns the smallest value</strong>, which means it sets an <em>upper</em> limit. <code dir=\"ltr\">min(100%, 40ch)</code> is 40ch on a wide card and 100% on a narrow one; it replaces the <code dir=\"ltr\">width</code> plus <code dir=\"ltr\">max-width</code> pair with one declaration. <strong><code dir=\"ltr\">max()</code> returns the largest value</strong>, so it sets a <em>lower</em> limit: the page gutter is 4vw on wide screens but never shrinks below 1rem on a phone.</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>Say it out loud</span></p>\n<p>The names feel backwards at first. Read <code dir=\"ltr\">min(100%, 40ch)</code> as “whichever is smaller”, and you’ll write the right one every time. Most people need a week of saying it out loud before it sticks.</p>\n</aside>\n<p><strong><code dir=\"ltr\">clamp(MIN, PREFERRED, MAX)</code></strong> combines both: it returns the preferred value, but never less than MIN and never more than MAX. It’s exactly <code dir=\"ltr\">max(MIN, min(PREFERRED, MAX))</code>.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 220\" role=\"img\" aria-labelledby=\"l-css-2-4-t1\"><defs><marker id=\"arrow-l-css-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-css-2-4-t1\">A graph of padding against container width. The line is flat at 12 pixels for narrow containers, rises along 4 percent of the width in the middle, and is flat at 32 pixels for wide containers.</title>\n  <path class=\"d-line\" d=\"M60 180 L640 180\"/>\n  <path class=\"d-line\" d=\"M60 180 L60 20\"/>\n  <text class=\"d-label-muted\" x=\"560\" y=\"204\">container width</text>\n  <text class=\"d-label-muted\" x=\"70\" y=\"30\">padding</text>\n  <path class=\"d-arrow\" d=\"M60 150 L220 150 L440 70 L630 70\"/>\n  <text class=\"d-code\" x=\"90\" y=\"140\">12px (MIN)</text>\n  <text class=\"d-code\" x=\"250\" y=\"100\">4% (PREFERRED)</text>\n  <text class=\"d-code\" x=\"480\" y=\"60\">32px (MAX)</text>\n  <path class=\"d-line d-dashed\" d=\"M220 150 L220 180\"/>\n  <path class=\"d-line d-dashed\" d=\"M440 70 L440 180\"/>\n  <text class=\"d-label-muted\" x=\"196\" y=\"200\">300px</text>\n  <text class=\"d-label-muted\" x=\"416\" y=\"200\">800px</text>\n</svg><figcaption>clamp() follows the preferred value between two limits</figcaption></figure>\n<p>With <code dir=\"ltr\">clamp(12px, 4%, 32px)</code>, a card in a 300px column gets 12px of padding, one in a 500px column gets 20px, and anything wider than 800px tops out at 32px. Padding percentages are relative to the containing block’s <em>inline size</em>, so the card’s spacing follows its container, not the viewport.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">Units that make math functions useful</h2>\n<p>The preferred value in <code dir=\"ltr\">clamp()</code> should be something that scales: a percentage, <code dir=\"ltr\">vw</code>, or the container units you’ll meet in <a href=\"/lesson/css-mastery/l-css-2-5\">Container Queries</a>. The limits should be stable units like <code dir=\"ltr\">px</code> or <code dir=\"ltr\">rem</code>. Using <code dir=\"ltr\">rem</code> for the limits has a bonus: if a user raises their default font size, the limits scale with it.</p>\n<p>This is also the trick behind the guard from the grid lesson: <code dir=\"ltr\">minmax(min(180px, 100%), 1fr)</code>. Inside a container narrower than 180px, <code dir=\"ltr\">min()</code> picks 100%, so the track never forces overflow.</p>\n<aside class=\"callout callout-note\" 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\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg><span><span class=\"callout-kind\">Note</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Support</span></p>\n<p><code dir=\"ltr\">min()</code>, <code dir=\"ltr\">max()</code>, <code dir=\"ltr\">clamp()</code> and the <code dir=\"ltr\">fit-content</code> keyword for <code dir=\"ltr\">width</code> are supported in every current browser. They’ve been safe to ship without fallbacks for years.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">Your turn</h2>\n<p>The exercise has a session card inside a wrapper whose width the checks change. Cap the abstract at 40ch without overflowing narrow cards, make the badge hug its text, and give the card padding that scales between 12px and 32px. Next, you’ll make whole components change layout based on their container’s width, with container queries.</p>\n","toc":[{"id":"sec-1","text":"Let the content decide: intrinsic keywords","level":2},{"id":"sec-2","text":"min(), max() and clamp()","level":2},{"id":"sec-3","text":"Units that make math functions useful","level":2},{"id":"sec-4","text":"Your turn","level":2}],"takeaways":["<code dir=\"ltr\">min-content</code> is the narrowest an element can be without overflowing, <code dir=\"ltr\">max-content</code> is its width with no wrapping, and <code dir=\"ltr\">fit-content</code> is max-content capped at the available space.","<code dir=\"ltr\">min()</code> picks the smallest value, so it acts as a ceiling: <code dir=\"ltr\">width: min(100%, 40ch)</code> never exceeds 40ch and never overflows its container.","<code dir=\"ltr\">max()</code> acts as a floor, and <code dir=\"ltr\">clamp(MIN, PREFERRED, MAX)</code> keeps a fluid value between two limits.","Math functions accept mixed units and arithmetic, so <code dir=\"ltr\">min(100% - 2rem, 60rem)</code> works without a nested <code dir=\"ltr\">calc()</code>."],"further":[{"title":"clamp() (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/clamp"},{"title":"fit-content (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/fit-content"},{"title":"Sizing units (web.dev Learn CSS)","url":"https://web.dev/learn/css/sizing"}],"quiz":[{"q":"<p>A session abstract has <code dir=\"ltr\">width: min(100%, 40ch)</code>. Its card is 900px wide. How wide is the abstract?</p>","options":[{"text":"900px, because 100% is the larger value.","why":"<code dir=\"ltr\">min()</code> returns the smaller value, not the larger one. It’s easy to mix up because it acts as a maximum."},{"text":"Whichever is smaller, so 40ch (roughly 320px at 16px).","why":"Correct. 40ch is smaller than 900px, so it wins. In a 200px card, 100% would be smaller and win instead."},{"text":"40ch, but it overflows when the card is narrower.","why":"That’s what plain <code dir=\"ltr\">width: 40ch</code> does. With <code dir=\"ltr\">min()</code>, 100% takes over as soon as the card is narrower than 40ch."},{"text":"It depends on the viewport width.","why":"Neither <code dir=\"ltr\">100%</code> nor <code dir=\"ltr\">ch</code> depends on the viewport; <code dir=\"ltr\">100%</code> is relative to the containing block."}],"answer":1},{"q":"<p>What does <code dir=\"ltr\">padding: clamp(12px, 4%, 32px)</code> give a card in a 500px-wide container?</p>","options":[{"text":"12px, because the minimum always applies first.","why":"The minimum only applies when the preferred value falls below it. 4% of 500px is 20px, which is above 12px."},{"text":"32px, because clamp() prefers the maximum.","why":"The maximum only applies when the preferred value exceeds it."},{"text":"4px, because the percentage is of the padding box.","why":"Padding percentages are always relative to the containing block’s inline size, here 500px."},{"text":"20px, because 4% of 500px sits between the limits.","why":"Correct. clamp() returns the preferred value when it falls between the minimum and maximum."}],"answer":3},{"q":"<p>A “Sold out” badge is <code dir=\"ltr\">display: block</code> inside a card, and it stretches across the whole card. Which declaration makes it hug its text but still wrap if the text is longer than the card?</p>","options":[{"text":"<code dir=\"ltr\">width: max-content</code>","why":"<code dir=\"ltr\">max-content</code> never wraps, so a long label would overflow the card."},{"text":"<code dir=\"ltr\">width: min-content</code>","why":"<code dir=\"ltr\">min-content</code> wraps at every opportunity, so a two-word label would break onto two lines."},{"text":"<code dir=\"ltr\">width: fit-content</code>","why":"Correct. It uses the max-content width when there’s room and falls back to the available width when there isn’t."}],"answer":2},{"q":"<p>Why does <code dir=\"ltr\">max(1rem, 4vw)</code> make a good page gutter?</p>","options":[{"text":"It grows with the viewport but never drops below 1rem on small screens.","why":"Correct. <code dir=\"ltr\">max()</code> picks the larger value, so it acts as a floor of 1rem while 4vw takes over on wider screens."},{"text":"It never grows beyond 1rem, keeping wide screens tidy.","why":"That would be <code dir=\"ltr\">min(1rem, 4vw)</code>, which acts as a ceiling."},{"text":"It switches from rem to vw at a breakpoint you declare.","why":"There’s no breakpoint; the browser compares the two values continuously at every width."}],"answer":0}],"exercise":{"kind":"web","mode":"dom","starter":{"html":"<div class=\"wrap\">\n  <article class=\"session-card\">\n    <span class=\"badge\">Sold out</span>\n    <h3>Intrinsic Sizing in Practice</h3>\n    <p class=\"abstract\">Let content decide how big things are: min-content, max-content, fit-content and the math functions that replace half your media queries.</p>\n  </article>\n</div>","css":".wrap {\n  width: 600px; /* the checks change this width */\n}\n.session-card {\n  border: 1px solid #e5e7eb;\n  border-radius: 12px;\n}\n.session-card h3 { margin: 8px 0; }\n.badge {\n  display: block;\n  padding: 0.1em 0.6em;\n  border-radius: 999px;\n  background: #fee2e2;\n  color: #991b1b;\n}\n\n.session-card { padding: 24px; }\n.abstract { width: 40ch; }\n"},"solution":{"html":"<div class=\"wrap\">\n  <article class=\"session-card\">\n    <span class=\"badge\">Sold out</span>\n    <h3>Intrinsic Sizing in Practice</h3>\n    <p class=\"abstract\">Let content decide how big things are: min-content, max-content, fit-content and the math functions that replace half your media queries.</p>\n  </article>\n</div>","css":".wrap {\n  width: 600px; /* the checks change this width */\n}\n.session-card {\n  border: 1px solid #e5e7eb;\n  border-radius: 12px;\n}\n.session-card h3 { margin: 8px 0; }\n.badge {\n  display: block;\n  padding: 0.1em 0.6em;\n  border-radius: 999px;\n  background: #fee2e2;\n  color: #991b1b;\n}\n\n.session-card { padding: clamp(12px, 4%, 32px); }\n.abstract { width: min(100%, 40ch); }\n.badge { width: fit-content; }\n"},"checks":[{"id":"abstract-capped","test":"const setW = async (w) => { $('.wrap').style.width = w + 'px'; await tick(16); }; await setW(600); const a = $('.abstract'); const probe = document.createElement('div'); probe.style.cssText = 'width:40ch;height:0;font:inherit;'; a.after(probe); const ch40 = probe.getBoundingClientRect().width; probe.remove(); return Math.abs(a.getBoundingClientRect().width - ch40) < 1;"},{"id":"abstract-fits-narrow","test":"const setW = async (w) => { $('.wrap').style.width = w + 'px'; await tick(16); }; const pad = () => parseFloat(style('.session-card', 'padding-left')); await setW(220); const card = $('.session-card').getBoundingClientRect(); const r = $('.abstract').getBoundingClientRect(); const ok = r.right <= card.right - pad() + 0.5; await setW(600); return ok;"},{"id":"badge-hugs","test":"const card = $('.session-card').getBoundingClientRect(); const b = $('.badge').getBoundingClientRect(); return style('.badge', 'display') === 'block' && b.width < card.width / 2 && b.width > 20;"},{"id":"padding-min","test":"const setW = async (w) => { $('.wrap').style.width = w + 'px'; await tick(16); }; const pad = () => parseFloat(style('.session-card', 'padding-left')); await setW(250); const p = pad(); await setW(600); return Math.abs(p - 12) < 0.5;"},{"id":"padding-fluid","test":"const setW = async (w) => { $('.wrap').style.width = w + 'px'; await tick(16); }; const pad = () => parseFloat(style('.session-card', 'padding-left')); await setW(500); const p = pad(); await setW(600); return Math.abs(p - 20) < 0.5;"},{"id":"padding-max","test":"const setW = async (w) => { $('.wrap').style.width = w + 'px'; await tick(16); }; const pad = () => parseFloat(style('.session-card', 'padding-left')); await setW(1000); const p = pad(); await setW(600); return Math.abs(p - 32) < 0.5;"}],"title":"Size the card from its content","prompt":"<p>The checks resize <code dir=\"ltr\">.wrap</code> between 220px and 1000px. Without media queries:</p>\n<ol>\n<li>Make <code dir=\"ltr\">.abstract</code> at most <strong>40ch</strong> wide, but never wider than the card’s content box.</li>\n<li>Make the block-level <code dir=\"ltr\">.badge</code> hug its text instead of stretching (keep <code dir=\"ltr\">display: block</code>).</li>\n<li>Give <code dir=\"ltr\">.session-card</code> padding of <strong>4%</strong> of the wrapper’s width, never less than <strong>12px</strong> and never more than <strong>32px</strong>.</li>\n</ol>\n","hints":["Each task is one declaration. Think: ceiling, shrink-wrap, range.","<code dir=\"ltr\">min()</code> acts as a ceiling, a keyword makes a block hug its content, and <code dir=\"ltr\">clamp()</code> takes three values.","<code dir=\"ltr\">.abstract { width: min(100%, 40ch); }</code>, <code dir=\"ltr\">.badge { width: fit-content; }</code>, <code dir=\"ltr\">.session-card { padding: clamp(12px, 4%, 32px); }</code>."],"explanation":"<p><code dir=\"ltr\">width: min(100%, 40ch)</code> resolves to whichever is smaller, so the abstract stops at 40ch in a wide card and shrinks to the content box in a narrow one, where a plain <code dir=\"ltr\">40ch</code> would overflow. <code dir=\"ltr\">fit-content</code> sizes the badge to its max-content width, capped at the space available, while it stays a block. <code dir=\"ltr\">clamp(12px, 4%, 32px)</code> returns 4% of the containing block’s width (20px at 500px), but never drops below 12px or rises above 32px, so one declaration replaces two breakpoints.</p>\n","checkLabels":{"abstract-capped":"In a wide card, the abstract is 40ch wide","abstract-fits-narrow":"In a narrow card, the abstract doesn’t overflow","badge-hugs":"The badge hugs its text and stays a block","padding-min":"Padding never drops below 12px","padding-fluid":"Padding is 4% of the width in between","padding-max":"Padding never exceeds 32px"}},"words":684,"readMinutes":3}