The Short Version
- It is the markup, not the CSS. The copy was built from
divelements pasted out of Word, and Divi's spacing rule only targetsp. - A paragraph gets 14 pixels, a div gets zero. The two look identical in the builder and render 14 pixels apart live.
- Empty spacer divs are 0 pixels tall. All 17 on that page measured zero, so every blank line the client added rendered as nothing.
- The fix is converting divs to paragraphs. Paste as plain text, and hash the copy before and after to prove only tags moved.
A client sent me a Word document with nine paragraphs highlighted in yellow. She had tried everything and could not get the line breaks to hold on one page. If you have run into Divi text module line breaks that refuse to take, you know the feeling. You add a blank line, you save, you reload, and the page comes back the same.
My going-in theory was a CSS rule flattening everything. I was wrong, and disproving your own theory is the useful part of the story.
The cause was in the markup. The body copy was built out of div elements instead of p elements, the fingerprint of a paste from Word or Google Docs. Divi's spacing rule does not apply to a div, and an empty div is exactly zero pixels tall.
Divi Spaces Paragraphs, and Only Paragraphs
All the visible air between blocks of body copy comes from one pair of rules in Divi's own stylesheet. I pulled these off a live site while writing this post.
Click to see the CSS code: Divi's entire paragraph spacing rule (14 lines)
/* Divi's own stylesheet. This is the whole of the paragraph spacing. */
p {
padding-bottom: 1em;
}
p:not(.has-background):last-of-type {
padding-bottom: 0;
}
/* And the two values 1em resolves against, from Divi's body rule. */
body {
font-size: 14px;
line-height: 1.7em;
}Every p gets 1em of bottom padding, and the last p in its container gets none. Divi's body font size is 14px, so 1em resolves to 14 pixels.
Now read what it does not say. The word div never appears. A div in the same module inherits the font family, size, and line height, so it looks like a paragraph. It gets no bottom padding, so it does not behave like one, and the builder gives you no signal about which one you are looking at.
That gap in the selector is behind almost every report of Divi text module line breaks that will not take. Note too that the spacing is padding, not margin, so the margin collapsing tricks most advice reaches for do nothing here.
How I Ruled Out My Own CSS Theory
I read the site's custom CSS line by line, then all 34 stylesheets loading on the page, looking for anything that touched bottom spacing on a paragraph or a div. Nothing.
Absence of evidence is weak on its own, so I proved the opposite positively. I opened the page in a headless browser, injected a test block into a real text module, and read the computed styles from the rendered document. That makes the browser answer directly. I used the same approach to settle a WooCommerce mystery.
You can run the same check yourself. Open the console on the page and paste this in.
Click to see the JavaScript code: measuring every element in your text modules (18 lines)
// Paste this into the browser console on the page you are checking.
// It prints every direct child of every Divi text module with its
// real rendered height and its bottom spacing.
var modules = document.querySelectorAll('.et_pb_text_inner');
modules.forEach(function (mod) {
mod.childNodes.forEach(function (node) {
if (node.nodeType !== 1) return;
var style = getComputedStyle(node);
console.log(
node.tagName,
'height: ' + Math.round(node.getBoundingClientRect().height) + 'px',
'padding-bottom: ' + style.paddingBottom,
'margin-bottom: ' + style.marginBottom,
JSON.stringify(node.textContent.slice(0, 40))
);
});
});If the output is full of DIV lines with padding-bottom of 0px, you have found your problem.
The 14 Pixels a Div Never Gets
Every row here is a computed value read from the rendered page.
| Element inside a Divi text module | padding-bottom | margin-bottom | Visible gap below it |
|---|---|---|---|
p, not the last one | 14px | 0px | 14px |
p, the last one | 0px | 0px | 0px |
div, any position | 0px | 0px | 0px |
Empty div used as a spacer | 0px | 0px | 0px tall, total |
div containing one non-breaking space | 0px | 0px | 23.8px tall |
A paragraph that is not the last of its type carries 14 pixels of bottom padding. An identically styled div carries zero. That one difference explains the whole page.
The spacers told the same story. The page had 17 empty spacer divs, put there to force a gap, and all 17 measured exactly 0 pixels tall. Only two had any height, and both held a single non-breaking space. Those measured 23.8 pixels, which is 14px times Divi's line height of 1.7.
That is not Divi stripping anything. It is the browser following the specification. Per the W3C CSS 2.1 visual formatting model, a line box with no text and no in-flow content is treated as zero height. Put one character in it, even an invisible one, and the browser has a line to draw.
So the client was not doing anything wrong. Her blank lines rendered faithfully, at their true height, which was nothing. Every attempt looked like a failure and every attempt had worked as instructed.
How a Word Paste Kills Divi Text Module Line Breaks
Word and Google Docs put rich HTML on your clipboard, not plain text. That markup carries its own element choices, inline styles, and classes you never asked for, and some of it survives. This is why the advice is to never paste directly from Google Docs into WordPress.
A second mechanism makes it stick. WordPress normally turns double line breaks into real paragraph tags through wpautop(). Per the WordPress developer documentation, that function keeps a hardcoded list of block-level elements it will not reformat, and div is on it. The paste puts divs in, and the safety net declines to take them out.
Paste as Plain Text, or Paste and Then Convert
The prevention is one keystroke. Use Ctrl+Shift+V on Windows or Cmd+Shift+V on a Mac to paste without formatting. You lose bold and italics and re-apply them in thirty seconds.
If the content is already on the page, the fix is a conversion, not a settings change. Open each module's code view and change every content div to a p. On this project that meant 13 text modules.
Three things to do while you are in there:
- Delete the empty spacer divs rather than filling them with non-breaking spaces. Those cause strange word wrapping on narrow screens, which trades a spacing bug for a layout bug on phones. Gaps belong in the module's own spacing settings.
- Remove wrapper divs. A div that exists only to hold one paragraph does nothing but break the spacing rule.
- Preserve every shortcode attribute verbatim. Divi stores module content inside shortcodes, and a careless rewrite eats attributes silently.
A page full of pasted divs usually means a neglected site, so check where the custom CSS lives too. I have written before about code snippets versus a child theme.
The Check That Proves You Only Moved Tags
Here is the part worth stealing. Any time you rewrite tags, prove you did not change a word. Clients notice missing sentences long before missing pixels.
Before touching anything, I extracted the rendered text of every module, stripped the tags, collapsed the whitespace, and took a SHA-256 hash. The baseline was 17,627 characters across 86 lines. After the conversion I hashed it again.
The hashes were identical. That is a mathematical guarantee that only the tags moved. Two minutes of setup turns a nervous handoff into a confident one.
Three Questions That Come Up Next
Is this a Divi bug?
No. Divi renders what is in the module, and the browser measures what Divi renders. Divi has a real learning curve, and I have written about whether it suits beginners, but this is not one of its rough edges. Adding more blank lines will not help either, because each one is another empty div and another zero pixels.
How do I tell which one I have without opening a console?
Switch the module from visual to text view and look at the raw markup. If you see div where you expect p, that is your answer. On the front end, right-click a paragraph and choose Inspect.
Can I fix it with a database find and replace?
Please do not. Divi stores module content inside shortcodes in post_content, and a blind search and replace will chew through an attribute and break a module in a way that is tedious to trace. Work module by module and verify with the hash check. On a 13 module page that took well under an hour, verification included.
The One Thing To Remember
In Divi, the space between paragraphs comes from a rule that only knows about p. If your module is full of divs, there is nothing for that rule to act on. The builder is not ignoring you. It is rendering elements that have no height. Broken Divi text module line breaks are almost always a markup problem wearing a styling costume.
Paste as plain text and you never meet this problem. If you inherited a site where somebody did the other thing across a few dozen pages, that is a real cleanup job with a real verification step, and it is the kind of work I do for clients every week.
Sources
- W3C, CSS 2.1 Visual formatting model, section 9.4.2 Inline formatting contexts
- WordPress Developer Resources, wpautop()
- MDN Web Docs, padding-bottom
- Digital Ink, Before You Paste from Google Docs into WordPress, Do This
- Elegant Marketplace, Help! My paragraphs and line breaks keep disappearing from the Divi text module
- Divi Booster, Reducing Divi Builder Module Spacing




0 Comments