max()

Gabriel Shoyombo on

Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.

The CSS max() function takes two or more comma-separated arguments of spacing values, evaluates them, and returns the largest value of the bunch.

.element {
  width: max(80%, 800px); /* The largest value is returned */
}

This function can be used anywhere that a length, frequency, angle, time, percentage, number, or integer is allowed. If you need to grow with content but never shrink below a particular size, say 200px, then the max() function is your best bet. It’s like “lower limit” guardian for responsive layouts.

The CSS max() function is a working draft of the CSS Values and Units Module Level 4 specification with other related functions, like min() and clamp().

Syntax

max(value1, value2, ...);

The max() function takes two or more arguments — think lengths (e.g., px, em, rem), percentages (i.e., %), viewport units(e.g., vw, vh), or even calculations with calc() or keywords, like max-content and min-content. It compares them all and picks the largest value, whichever that is at render time.

Example

The following example sets an element with a class of .container to 50vh, but it will never be less than 300px. So, if the viewport’s height is 1000px, then 50vh equals 500px, which is greater than the first argument at 300px, and as a result, the .container height becomes 500px.

.container {
  height: max(300px, 50vh); /* Uses 200px unless 50vh is larger */
}

But let’s say the viewport’s height is 500px. In that case, 50vh equals 250px, which is less than the first argument at 300px, and as a result, the .container height becomes 300px. The greater of the two values is what gets returned, depending on the context.

Basic usage

The max() function excels at setting floors in responsive design. It evaluates its arguments dynamically, picking the largest value based on context. It is as straightforward as any CSS value function and fits anywhere a numeric value is accepted — widthheightmarginfont-size, you name it. 

For example, max(12px, 2vw) might enforce a 12px minimum on small screens but scale up on wider ones. It’s the flip side of min() — where min() caps at a ceiling, max() ensures a baseline. As long as your units are comparable, mixing px with % is fine, but auto might trip things up.

Here’s a quick example that sets a minimum width for a sidebar:

.sidebar {
  width: max(25%, 200px); /* At least 200px, grows to 25% if larger */
  padding: 15px;
  background: #2c3e50;
  color: white;

  &:hover {
    width: max(30%, 250px); /* Wider minimum on hover */
  }
}

The sidebar stays at least 200px wide but expands to 25% of its container width if that’s bigger. On hover, it bumps up to a 250px minimum — smooth and controlled, ideal for interactive panels or navigation.

Ensuring readable text

It keeps font sizes from shrinking too small:

.text-block {
  font-size: max(16px, 3vw); /* Never below 16px, scales with viewport */
  line-height: 1.5;
}

On small screens, the text stays legible at 16px while on larger ones, it grows with the viewport. The max() function provides a simple way to prioritize readability without extra breakpoints.

Minimum gaps in flex

It helps maintain spacing in flexible layouts:

.flex-container {
  display: flex;
  gap: max(10px, 2vw); /* At least 10px, grows with viewport */
}

.flex-item {
  flex: 1;
  background: #3498db;
  padding: 20px;
  color: white;
}

The gap between flex items never drops below 10px, ensuring clarity, but scales up on wider screens for a polished look.

Managing padding

For inner elements, max() can smartly manage padding to balance responsiveness with a minimum threshold — solving the “inside problem” where content needs breathing room without overflowing its container. Inspired by a clever idea from Caluã de Lacerda Pataca, you can use max() to add padding that grows on larger screens but stays sensible on smaller ones:

:root {
  --content-width: 800px; /* Max content width */
}

.inner-content {
  max-width: var(--content-width);
  margin: 0 auto;
  padding-left: max(2rem, calc((100vw - var(--content-width)) / 2));
  padding-right: max(2rem, calc((100vw - var(--content-width)) / 2));
  padding-top: 1rem;
  padding-bottom: 1rem
  background: #f9ebea;
}

Here’s the magic: the calc((100vw - var(--content-width)) / 2) statement calculates the extra space on either side of a centered content block. On wide screens, this grows, adding generous padding; on narrow screens, max() ensures it never drops below 2rem. This keeps the inner content snug but readable, avoiding the cramped feel when viewport width shrinks. It is a slick alternative to media queries for fluid padding control.

Responsive images

You can set a minimum size for visuals, as in the image in the example below:

.image-wrapper {
  width: max(50%, 300px); /* At least 300px, grows to 50% if larger */
  height: auto;
}

.image-wrapper img {
  width: 100%;
  display: block;
}

The image stays substantial at 300px minimum, avoiding pixelation or awkward shrinking, while scaling up responsively.

Math with max()

The calc() function can also be used to adjust the max() function dynamically:

.hero {
  height: max(300px, calc(50vh - 2rem)); /* Minimum 300px, adjusts with viewport */
  background: #ecf0f1;
  display: flex;
  align-items: center;
  justify-content: center;
}

This ensures the hero section is at least 300px tall but grows based on viewport height minus padding, perfect for dynamic layouts.

Minimum height with max()

You can set a minimum height by combining the CSS height property and the max() function:

.section {
  height: max(300px, 25%);
  background: #e0e0e0;
  padding: 20px;
}

The .section stays at least 300px tall but can grow to 25% of its container’s height if that’s larger. Resize your window, and it’ll hold that minimum while adapting fluidly.

max(), min(), and clamp() functions compared

The max() function is part of a trio of CSS comparison functions, alongside min() and clamp(). Each handles responsive sizing differently — min() sets an upper limit, max() sets a lower limit, and clamp() balances both. Here’s how they stack up:

max()min()clamp()
PurposePicks the largest value (lower limit)Picks the smallest value (upper limit)Sets a value within a min/max range
Syntaxmax(25%, 200px)min(50%, 500px)clamp(200px, 50%, 800px)
BehaviourEnsures a floor, e.g., never below 200pxCaps growth, e.g., never exceeds 500pxStays between min and max, e.g., 200px to 800px
Use caseEnsure minimum readability or visibilityPrevent overflow or oversized elementsFluid scaling with both floor and ceiling
Arguments2+ comparable values2+ comparable valuesExactly 3: minimum, preferred, and maximum.
Example outputmax(10px, 2vw)10px if 2vw < 10px, else 2vwmin(10vw, 100px): 10vw if < 100px, else 100pxclamp(16px, 4vw, 32px)16px32px range.
  • When to use min(): Cap a button at min(50%, 200px) to keep it compact.
  • When to use max(): Ensure text is legible with max(16px, 3vw).
  • When to use clamp(): Scale a container fluidly with clamp(200px, 50%, 800px).

Think of max() as the enforcer of minimums, min() as the limiter of maximums, and clamp() as the Goldilocks solution — together, they’re a responsive design dream team.

Browser support

max() is supported in all modern browsers (Chrome, Firefox, Safari, Edge) since 2019–2020. Check Caniuse for specifics. No Internet Explorer support, though, so add a fallback like this, if needed:

width: 200px; /* Fallback */
width: max(25%, 200px);

More information