Table of Contents
Overview
We had been using word-break: break-word to prevent long strings from overflowing their containers. However, we recently discovered that this value is deprecated. According to the MDN documentation, word-break: break-word is a legacy value that has the same effect as combining overflow-wrap: anywhere with word-break: normal, and it is explicitly marked as deprecated.
We then switched to overflow-wrap: break-word, but found that line breaking stopped working on certain elements.
After investigating, we discovered a subtle but critical difference between overflow-wrap: break-word and overflow-wrap: anywhere. In this post, we share our analysis of the root cause, the solution, and how we automated detection and fix recommendations using a Stylelint custom plugin.
For Stylelint configuration details, please refer to the following post.
What is overflow-wrap?
overflow-wrap is a safety net that forces line breaks in long strings that would otherwise overflow their container. It does nothing under normal circumstances and only activates when overflow occurs.
How It Works with English Text
Regular English sentences naturally wrap at spaces regardless of overflow-wrap.
This is a sample
text for testing
word wrap behavior.
However, long strings without spaces — such as URLs or serial numbers — will overflow. When overflow-wrap is set, it forces a line break at the overflow point.
- Without overflow-wrap
https://example.com/very/long/path/to/resource ← Overflow!
- With overflow-wrap
https://example.co
m/very/long/path/t
o/resource
The Difference Between break-word and anywhere
The two overflow-wrap values break-word and anywhere produce identical visual line-breaking results.
// break-word
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef
// anywhere
Password:
aB3$kL9mNpQrStUvWx
Yz1234567890abcdef
The difference lies in layout calculation (min-content).
break-word: Does NOT consider soft wrap opportunities when calculating min-content intrinsic sizes. The minimum width equals the full word width.anywhere: Does consider soft wrap opportunities when calculating min-content intrinsic sizes. The minimum width can shrink down to a single character.
The MDN documentation clearly explains this difference:
anywhere: “Soft wrap opportunities introduced by the word break are considered when calculating min-content intrinsic sizes.”break-word: “Soft wrap opportunities introduced by the word break are NOT considered when calculating min-content intrinsic sizes.”Source: MDN - overflow-wrap
This difference is exactly why break-word fails on certain elements.
Why break-word Fails
The problematic element had display: inline-block applied to it.
inline-block is an intrinsic sizing element whose size is determined by its content.
- Reference: MDN - Intrinsic Size
The element’s width is determined based on min-content. The min-content calculation difference explained earlier causes problems here.
- With inline-block + break-word
min-content = full word width (260px)
→ Element expands to 260px
→ No overflow occurs
→ break-word is not triggered
→ No line break!
- With inline-block + anywhere
min-content = single character width (~8px)
→ Width constrained by parent
→ Overflow occurs
→ Line break happens!
In summary, break-word only breaks lines “when overflow occurs,” but since it doesn’t include soft wrap opportunities in the min-content calculation for intrinsic sizing elements, the element itself expands so that no overflow occurs in the first place. As a result, line breaking is never triggered.
Other CSS Properties with the Same Issue
Besides inline-block, all CSS properties that use intrinsic sizing have the same problem.
| CSS Property | Reason |
|---|---|
display: inline-block | Width determined by content |
display: inline-flex | Inline-level flex container |
display: inline-grid | Inline-level grid container |
display: table-cell | Content-based width |
float: left / right | Shrink-to-fit |
position: absolute / fixed (without width) | Shrink-to-fit |
width: min-content / fit-content | Explicit intrinsic sizing |
All of these properties determine width based on content, so the min-content calculation behavior of break-word prevents line breaking from working.
- Reference: MDN - Block formatting context
Recommended CSS Combination
To solve this problem, we recommend using the following three CSS properties together.
overflow-wrap: anywhere;
word-break: normal;
line-break: strict;
Role of Each Property
overflow-wrap: anywhere
Forces line breaks to prevent long strings from overflowing the container. Unlike break-word, it includes soft wrap opportunities in the min-content calculation, so it works correctly on intrinsic sizing elements.
word-break: normal
Uses the default word-breaking rules. English text wraps at spaces, while Japanese and Chinese (CJK) text wraps at character boundaries. Since this is the default value, it can be omitted, but it is good practice to explicitly declare it where word-break: break-word was previously applied to make the intent clear.
The behavioral differences for each word-break value are as follows:
| Value | English | Japanese, Chinese (CJK) |
|---|---|---|
normal | Word-level line breaks | Character-level line breaks |
break-all | Character-level breaks | Same as normal |
keep-all | Same as normal | Word-level line breaks (overflow risk) |
line-break: strict
Enforces strict Japanese kinsoku processing (禁則処理). It controls characters that should not appear at the beginning of a line (、 。 ぁ っ 々 ー, etc.), producing more natural text.
- Without strict →
々appears at the beginning of a line (unnatural)
そこは湖のほ
とりで木
々が輝いてい
- With strict →
木々stays together (natural)
そこは湖の
ほとりで
木々が輝い
This has no practical effect on English text, so it can be applied without side effects.
References:
Combined Effect of All Three Properties
For English text:
# Input: "Visit this link: https://example.com/very/long/path/to/resource"
Visit this link: ← word-break: normal (wraps at space)
https://example.co ← overflow-wrap: anywhere (forced break at overflow point)
m/very/long/path/t
o/resource
For Japanese text:
# Input: "デバイスID: ABCDEFGHIJKLMNOPQRSTUVWXYZ を確認してください。"
デバイスID: ← word-break: normal (CJK character-level wrapping)
ABCDEFGHIJKLMNOPQR ← overflow-wrap: anywhere (forced break for Latin text)
STUVWXYZを確認し
てください。 ← line-break: strict (「。」 does not appear at line start)
Can We Use anywhere Everywhere?
The visual line-breaking results of break-word and anywhere are identical — the only difference is in the min-content calculation.
When unifying to anywhere, there is a theoretical possibility that space distribution in flex/grid/table layouts could change. Since anywhere allows min-content to shrink down to a single character width, flex items might shrink smaller than expected, or grid tracks might become narrower.
However, this rarely causes issues in practice. Here’s why:
- min-content is only a lower bound. The actual rendered width is determined by other properties such as
flex-basis,width, andgrid-template-columns. A smaller min-content doesn’t mean the element immediately shrinks to that size. - In flex layouts,
flex-grow/flex-shrinkdistribute space. Most flex items haveflex: 1or a fixedflex-basis, so min-content differences don’t affect the final width. min-content only matters when determining the minimum limit below which an item cannot shrink. - In grid layouts, track sizes are typically declared explicitly. Declarations like
grid-template-columns: 1fr 2frorminmax(200px, 1fr)are common, so changes in min-content don’t affect track sizes. Only when using themin-contentkeyword directly as a track size would differences appear, and this is a rare pattern. - In tables,
table-layout: fixedis commonly used. With fixed layout, sizes are determined by column width declarations rather than cell content, so min-content differences are ignored. Onlytable-layout: auto(the default) could be affected, but even then, proper line breaking is a better outcome than text overflowing.
In contrast, using break-word causes a real bug where line breaking fails on intrinsic sizing elements, as we saw earlier. Therefore, unifying to anywhere is the safer choice.
Why is word-break: break-word Deprecated?
word-break: break-word is not a formally defined value in the CSS3 specification. It was originally supported by browsers as a legacy alias for overflow-wrap: break-word for backwards compatibility. The CSS Text Level 3 spec also explicitly marks this value as deprecated and recommends using overflow-wrap: anywhere instead.
Automating with a Stylelint Custom Plugin
It’s difficult for developers to remember these rules every time. So we created a Stylelint custom plugin to automatically detect violations and provide error messages with the correct alternative combination.
For Stylelint configuration details, please refer to the following post.
Detection Rules
| Target | Error Message |
|---|---|
overflow-wrap: break-word | May not break as expected in some cases, deprecated → suggests 3-property set |
word-break: break-word | Deprecated → suggests 3-property set |
overflow-wrap: anywhere + missing line-break: strict | Suggests adding line-break: strict |
Plugin Code
Create a plugins/require-strict-wrap-rules.js file in the project root and write the following.
'use strict';
const stylelint = require('stylelint');
const ruleName = 'custom/require-strict-wrap-rules';
const REPLACEMENT =
' Use "overflow-wrap: anywhere; word-break: normal; line-break: strict;" instead.';
const messages = stylelint.utils.ruleMessages(ruleName, {
rejectedOverflowWrapBreakWord:
'"overflow-wrap: break-word" may not break as expected in some cases and is deprecated.' +
REPLACEMENT,
rejectedWordBreakBreakWord:
'"word-break: break-word" is deprecated.' + REPLACEMENT,
rejectedLineBreak:
'When using overflow-wrap: anywhere, also specify "line-break: strict"' +
' (required for Japanese kinsoku processing).',
});
const ruleFunction = (primary) => {
return (root, result) => {
const validOptions = stylelint.utils.validateOptions(result, ruleName, {
actual: primary,
possible: [true],
});
if (!validOptions) return;
root.walkRules((rule) => {
let anywhereNode = null;
let hasLineBreakStrict = false;
rule.walkDecls((decl) => {
if (decl.prop === 'overflow-wrap' && decl.value === 'break-word') {
stylelint.utils.report({
message: messages.rejectedOverflowWrapBreakWord,
node: decl,
result,
ruleName,
});
}
if (decl.prop === 'word-break' && decl.value === 'break-word') {
stylelint.utils.report({
message: messages.rejectedWordBreakBreakWord,
node: decl,
result,
ruleName,
});
}
if (decl.prop === 'overflow-wrap' && decl.value === 'anywhere') {
anywhereNode = decl;
}
if (decl.prop === 'line-break' && decl.value === 'strict') {
hasLineBreakStrict = true;
}
});
if (anywhereNode && !hasLineBreakStrict) {
stylelint.utils.report({
message: messages.rejectedLineBreak,
node: anywhereNode,
result,
ruleName,
});
}
});
};
};
ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;
module.exports = stylelint.createPlugin(ruleName, ruleFunction);
Stylelint Configuration
Add the plugin and rule to the .stylelintrc.json file in the project root.
{
"plugins": ["./plugins/require-strict-wrap-rules.js"],
"rules": {
"custom/require-strict-wrap-rules": true
}
}
Output Results
When running Stylelint with this rule configured, the following error messages will be displayed.
- When using overflow-wrap: break-word
✖ "overflow-wrap: break-word" may not break as expected in some cases and is deprecated.
Use "overflow-wrap: anywhere; word-break: normal; line-break: strict;" instead.
- When using word-break: break-word
✖ "word-break: break-word" is deprecated.
Use "overflow-wrap: anywhere; word-break: normal; line-break: strict;" instead.
- When line-break: strict is missing with overflow-wrap: anywhere
✖ When using overflow-wrap: anywhere, also specify "line-break: strict"
(required for Japanese kinsoku processing).
Conclusion
CSS line-breaking properties may look similar, but subtle differences can cause them to behave unexpectedly. Here is a summary of what we covered in this post.
| Deprecated | Recommended |
|---|---|
word-break: break-word | overflow-wrap: anywhere |
overflow-wrap: break-word | word-break: normalline-break: strict |
overflow-wrap: anywhereworks correctly on intrinsic sizing elements (inline-block,inline-flex,float, etc.), unlikebreak-word.word-break: normalprovides the most natural line breaking for both English and Japanese (CJK) text.line-break: strictenforces strict Japanese kinsoku processing for higher text quality.- Automating these rules with a Stylelint custom plugin eliminates the need for developers to remember them every time.
References
- MDN - overflow-wrap
- MDN - word-break
- MDN - line-break
- MDN - Intrinsic Size
- MDN - Block Formatting Context
- W3C - CSS Text Level 3: overflow-wrap
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku.Deku created the applications with Flutter.If you have interested, please try to download them for free.