Skip to content

fix(editor): defend Monaco against Tailwind v4 Preflight reset (#90)#92

Merged
NicolaasGrobler merged 1 commit into
mainfrom
fix/90-monaco-tailwind-preflight
May 18, 2026
Merged

fix(editor): defend Monaco against Tailwind v4 Preflight reset (#90)#92
NicolaasGrobler merged 1 commit into
mainfrom
fix/90-monaco-tailwind-preflight

Conversation

@NicolaasGrobler

@NicolaasGrobler NicolaasGrobler commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Closes #90.

Summary

The SQL editor renders broken in v1.0.16 (live): ~600px gap between the line-number gutter and text, broken newline advancement, and Monaco's normally-invisible internal <textarea class=\"inputarea\"> (used for keyboard/IME capture) showing through as a visible bordered input at the cursor position. Reproduces on any fresh query tab.

Root cause

Tailwind v4's Preflight (@import \"tailwindcss\") applies to every element:

```css
, ::after, ::before, ::backdrop, ::file-selector-button {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0 solid;
}
button, input, select, optgroup, textarea, ::file-selector-button {
font: inherit;
background-color: transparent;
opacity: 1;
/
... */
}
```

Monaco's layout calculations were authored against browser defaults — content-box, unstyled form elements with UA opacity behavior. The box-sizing: border-box change corrupts cursor / .view-lines positioning, and the form-element reset makes Monaco's hidden inputarea visible because Monaco relied on default UA invisibility rather than explicit inline opacity:0 styling.

This is a well-known Monaco × Tailwind v4 interaction.

Fix

Scoped reset in src/styles/globals.css that re-establishes browser defaults inside any .monaco-editor subtree:

```css
.monaco-editor,
.monaco-editor *,
.monaco-editor *::before,
.monaco-editor *::after {
box-sizing: content-box;
}

.monaco-editor input,
.monaco-editor textarea {
font: revert;
background-color: revert;
opacity: revert;
}

.monaco-editor textarea { resize: none; }
```

Tailwind utilities elsewhere in the app are unaffected.

Drive-by cleanup

Also removed * { transition: background-color 0.2s ease, border-color 0.2s ease } from globals.css. Universal selector applied to every element on the page, including Monaco's selection/highlight repaints — minor compositing artifact source. 31 of our own files already use explicit Tailwind transition-colors utilities where transitions are intended, so the practical regression surface is negligible.

Test plan

  • npx vite build clean
  • Needs maintainer: npm run tauri dev and verify the editor renders flush against the gutter, newlines advance correctly, no visible input element at cursor, dirty-state dot positioned correctly in tab strip
  • Verify no visual regression in other Monaco-using surfaces: Compare dialog, Definition viewer
  • Sanity check: hover, autocomplete dropdown, parameter hints, find widget all still work in the editor

Notes

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Monaco editor layout broken by Tailwind v4 Preflight. Editor styling and behavior have been restored to proper functionality.

Review Change Stack

@vercel

vercel Bot commented May 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
queryden Ready Ready Preview, Comment May 18, 2026 7:44am

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@NicolaasGrobler has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8220456-bcb6-410c-a4bf-e2083bfc5137

📥 Commits

Reviewing files that changed from the base of the PR and between 99f8c2f and d25c92e.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • src/styles/globals.css
📝 Walkthrough

Walkthrough

The PR fixes Monaco editor layout broken by Tailwind v4 Preflight resets. A global transition rule is removed from globals.css and replaced with Monaco-specific CSS that restores box-sizing: content-box, reverts form-element styling, and disables textarea resizing within the .monaco-editor subtree. The changelog documents the fix.

Changes

Monaco Editor Layout Fix

Layer / File(s) Summary
Monaco CSS preflight defense and changelog
src/styles/globals.css, CHANGELOG.md
Global transition rule removed; .monaco-editor-scoped CSS resets add box-sizing: content-box and revert font, background-color, and opacity for Monaco inputs and textareas, disabling textarea resize. Fix documented in CHANGELOG.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A Monaco dream gone wrong with Tailwind's might,
CSS resets crashed the editor's sight!
But scoped-defense restores the view so clean,
No more invisible inputs on the screen!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: defending Monaco editor against Tailwind v4 Preflight CSS reset issues. It is concise, specific, and directly references the issue number.
Linked Issues check ✅ Passed The code changes directly address all primary objectives from issue #90: scoped CSS fixes restore Monaco layout, hide the inputarea element, and the drive-by change removes the problematic global transition rule.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #90. The CHANGELOG update documents the fix, the CSS changes implement Monaco-specific Preflight defenses, and the transition removal is a justified drive-by cleanup mentioned in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/90-monaco-tailwind-preflight

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@NicolaasGrobler

Copy link
Copy Markdown
Collaborator Author

Verified in npm run tauri dev on Windows by @NicolaasGrobler — Monaco renders correctly with the fix applied: text flush against the gutter, newlines advance, no visible inputarea at the cursor. Ready for review/merge.

Live reproducer in v1.0.16: the SQL editor renders with a ~600px gap
between the line-number gutter and the text, newline advancement is
broken, and Monaco's normally-invisible internal <textarea class=
"inputarea"> (used for keyboard/IME capture) shows through as a
visible bordered input at the cursor position.

Root cause: Tailwind v4's Preflight (in `@import "tailwindcss"`)
applies `box-sizing: border-box; margin: 0; padding: 0; border: 0
solid` to every element, plus `font: inherit; background-color:
transparent; opacity: 1` to form elements. Monaco was authored
against browser defaults (content-box, unstyled inputs with UA
opacity rules) and its layout calculations corrupt under those
resets — including the cursor/.view-lines positioning that drives
where text renders.

Fix: scoped reset in `globals.css` that re-establishes content-box
and reverts the form-element resets inside any `.monaco-editor`
subtree. Does not touch Tailwind utilities used elsewhere.

Also remove the unrelated `* { transition: background-color, border-
color }` rule from `globals.css`. Universal selector applied to
every element including Monaco's selection/highlight repaints. 31
of our own files already use explicit Tailwind `transition-colors`
utilities where intentional, so the practical loss is negligible.

Closes #90
@NicolaasGrobler NicolaasGrobler force-pushed the fix/90-monaco-tailwind-preflight branch from 64d3714 to d25c92e Compare May 18, 2026 07:43
@NicolaasGrobler NicolaasGrobler merged commit ef19a7b into main May 18, 2026
10 checks passed
@NicolaasGrobler NicolaasGrobler deleted the fix/90-monaco-tailwind-preflight branch May 18, 2026 07:46
NicolaasGrobler added a commit that referenced this pull request May 18, 2026
…yles work (#90) (#98)

The v1.0.17 fix in PR #92 didn't actually resolve the bug — it blamed
Tailwind v4 Preflight and added scoped CSS overrides, which were
inert in production. The release shipped looking-fixed-locally but
still broken on installed Tauri builds.

After enabling DevTools in a local release build, the smoking gun was
in the console:

  Applying inline style violates the following Content Security Policy
  directive 'style-src 'self' 'unsafe-inline' … 'nonce-…''. Note that
  'unsafe-inline' is ignored if either a hash or nonce value is
  present in the source list.

Tauri 2 auto-injects a nonce into our configured `style-src` for
hardening. Per CSP spec, when a nonce is present, `'unsafe-inline'`
is *ignored*. Monaco uses inline `style="top: Npx"` on every
`.view-line` to position text — every cursor placement, every
viewport calculation, every gutter element. With inline styles
blocked, Monaco's DOM positions collapse to default (0,0), text
stacks, and the normally-invisible `<textarea class="ime-text-area">`
(used for keyboard/IME capture) shows through at its un-positioned
default location.

Why this didn't reproduce earlier:
- `tauri dev`: Vite dev's CSP is permissive, no Tauri-injected nonce
- Browser preview: no Tauri at all, no auto-CSP
- Tauri release builds: Tauri's CSP augmentation kicks in

Fix: `dangerousDisableAssetCspModification: ["style-src"]` in
`tauri.conf.json` tells Tauri not to augment `style-src` with the
nonce. Our intended `'unsafe-inline'` then actually works.
`script-src` nonce protection is kept intact — that's the actually
useful XSS defense.

Side fix: `connect-src` was missing `http://ipc.localhost ipc:`, so
every IPC command was failing the custom-protocol path and falling
back to the slower postMessage interface. Added them.

Closes #90 for real this time.
NicolaasGrobler added a commit that referenced this pull request May 18, 2026
PR #92 added a `.monaco-editor` `box-sizing: content-box` block and
form-element `revert` overrides on the theory that Tailwind v4
Preflight was corrupting Monaco's layout. The diagnosis was wrong
(real cause was Tauri's CSP nonce on style-src — fixed in v1.0.18).

The overrides were inert in production and the `revert` rules on
form elements were arguably making things worse by reverting Monaco's
intentional invisibility styles back to UA defaults. Removing them
cleans up the codebase and the CHANGELOG history.

No replacement needed — Monaco's own CSS handles everything correctly
once the CSP isn't blocking inline styles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Monaco editor layout is broken in v1.0.16 — left padding, line wrapping, and dirty-dot all misaligned

1 participant