The symptom showed up minutes after I added Tailwind v4 to a custom WordPress theme. No console error, no build warning — just one thing that felt instantly wrong the moment I opened an article: every image that should have been floating to the left or right of the text was suddenly stacked vertically. The editor still showed the correct layout, but on the frontend, every alignleft and alignright image had become a full-width block, the text no longer wrapped beside it, and posts that used to read cleanly were now a vertical pile.
The markup Gutenberg produced hadn't changed at all. It was still exactly this:
<figure class="wp-block-image alignleft">
<img src="/wp-content/uploads/photo.jpg" alt="" />
</figure>
<h2>Subheading that should wrap to the right of the image</h2>
<p>A paragraph that should flow beside the image...</p>The alignleft class was still in the HTML. So what went missing wasn't the markup — it was the CSS that drives it. And the only new thing in my pipeline was Tailwind.
Why this happens
Tailwind v4 ships preflight — its built-in CSS reset — by default the moment you import its main stylesheet. Preflight is aggressive on purpose: it scrubs cross-browser inconsistencies so that utility classes behave predictably. Two of its rules are what killed WordPress alignment.
First, preflight sets every image to display: block. Second, it strips default margins off elements. The problem is that WordPress alignment depends entirely on float plus specific side margins on the image — and historically, a lot of that "just worked" thanks to built-in editor styles and browser defaults. Once preflight forces img { display: block } and strips the margins, the floats on .alignleft/.alignright lose the context that normally made them behave, and the aligncenter/alignwide/alignfull images lose the auto margins and widths that center or extend them.
Here's the core of it: a CSS reset silently removed WordPress's built-in editor styles. WordPress never re-declares its alignment rules somewhere safe from preflight, so once the reset lands, those classes are just names with no effect. Nothing "broke" in the error sense — everything did exactly what Tailwind asked it to.
The fix
The answer isn't to disable preflight (I want that reset for the rest of the theme) — it's to re-add the alignment rules preflight removed, surgically, only what's needed:
.alignleft {
float: left;
margin: 0 1.5em 1em 0;
}
.alignright {
float: right;
margin: 0 0 1em 1.5em;
}
.aligncenter {
display: block;
margin-left: auto;
margin-right: auto;
}
.alignwide {
max-width: 1100px;
margin-left: auto;
margin-right: auto;
}
.alignfull {
width: 100vw;
max-width: 100vw;
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
}As soon as these five rules land, alignleft and alignright float again, the text wraps, and alignwide/alignfull extend the way they should.
Then comes the temptation you have to resist. With floats live again, you'll see headings occasionally "stick" beside a floated image — the next H2 rides up alongside the image instead of dropping below it. My reflex was to throw clear: both on every heading, or on every descendant inside the content section. Don't.
A clear: both rule on headings does push H2/H3 down below the floated image — but that's exactly what breaks parity between the editor and the frontend. The TinyMCE editor doesn't clear its headings, so the moment you force a clear on the frontend, the layout you saw while writing no longer matches the layout your reader sees. The float that was supposed to wrap the heading gets cut off. You've traded one visual glitch for a more confusing inconsistency.
There's exactly one correct place to clear floats: the <hr>, i.e. the Separator block. It's meant to be a divider, so clearing there is safe and makes sense:
hr {
clear: both;
}The last touch is heading rhythm. After the reset, my heading top margins didn't match what the editor rendered, so the vertical spacing on the frontend felt different from what was typed in TinyMCE. I tuned them to TinyMCE's rhythm — around 1.4em on H2, not the 2em I'd briefly used:
h2 {
margin-top: 1.4em;
}That number isn't an arbitrary aesthetic choice; it's what makes the rendered post match what the author sees in the editor. The end goal is always parity: what you write is what people read.
The takeaway
A CSS reset can silently strip WordPress's built-in editor styles, and it won't tell you — no error, just a layout that quietly goes wrong. When you add Tailwind (or any reset) to an older WordPress theme, assume Gutenberg alignment will break, then re-add the alignleft/alignright/aligncenter/alignwide/alignfull rules surgically. And resist the urge to spray clear: both everywhere just to tidy up floats: clear only on <hr>, let floats wrap headings the way the editor does, and tune heading margin rhythm so the frontend matches TinyMCE. The reset gives you a clean baseline — your job is to put back the things WordPress deliberately brought along, without overcorrecting.
