Skip to content

fix: add defensive styles to prevent global CSS pollution#214

Merged
mattrothenberg merged 4 commits intomainfrom
fix/defensive-styles
Mar 13, 2026
Merged

fix: add defensive styles to prevent global CSS pollution#214
mattrothenberg merged 4 commits intomainfrom
fix/defensive-styles

Conversation

@mattrothenberg
Copy link
Copy Markdown
Collaborator

Problem

When Kumo components are used in applications with aggressive global styles (e.g., Stratus's cfBaseStyles layer), certain elements get polluted:

  • label { margin-bottom: 1rem } adds unwanted margins to all labels
  • button { background: gray } affects unstyled button wrappers (e.g., tooltip triggers)
  • a { color: var(--text-color-primary) } can override link colors if the consuming app defines --text-color-primary differently (namespace collision)

Solution

Add defensive Tailwind utility classes directly to components. These:

  1. Reset commonly-polluted properties to safe defaults
  2. Use cn() (tailwind-merge) so consumer styles via className still override them
  3. Are no-ops in clean CSS environments (no visual change in Kumo docs)

Changes

Label margins (m-0)

Component Change
Label labelVariants() now includes m-0
Field FieldBase.Label gets m-0
Checkbox label wrapper gets m-0
Radio label wrapper gets m-0
Switch label wrapper gets m-0

Button trigger resets

Component Defensive styles
Tooltip trigger (when !asChild) bg-transparent border-none shadow-none p-0 m-0 h-auto min-h-0 leading-[0] inline-flex items-center
Collapsible trigger bg-transparent border-none shadow-none p-0 m-0

Link color namespace fix

Changed Link from text-primary to text-kumo-link to avoid collision with consuming apps that define --text-color-primary differently. This was causing links to appear white/invisible in Stratus.

Label tooltip composition

Label's tooltip trigger now uses <Button variant="ghost" size="xs" shape="square"> with asChild, leveraging composition instead of relying on defensive resets.

Docs

Added "Custom Trigger" section to Tooltip docs demonstrating that className can fully override defensive styles when not using asChild.

Testing

  • All tests pass
  • Verified Link colors render correctly in docs
  • Designed for testing in Stratus kitchen sink page

Related

This is an alternative approach to PR #207 (data-kumo attributes). Both solve the same problem:

These approaches can be used together or separately depending on the consuming app's needs.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 12, 2026

npm i https://pkg.pr.new/@cloudflare/kumo@214

commit: 96844e2

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 12, 2026

Docs Preview

View docs preview

Commit: 96844e2

- Use !important to override CSS layer styles (margin, padding, border, background)
- Reset pre: margin, border, border-radius, background, padding
- Reset code: margin, padding, background, border
- Add keepMounted to Checkbox.Indicator to prevent DOM removal on toggle
- Use data-[unchecked]:invisible to hide icon while preserving layout
- Add defensive label styles (!m-0 !min-h-0 !text-base) against global CSS pollution

Fixes checkbox jumping issue when used in apps with global label styles.
@mattrothenberg mattrothenberg merged commit cb121bc into main Mar 13, 2026
10 checks passed
@mattrothenberg mattrothenberg deleted the fix/defensive-styles branch March 13, 2026 13:05
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.

2 participants