Kombai Logo

Tailwind CSS Flex Shrink

Flex shrink determines how much a flex item should shrink relative to other items in a flex container when there isn’t enough space available on a row (or column) for all items to fit at their original size. This means that when the total width (or height) of the flex items exceeds their container, items with a higher shrink value will become smaller faster than those with a lower shrink value.

Tailwind CSS provides shrink and shrink-0 utility classes to control flex shrink behavior, ensuring that the layout adapts precisely to your needs. In this guide, we will learn how to effectively work with the shrink utilities.

ClassPropertiesExample
shrinkflex-shrink: 1;<div className="shrink"></div>
shrink-0flex-shrink: 0;<div className="shrink-0"></div>

Overview of Flex Shrink

Adding the Flex Shrink

Ensuring that a flex item can shrink as needed is crucial for responsive layouts. Tailwind provides the shrink utility to shrink a flex item.

In the below snippet, there are three items in a flex container:

  • The first item has flex-1, meaning it will take up the maximum available space before others are laid out, but can still shrink if needed.
  • The second item also has flex-1, similarly taking up maximum available space.
  • The third item explicitly uses shrink to highlight that it can reduce its size when the container runs short on space.
This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Disabling the Shrink Behavior

While letting items shrink can be incredibly useful, there may be situations where you need a particular element to preserve its size no matter how tight the space gets. In such instances, preventing shrink can be equally beneficial.

In the below snippet, there are three items in a flex container:

  • The first item flex-1 usually expands and shrinks proportionally.
  • The second item flex-1 also shares the available space.
  • The third item uses shrink-0 utility, meaning it maintains its space even if the rest of the container becomes restricted in width.
This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

States and Responsiveness

Moders layouts often rely on state-specific or breakpoint-specific shifting. Tailwind’s modifiers makes it straightforward to conditionally enable or disable flex shrink based on states such as hover or focus, and also to selectively enable or disable it at various breakpoints.

Hover and Focus States

Tailwind’s state variants allow you to prepend a modifier (such as hover or focus) to any utility class. While not all layouts need a shrinking behavior tied to hovering or focusing, there may be interesting scenarios where you want an item to become more flexible when users interact with it. For instance, you might want a card to shrink slightly on hover so other items can stand out.

In the below example, the third item starts with shrink-0 but changes behavior on hover. When hovered, it applies the shrink utility.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Breakpoint Modifiers

Another central aspect of Tailwind is the responsive design approach. Tailwind provides breakpoint prefixes that you can attach to any utility class. This allows you to define different flex shrink behaviors for different device sizes, ensuring that your layout remains adaptable.

In the below example, the third item will not shrink on md breakpoint or above.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Custom Flex Shrink

In many scenarios, the default classes provided by Tailwind CSS meet your layout requirements. However, there can be unique use cases where you want more granular control or specialized shrink values that aren’t in the standard set. Tailwind conveniently supports customizing its theme to introduce custom shrink values. You can also apply arbitrary shrink values on the fly without modifying your configuration.

Extending the Theme

When you require custom numeric shrink values, you can extend Tailwind’s theme. The typical approach involves editing your tailwind.config.js to add or override specific utilities. This extension gives you the flexibility to define your own scale of shrink values. For instance, if you need an item to shrink at half the rate of a standard item, you might define a utility that does precisely that.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Using Arbitrary Values

Tailwind also allows you to specify arbitrary values for CSS properties directly in your class names. This is beneficial when you want to experiment without updating your Tailwind config or simply need a one-off shrink behavior. Arbitrary values spare you from adding additional lines in your configuration every time you come across a new layout nuance.

Here is an example showing how to apply a custom shrink value on the fly. Take note of how these classes look: shrink-[.75] or shrink-[3], for instance. This direct approach may be simpler for quick prototypes or unique scenarios:

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Real World Examples

File List with Download Progress

A file manager interface that displays files with long names, sizes, and download progress.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Contact Cards with Status

A team directory showing contact cards with long names and email addresses.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Notification Panel with Actions

A notifications interface that handles long notification messages with user mentions.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Flexible News Card

A dynamic news card layout where hovering causes the image to maintain its size while the content adjusts.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Interactive Message List

A message list that uses shrink to control space distribution between sender info and message content on click.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Customization Examples

E-commerce Product Layout

A responsive product view where image and content shrink proportionally when space is limited.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

A row of images that shrink at different rates when space is constrained.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Content Dashboard Layout

This example demonstrates a dashboard layout with sidebar and main content having different shrink behaviors.

This is a live editor. Play around with it!
export default function App() {
  return <h1>Hello world</h1>
}

Best Practices

Maintain Design Consistency

Maintaining design consistency also requires careful planning of shrink behaviors for essential and non-essential components.

Buttons with vital calls to action, for instance, might have a zero shrink rate so that they never diminish in size, while image containers or side widgets can use higher shrink rates to adapt to limited space. By planning these strategies in advance, you can preserve the critical elements of every layout under different screen conditions.

Build Responsive Design

Flex shrink excels in adaptive layouts. Use breakpoint prefixes like sm:shrink-0 or lg:shrink to tailor each component’s shrink behavior to the screen size. This practice ensures essential information remains accessible on smaller devices without preventing layout fluidity on larger screens.

In a responsive design, some components may have restricted space on mobile yet ample room on desktop. By adjusting shrink properties at breakpoints, you can gracefully handle the variation in viewport dimensions. This strategy helps you avoid hidden or truncated content that might confuse users on smaller devices.

Accessibility Considerations

Enhance Readability and Navigability

Applying flex-shrink must go hand in hand with readability. When items compete for space, crucial text or interactive elements can become harder to read, especially for users with low vision. By carefully deciding which elements shrink and which remain fixed, designers ensure that text stays fully visible and large enough to be legible.

Navigation bars and core site structures benefit from limited shrink behavior, preventing key areas from collapsing into tiny, unreadable components. This practice also lessens the cognitive load for screen reader users who rely on a predictable layout.

Focus on High Contrast

High contrast plays a critical role in supporting visually impaired users. When shrink is used, particularly in dynamic content blocks that might resize, ensuring color contrast between text and background remains strong is essential. For example, shrinking a banner or card should not reduce the readability of any text component or interactive label nested within.

Contrast is not limited to color alone. Sufficient font weight, spacing, and element borders become more significant as the container adjusts its size. If an element is allowed to shrink, using appropriate text styling can help preserve clarity.

Debugging Common Issues

Resolve Common Problems

Inadvertent overflows, awkward wrapping, and layout breaking are among the most frequent concerns when mixing shrink with other utilities. One approach to alleviating these issues is to ensure at least one element in the container can expand or shrink sufficiently to absorb extra space. If every element holds a rigid size, the container might force an overflow.

When shrink issues persist, temporarily remove or disable conflicting utilities. Classes like grow, basis-*, or specific widths could be locking the element’s size. Narrowing down these conflicting classes via a process of elimination is often the quickest way to identify the culprit.

Iterative Testing and Maintenance

An iterative approach to refining your shrink logic minimizes regressions. For every new feature or layout change, validate how items shrink on a range of screen sizes. This helps you detect subtle conflicts early, before they escalate.

Version control also plays a significant role in iterative testing. Committing smaller, more focused changes to your layout or shrink values allows you to roll back if issues arise. When combined with component-level reviews, it’s simpler to isolate the commit that introduced an undesired behavior.

As your project grows, maintain thorough documentation of your design patterns, including shrink usage in various sections of the UI. By referencing these patterns, you conduct more effective audits and keep your application consistent over time.