AD JB Toolbox 01 EN

CSS Tutorial / Fluid CSS Layouts with min, max, and clamp

A fluid layout lets dimensions adapt to available space while imposing useful limits. Relative widths, max-width, and functions such as clamp() can keep content readable without forcing the same fixed dimensions onto every screen.

Separate viewport width and available width

The area where a web page is displayed in the browser is called the viewport. However, the available width for in-body cards may be less than the viewport. This is because the card must fit in the remaining space excluding the parent's margin, spacing from other columns, and the maximum width limit.

The percentage in width: 100% uses the width of the base area surrounding the element in a typical block layout. 100vw is based on the viewport width, so even if you put it inside a small card it can be as big as the entire screen. When vertical scroll bars and outer margins are added, horizontal overflow can occur. For the width of elements inside the body, first consider percentage or autosize.

designation narrow parents wide parents Standard of use
width: 48rem May be larger than parents Maintain 48rem Not suitable as default value for text that can be shortened
width: 100% Reduced to match parents Continues to increase to parent width Elements that need to fill in the parent
width: 100%; max-width: 48rem Reduced to less than 48rem Up to 48rem Text that requires limited reading width
min-width: 48rem Does not reduce below 48rem Decided according to different size rules Use only when there is a required minimum size

Bound and center the content area

*, *::before, *::after { box-sizing: border-box; }
.content {
  width: 100%;
  max-width: 48rem;
  margin-inline: auto;
  padding-inline: 1rem;
}

With border-box, padding and borders fit inside the declared width. If the root font is 16px and the parent is 390px wide, this content box's outer width is 390px and its 16px padding on each side leaves 358px for content. At a 1000px parent width, the outer width stops at 768px and automatic margins center it. For further detail, see CSS Width, Height, min/max Limits, and box-sizing.

Applying content-box to the same element will add padding to width: 100%, making it wider than its parent. On the other hand, margins are not included in border-box either. When specifying width: 100% and fixed margins on both sides together, you must check the total sum. If the min-width and max-width conflict, check min-width as well, as the min-width may cause it to be larger.

Use min() and clamp()

min() selects the smaller value among candidates. width: min(100%, 48rem) uses the smaller of the parent width and 48rem, so the 100% and maximum width limits specified earlier can be expressed in one declaration.

.content { width: min(100%, 48rem); }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); }

clamp(minimum, preferred, maximum) calculates the middle value but does not exceed the range at both ends. In the title above, rem is based on the root font size and vw is based on 1% of the viewport width. If the root size is 16px, the minimum is 24px, the maximum is 40px, and the preferred value is 16px plus 2% of the screen width.

viewport width Calculate center value actual title size
320px 16 + 6.4 = 22.4px Minimum 24px
600px 16 + 12 = 28px 28px
1200px 16 + 24 = 40px 40px
1600px 16 + 32 = 48px Maximum 40px

If you make body text dependent solely on the screen width, it may become too small on narrow screens or in zoomed-in situations. When using fluid sizes in titles, a good starting point is to have a lower readable limit and keep the body at a rem-based size. Just because you've mixed up rem doesn't automatically guarantee magnification accessibility, so you'll need to check the actual browser magnification and default font settings as well. You can check the role of each argument in MDN's clamp() definition and accessibility explanation.

Run the fluid card and image example

Save the following code as fluid-size.html in UTF-8 and open it in your browser. The picture is SVG data included in the file, so there is no need to download a separate image or external library. Compare the width of the body, number of card columns, and title size on a wide screen and a narrow screen of about 390px. If you want to place multiple cards flexibly, check out CSS Grid: repeat, auto-fit, auto-fill, and Areas for how to set the minimum width for the columns.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>fluid-size.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 48rem); margin-inline: auto; padding: 1rem; }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); line-height: 1.3; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 1rem; }
.card { min-width: 0; padding: 1rem; background: #e8f3fa; overflow-wrap: anywhere; }
.card img { display: block; max-width: 100%; height: auto; margin-bottom: 1rem; }
.token { font-family: monospace; }
</style>
</head>
<body>
<main class="content">
<h1>Size elements to fit the screen and content</h1>
<p>The content is at most 48rem wide and shrinks to fit its parent on smaller screens.</p>
<div class="cards">
  <article class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22400%22%20height%3D%22300%22%20viewBox%3D%220%200%20400%20300%22%3E%3Crect%20width%3D%22400%22%20height%3D%22300%22%20fill%3D%22%23287699%22%2F%3E%3Crect%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%23205c32%22%2F%3E%3Crect%20y%3D%22265%22%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%239e3131%22%2F%3E%3Ccircle%20cx%3D%22200%22%20cy%3D%22150%22%20r%3D%2270%22%20fill%3D%22%23f6ae4c%22%2F%3E%3Crect%20x%3D%2212%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3Crect%20x%3D%22358%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E" width="400" height="300" alt="Practice drawing with upper and lower bands and center circle"><h2>card with picture</h2><p>The image stays within the card width and preserves its original aspect ratio.</p></article>
  <article class="card"><h2>A heading and description that wrap onto several lines</h2><p>Without a fixed height, the card grows as its text gets longer.</p></article>
  <article class="card"><h2>Long identifier</h2><p class="token">ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></article>
</div></main>
</body>
</html>

The card's minmax(min(100%, 14rem), 1fr) uses a default minimum width of 14rem, but if the parent is narrower, it is reduced by 100%. auto-fit creates a column that can be entered, and the remaining width is divided into 1fr columns. Because of the margins inside the card, the actual width of the text and pictures is smaller than the outside width of the card. Don't judge the number of columns by the device's name, but by the width available to the parent.

min-width: 0 removes a minimum-size constraint that could prevent the card from shrinking. overflow-wrap: anywhere supplies breaks within a long URL or identifier when needed. They have different roles: allowing the box to shrink does not by itself wrap its text. Wrapping changes presentation, not the copied string value.

Test one sizing change at a time

  1. Reduce the screen to 390px. The text should fit within the screen, the card should run vertically, and the bands above and below the picture and the circle in the center should all be visible.
  2. Change only the width of .content to 48rem. After checking why the text is overflowing on the narrow screen, return it to min(100%, 48rem).
  3. Change only the maximum value of the title to 3rem and see the difference on a wider screen. Calculating the center value explains why narrow screens do not change size and recovers to 2.5rem.
  4. It only removes overflow-wrap: anywhere from .card. Check and recover if long identifiers are outside the card. Subsequent experiments to change the root size and browser enlargement are recorded under separate conditions.

Before inserting overflow-x: hidden, which hides overflow, into the entire page, check the width, margin, minimum width, and string. If you hide it from view, content or operating elements may be cut off without resolving the cause. For the basic principles of responsive configuration, you can also refer to MDN's responsive design guide.

More in This Category
CSS Tutorial / CSS position: relative, absolute, fixed, and sticky

CSS Tutorial / CSS position: relative, absolute, fixed, and sticky

Compare positioning modes in a complete example, identify containing blocks, and troubleshoot sticky limits and overlapping content.

CSS Tutorial / CSS Combinators and Pseudo-Classes

CSS Tutorial / CSS Combinators and Pseudo-Classes

Compare descendant, child, and sibling selectors, then test hover, focus, and child-position conditions in a complete example.

CSS Tutorial / CSS display: Block, Inline, inline-block, and Hiding

CSS Tutorial / CSS display: Block, Inline, inline-block, and Hiding

Compare block and inline sizing, replaced elements such as images, and the layout and interaction differences between common hiding techniques.

CSS Tutorial / CSS Overflow, Long Text Wrapping, and Ellipsis

CSS Tutorial / CSS Overflow, Long Text Wrapping, and Ellipsis

Compare scrolling, clipping, long-word wrapping, and single-line ellipsis, including keyboard access and minimum-size issues in layout containers.

CSS Tutorial / Apply CSS with Inline, Internal, and External Styles

CSS Tutorial / Apply CSS with Inline, Internal, and External Styles

Compare three ways to apply CSS, create a working external stylesheet, and diagnose common file-path and loading problems.

CSS Tutorial / CSS Borders, Rounded Corners, and Shadows

CSS Tutorial / CSS Borders, Rounded Corners, and Shadows

Build cards with borders and shadows, compare circles and ellipses, and inspect how ancestor overflow changes visible shadows.

CSS Tutorial / CSS Paragraph and List Styling

CSS Tutorial / CSS Paragraph and List Styling

Style paragraphs and ordered or unordered lists, compare inside and outside markers, and check spacing and wrapped text on narrow screens.

CSS Tutorial / Pseudo-Elements: ::before and ::after

CSS Tutorial / Pseudo-Elements: ::before and ::after

Add decorative pseudo-elements, compare them with the original page, and keep essential information in HTML while checking keyboard access.

CSS Tutorial / CSS Link States and Visible Keyboard Focus

CSS Tutorial / CSS Link States and Visible Keyboard Focus

Compare link states in a working multi-file example, inspect keyboard focus, and understand browser privacy restrictions on visited-link styles.

CSS Tutorial / CSS Form States: Focus, Validation, disabled, and readonly

CSS Tutorial / CSS Form States: Focus, Validation, disabled, and readonly

Compare form states, create accessible labels and error messages, and inspect which enabled, disabled, and read-only fields enter submitted form data.