0Support

CSS text-wrap playground

Explore text-wrap with a selector for comparing line breaking, balanced headings, and readability-focused wrapping.

Read the guide

Ask AI

CSS text-wrap playground

Response generated with openai/gpt-5.4-nano. AI can make mistakes. Always review the result.

BaselineLab creates clear headings for responsive interfaces. Adjust text-wrap and observe how line breaks change in a narrow block.

HTML
<p class="text-wrap-sample">
  BaselineLab creates clear headings for responsive interfaces.
  Adjust text-wrap and observe how line breaks change in a narrow block.
</p>
Tailwind CSS
Some classes with arbitrary values can be replaced by native classes, depending on the value and your Tailwind CSS configuration.
<p class="max-w-md text-4xl font-bold leading-tight text-balance">
  BaselineLab creates clear headings for responsive interfaces.
  Adjust text-wrap and observe how line breaks change in a narrow block.
</p>
CSS
.text-wrap-sample {
  max-inline-size: 28rem;
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}

Educational guide to text-wrap

Choose how text is distributed across lines

Compare wrap, balance, and pretty for different content. Learn what nowrap prevents, why stable matters while editing, and how width, fonts, and browsers change the result.

Back to the playground

Mental model

The browser chooses breaks inside a box that already has its own width.

Box, opportunities, and choiceConceptual diagram of three decisions; the bars are neither measurements nor output from a real algorithm.
  1. 1 · Available widthinline-size and the font determine how much text fits on each line.
  2. 2 · Wrapping opportunitiesLanguage, spaces, and breaking rules allow certain breaks.
  3. 3 · Line selectiontext-wrap chooses between those breaks; it does not create space or change characters.

text-wrap controls automatic line breaks, not box width or font size. wrap allows normal wrapping; nowrap prevents those breaks. balance, pretty, and stable guide the choice between existing wrapping opportunities.

It is a shorthand for text-wrap-mode and text-wrap-style. text-wrap: balance is equivalent to wrap balance. Omitting one part resets it to its initial value: wrap for mode and auto for style. Use longhands to change only one part.

.title { text-wrap: balance; }.title { text-wrap-mode: wrap; text-wrap-style: balance; }

wrap and balance for headings

Same content and width; a different composition strategy.

wrap prioritizes normal wrapping. balance aims for similar line lengths in short blocks such as headings or quotations. It does not center text like text-align or guarantee identical line lengths.

A heading with normal and balanced wrapping

text-wrap: wrap

Design interfaces that remain clear when the available width changes

text-wrap: balance

Design interfaces that remain clear when the available width changes
Both boxes allow up to 22ch and share text and font. balance may leave more space at line ends without reducing the box width. If the heading fits on one line, the difference disappears.
A heading with normal and balanced wrapping
<div class="wrap-guide-headings">
  <div>
    <p class="wrap-guide-label">text-wrap: wrap</p>
    <h5 class="wrap-guide-normal">Design interfaces that remain clear when the available width changes</h5>
  </div>
  <div>
    <p class="wrap-guide-label">text-wrap: balance</p>
    <h5 class="wrap-guide-balanced">Design interfaces that remain clear when the available width changes</h5>
  </div>
</div>
:root {
  color-scheme: light dark;
}

.wrap-guide-headings {
  display: grid;
  gap: 2rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));

  .wrap-guide-label {
    margin: 0 0 0.75rem;
    font: 1rem/1.6 system-ui, sans-serif;
  }

  h5 {
    margin: 0;
    max-inline-size: 22ch;
    font: 800 1.75rem/1.3 system-ui, sans-serif;
    overflow-wrap: anywhere;
    text-wrap: wrap;
  }

  .wrap-guide-balanced {
    text-wrap: balance;
  }
}

The balance limit depends on the engine: MDN documents up to six lines in Chromium and ten in Firefox. Do not make this a layout contract; normal wrapping may apply beyond the limit. Use it for short blocks and check actual width, translations, and fallback fonts.

wrap and pretty for paragraphs

Better composition does not mean balancing every line.

pretty favors typographic quality over speed. It can avoid a very short last line and improve other breaks. Algorithms vary: Chromium focuses on the end of the paragraph; WebKit may consider the entire paragraph. It does not promise to remove every isolated word.

A paragraph with normal and pretty wrapping

text-wrap: wrap

An interface needs text that can grow with translations and reading preferences. Choosing line breaks carefully improves composition, but does not replace a readable measure, a suitable font, or space between lines. Always check the result with real content.

text-wrap: pretty

An interface needs text that can grow with translations and reading preferences. Choosing line breaks carefully improves composition, but does not replace a readable measure, a suitable font, or space between lines. Always check the result with real content.

Both samples allow up to 28ch to make the breaks visible. The difference may be subtle or absent depending on text, width, and engine. If pretty is unsupported, that declaration is ignored and wrap remains; the first sample is an explicit reference.
A paragraph with normal and pretty wrapping
<div class="wrap-guide-paragraphs">
  <div>
    <p class="wrap-guide-label">text-wrap: wrap</p>
    <p class="wrap-guide-normal">An interface needs text that can grow with translations and reading preferences. Choosing line breaks carefully improves composition, but does not replace a readable measure, a suitable font, or space between lines. Always check the result with real content.</p>
  </div>
  <div>
    <p class="wrap-guide-label">text-wrap: pretty</p>
    <p class="wrap-guide-pretty">An interface needs text that can grow with translations and reading preferences. Choosing line breaks carefully improves composition, but does not replace a readable measure, a suitable font, or space between lines. Always check the result with real content.</p>
  </div>
</div>
:root {
  color-scheme: light dark;
}

.wrap-guide-paragraphs {
  display: grid;
  gap: 2rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));

  p {
    margin: 0;
    max-inline-size: 28ch;
    font: 1.125rem/1.7 system-ui, sans-serif;
    overflow-wrap: anywhere;
    text-wrap: wrap;
  }

  .wrap-guide-label {
    margin-block-end: 0.75rem;
    font-size: 1rem;
  }

  .wrap-guide-pretty {
    text-wrap: pretty;
  }
}

Use balance for short headings and pretty for selected prose. Evaluating multiple breaks has a different cost from normal wrapping; avoid imposing one strategy on the entire document without measuring. Neither replaces line-height or a comfortable reading width.

nowrap, forced breaks, and long words

Preventing automatic wrapping can cause overflow.

nowrap preserves forced breaks, such as br, while preventing automatic ones. It does not shrink text or add an ellipsis. This comparison contains scrolling inside the sample; for prose and controls that must grow, allowing wrap is usually preferable.

A long line and an explicit break

text-wrap: wrap

A long piece of text needs room to keep all of its words available.

text-wrap: nowrap

A long piece of text needs room to keep all of its words available.

text-wrap: nowrap + <br>

First explicit line.
Second explicit line.

The first sample wraps. The second can scroll horizontally; focus it to use the keyboard. The third preserves its br despite nowrap. No text is hidden and no truncation is simulated.
A long line and an explicit break
<div class="wrap-guide-nowrap">
  <div>
    <p class="wrap-guide-label">text-wrap: wrap</p>
    <p class="wrap-guide-normal">A long piece of text needs room to keep all of its words available.</p>
  </div>
  <div>
    <p class="wrap-guide-label">text-wrap: nowrap</p>
    <p class="wrap-guide-single" tabindex="0" role="region" aria-label="text-wrap: nowrap">A long piece of text needs room to keep all of its words available.</p>
  </div>
  <div>
    <p class="wrap-guide-label">text-wrap: nowrap + &lt;br&gt;</p>
    <p class="wrap-guide-single" tabindex="0" role="region" aria-label="text-wrap: nowrap + &lt;br&gt;">First explicit line.<br>Second explicit line.</p>
  </div>
</div>
:root {
  color-scheme: light dark;
}

.wrap-guide-nowrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));

  p {
    margin: 0;
    max-inline-size: 24ch;
    font: 1.125rem/1.7 system-ui, sans-serif;
    text-wrap: wrap;
  }

  .wrap-guide-label {
    margin-block-end: 0.75rem;
    font-size: 1rem;
    overflow-wrap: anywhere;
  }

  .wrap-guide-normal {
    overflow-wrap: anywhere;
  }

  .wrap-guide-single {
    text-wrap: nowrap;
    overflow: auto;

    &:focus-visible {
      outline: 2px solid currentColor;
      outline-offset: 3px;
    }
  }
}

overflow-wrap solves a different problem: it allows emergency breaks in strings that do not fit, such as URLs. white-space also controls spaces and breaks; a later declaration may reset text-wrap-mode. Check the cascade before blaming balance or pretty for overflow.

stable while editing content

Preserve lines before an edit without blocking reflow.

stable targets editable text: changing a line should not recompose earlier lines because of that edit. It does not freeze layout when width or fonts change, or save content. A static sample may look identical to wrap.

Edit a block with stable

Editable text · text-wrap: stable

Edit the last lines and observe earlier breaks. Changes are not saved.

This block lets you test composition while typing. Keep the first sentences and add a few words at the end to observe which lines the browser preserves. The result depends on support and the engine algorithm.
Enter with Tab and edit one of the last lines. Observe earlier lines in your engine. Changes stay in this sample: they are not saved, do not affect the playground, and the code represents the initial recipe. Reload to restore the text.
Edit a block with stable
<div class="wrap-guide-editing">
  <p id="wrap-guide-editor-label">Editable text · text-wrap: stable</p>
  <p id="wrap-guide-editor-hint">Edit the last lines and observe earlier breaks. Changes are not saved.</p>
  <div class="wrap-guide-editor" contenteditable="true" role="textbox" aria-multiline="true" aria-labelledby="wrap-guide-editor-label" aria-describedby="wrap-guide-editor-hint">This block lets you test composition while typing. Keep the first sentences and add a few words at the end to observe which lines the browser preserves. The result depends on support and the engine algorithm.</div>
</div>
:root {
  color-scheme: light dark;
}

.wrap-guide-editing {
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
  font: 1rem/1.6 system-ui, sans-serif;

  p {
    margin: 0 0 0.75rem;
    text-wrap: wrap;
  }

  .wrap-guide-editor {
    box-sizing: border-box;
    max-inline-size: 38ch;
    min-block-size: 6lh;
    padding: 0.75rem;
    border: 1px solid currentColor;
    border-radius: 16px;
    corner-shape: squircle;
    font-size: 1.125rem;
    line-height: 1.7;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    text-wrap: wrap;
    text-wrap: stable;

    &:focus-visible {
      outline: 2px solid currentColor;
      outline-offset: 3px;
    }
  }
}

The recipe keeps wrap as its base and adds stable. CSS.supports can confirm that the value is recognized, but does not certify behavior during editing. A complete editor requires further decisions; this field only tests native wrapping.

Common pitfalls

Check content, width, cascade, and support for the specific value.

balance does not change the heading

Expected result
See a different distribution of lines.
Cause
It fits on one line, exceeds the engine limit, or already has balanced breaks.
Solution
Try a width with a few lines and real content; check the computed value.

The box stays just as wide

Expected result
Have the background fit the balanced lines.
Cause
text-wrap changes breaks, not inline-size or the container layout.
Solution
Design box width separately and avoid depending on the last line length.

pretty leaves a short last line

Expected result
Always eliminate an isolated word.
Cause
The value may be unsupported or the algorithm cannot find a better composition.
Solution
Review support, font, and measure; keep a readable result with wrap.

nowrap makes the page scroll horizontally

Expected result
Keep content inside the viewport.
Cause
Automatic breaks are prevented without providing space or handling overflow locally.
Solution
Allow wrap for content that must grow; reserve nowrap for limited, accessible cases.

stable seems to do nothing

Expected result
See a change when selecting it for static text.
Cause
Its purpose appears during editing; it is not another form of balance.
Solution
Try editable content and check behavior in your target browsers.

Support and compatibility

The shorthand and its values do not share a single support timeline.

The general card does not guarantee every value. balance and pretty have separate entries in Web Platform DX. At the consultation date, MDN BCD lists pretty in Chrome 117 and Safari 26, and not in Firefox; stable starts in Chrome 130, Firefox 121, and Safari 17.5. Review current tables before publishing or setting requirements.

Start with text that wraps and remains readable. Declare wrap before an enhancement and avoid accidentally inheriting nowrap as the base. @supports (text-wrap: pretty) can condition associated styles; it detects syntax, not break quality. Samples use the real engine without polyfills.