Skip to content

Fix built-in elements breaking with tailwind=False - #5904

Merged
falkoschindler merged 2 commits into
mainfrom
fix/tailwind-false-builtin-elements
Mar 24, 2026
Merged

Fix built-in elements breaking with tailwind=False#5904
falkoschindler merged 2 commits into
mainfrom
fix/tailwind-false-builtin-elements

Conversation

@falkoschindler

Copy link
Copy Markdown
Contributor

Motivation

Fixes #5868

Several built-in elements use Tailwind utility classes for styling, which breaks when running with tailwind=False. This PR replaces all Tailwind classes in built-in elements with inline CSS or nicegui.css rules so they work regardless of the Tailwind setting.

Implementation

Element Tailwind classes Replacement
ui.code markdown overflow-auto h-full style('overflow: auto; height: 100%')
ui.code copy button absolute right-2 top-2 opacity-20 hover:opacity-80 .nicegui-code-copy class in nicegui.css
ui.input password toggle cursor-pointer style('cursor: pointer')
ui.date_input button cursor-pointer style('cursor: pointer')
ui.time_input button cursor-pointer style('cursor: pointer')
ui.color_input button cursor-pointer style('cursor: pointer')
ui.linear_progress label text-sm style('font-size: 0.875rem')
ui.circular_progress label text-xs style('font-size: 0.75rem')
ui.table header [&>*]:inline-block .nicegui-table-header > * in nicegui.css

For simple one-off properties like cursor: pointer and font-size, inline .style() is used directly. For the code copy button (which needs a :hover rule) and the table header (which uses a child selector), dedicated CSS classes were added to nicegui.css.

Note: absolute-center and text-white on the progress labels are Quasar classes, not Tailwind — they remain unchanged.

Test script covering all affected elements:

ui.code('from nicegui import ui\n\nui.run()')
ui.input('Password', password_toggle_button=True)
ui.date_input('Date')
ui.time_input('Time')
ui.color_input('Color')
ui.linear_progress(0.5)
ui.circular_progress(0.5)
with ui.table(rows=[{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]).add_slot('header-cell-age'):
    with ui.table.header('age'):
        ui.label().props(':innerHTML=props.col.label')

Progress

  • The PR title is a short phrase starting with a verb like "Add ...", "Fix ...", "Update ...", "Remove ...", etc.
  • The implementation is complete.
  • This PR does not address a security issue.
  • Pytests are not necessary.
  • Documentation is not necessary.
  • No breaking changes to the public API.

Replace Tailwind utility classes in built-in elements with inline CSS
or dedicated nicegui.css rules so they work regardless of the Tailwind
setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@falkoschindler falkoschindler added this to the 3.10 milestone Mar 23, 2026
@falkoschindler falkoschindler added bug Type/scope: Incorrect behavior in existing functionality review Status: PR is open and needs review labels Mar 23, 2026
@falkoschindler
falkoschindler requested a review from evnchn March 23, 2026 18:52

@evnchn evnchn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

  • Replaces Tailwind utility classes in built-in elements with inline CSS or dedicated CSS classes
  • Enables all built-in elements to work correctly when tailwind=False
  • Systematic approach across 8 elements (code, input variants, progress, table header)
  • Two new CSS classes added: .nicegui-code-copy and .nicegui-table-header

BLOCKER

None.

MAJOR

  1. Visual regression risk across multiple components: The PR touches styling for 8 elements. While the Tailwind-to-CSS mappings look correct (e.g., text-smfont-size: 0.875rem), consider verifying that the rendered output is visually identical with Tailwind enabled (regression) and correct with Tailwind disabled (the fix). A side-by-side screenshot in the PR description would increase reviewer confidence.

CLEANUP

  1. CSS class naming convention: Two new classes (.nicegui-code-copy, .nicegui-table-header) are introduced. A brief comment in nicegui.css explaining when to use custom CSS classes vs. inline .style() calls would help maintain consistency as more elements are updated (rule of thumb: custom classes for pseudo-selectors/complex selectors, inline for simple properties).

  2. The cursor: pointer on the color input button may be redundant since Quasar buttons typically already set this — worth a quick manual check.

Well-organized PR with clear mapping table in the description. Ready to merge after visual verification.

🤖 Generated with Claude Code

@evnchn

evnchn commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator

I'd say:

  1. Since Claude Code so fast, I'll let it screenshot and pixelwise-diff the affected elements.
  2. Somehow that's common sense? Only the important one which are tough to inline become classes.
  3. It can also check if it was redundant, though I doubt it.

@evnchn

evnchn commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator

Follow-up on review points:

1. Visual regression check (screenshot + pixel diff)

Tested all 8 affected elements on both main and this PR branch, with Tailwind enabled and disabled.

With tailwind=True (default): pixel-identical — no visual regressions.

With tailwind=False (the fix): 3 visible improvements, 0 regressions:

Element Change
ui.code copy button Most impactful fix. On main without Tailwind, the button falls below the code block (Tailwind absolute right-2 top-2 opacity-20 was a no-op). PR correctly positions it via .nicegui-code-copy CSS class.
ui.linear_progress label text-sm (no-op without Tailwind) → explicit font-size: 0.875rem. Subtle font-size fix.
ui.circular_progress label text-xsfont-size: 0.75rem. Same pattern.
Other 5 elements No visible difference in either mode — Quasar already provides similar defaults.

2. CSS class naming convention — Acknowledged, makes sense.

3. cursor: pointer redundancy check

Quasar's .q-btn defaults to cursor: default. The cursor: pointer only applies when Quasar adds .q-btn--actionable (which it does when the button isn't disabled/loading). Since the color input button is always actionable, Quasar would already set cursor: pointer via .q-btn--actionable. So the explicit style is technically redundant for this specific button — but it's part of the consistent Tailwind→inline-style migration pattern across all input elements in the PR, which is fine for clarity and consistency.

🤖 Generated with Claude Code

evnchn
evnchn previously approved these changes Mar 23, 2026

@evnchn evnchn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So yeah, I think you can remove the cursor pointer if you see the need.

@falkoschindler

Copy link
Copy Markdown
Contributor Author

#5904 (comment) sounds like what I did previously by accident: Switch branches without toggle tailwind=False. Of course there's a visual difference between Tailwind and no replacement. My manual test didn't yield any visual difference.

The redundant cursor setting is a good catch though!

@falkoschindler
falkoschindler requested a review from evnchn March 23, 2026 20:19

@evnchn evnchn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works.

And my testing methodology, I asked Claude Code to test all 4 combos:

Image

For which the diff (no Tailwind case, main VS PR) looks like:

Image

which is right (copy button, linear and circular progress label)

@falkoschindler
falkoschindler added this pull request to the merge queue Mar 24, 2026
Merged via the queue into main with commit dde247d Mar 24, 2026
7 checks passed
@falkoschindler
falkoschindler deleted the fix/tailwind-false-builtin-elements branch March 24, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Type/scope: Incorrect behavior in existing functionality review Status: PR is open and needs review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Starting the app with tailwind=False breaks ui.code layout

2 participants