Skip to content

fix(a11y): use pixels for spacing to allow for better text zoom#980

Open
knowler wants to merge 1 commit intonpmx-dev:mainfrom
knowler:spacing-use-px
Open

fix(a11y): use pixels for spacing to allow for better text zoom#980
knowler wants to merge 1 commit intonpmx-dev:mainfrom
knowler:spacing-use-px

Conversation

@knowler
Copy link
Contributor

@knowler knowler commented Feb 5, 2026

Browsers have two kinds of zoom:

  1. The regular type which scales the size of everything.
  2. Text specific zoom which is meant for scaling text specifically.

While rem units have long been held as a best practice unit over px, that’s really only true of text. If we use rem for spacing, we lose the distinction between the two aforementioned kinds of zoom. This problem has been noted by Ashlee Boyer and Josh Comeau in recent years. In my experience, this newer best practice has proliferated throughout the design systems space (at least for those who care about accessibility).

The goal of this PR is to restore the distinction and, in turn, act as a first step for improving the experience of zooming text for the app. Simply changing from 0.25rem as the spacing unit to 4px should have no consequences for anyone not using text zoom, as 16px is the default font size and 4px would’ve been the computed size of the unit. For those using text zoom, this change will mean that anything using spacing units will no longer increase with the text size. This gives more room for the text in place which in turn helps with readability.

Like I said, this is a first step. I do think we will find places where rem makes sense to be used for spacing, but I think we can handle them in future PRs. There’s other places where rem use could be problematic, such as border-radius and some sizing. This first step sets the stage for us to better design the text zoom experience.

Testing

In Safari, you can change the text zoom by either:

  1. Holding option while opening the “View” menu. The “Zoom In” and “Zoom Out” options will change to “Make Text Bigger” and “Make Text Smaller” respectively.
  2. There are also convenient shortcuts: commandoption+ and commandoption-.

In Chromium-based browsers, you can set the text size in chrome://settings/appearance. There are two options: using relative named sizes and changing the specific pixel size.

In Firefox, in about:preferences you can change the default font size or you can enable ”Zoom text only” for the default zoom level.

If you are testing for “regressions” I’d recommend sticking to the default text zoom. Like I said, this change should have no effect on that experience. The zoomed text experience might feel visually off. That’s normal. This is an accessibility preference taking precedence over design. We can improve the design of this experience, but we will need to specifically cater to that preference.

@vercel
Copy link

vercel bot commented Feb 5, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 5, 2026 1:18am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 5, 2026 1:18am
npmx-lunaria Ignored Ignored Feb 5, 2026 1:18am

Request Review

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

The change modifies the UnoCSS configuration file to extend the theme object with a new spacing configuration. A default spacing value of 4px is introduced to the theme's spacing scale. This addition integrates with the existing typography and colour configuration within the theme object. No modifications are made to other theme tokens, behaviour, or public interfaces. The change consists of a single line addition with no lines removed.

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description comprehensively explains the rationale for changing spacing units from rem to px for accessibility, directly addressing the code change in uno.config.ts.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

].filter(Boolean),
transformers: [transformerDirectives(), transformerVariantGroup()],
theme: {
spacing: { DEFAULT: '4px' },
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 5, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "uno.config.ts" -o -name "uno.config.js" | head -5

Repository: npmx-dev/npmx.dev

Length of output: 76


🏁 Script executed:

cat uno.config.ts

Repository: npmx-dev/npmx.dev

Length of output: 8459


🌐 Web query:

UnoCSS preset-wind4 spacing configuration theme override

💡 Result:

In preset-wind4, all the “size scale” utilities (including p-*, m-*, and also w-*, h-*, min/max-w/h, etc.) are unified to use theme.spacing. [1]

Override spacing via theme

// uno.config.ts
import { defineConfig, presetWind4 } from 'unocss'

export default defineConfig({
  presets: [presetWind4()],
  theme: {
    spacing: {
      0: '0px',
      1: '0.25rem',
      2: '0.5rem',
      4: '1rem',
      6: '1.5rem',
      8: '2rem',
      18: '4.5rem', // custom step (enables p-18, w-18, h-18, etc.)
    },
  },
})

This is the standard UnoCSS way to change what e.g. p-4 (and w-4, h-4, …) resolve to. [2]

Override the generated CSS variable (optional)

preset-wind4 puts theme variables (including --spacing) in a dedicated theme layer specifically to make overriding easy. [1] You can override it in your own CSS loaded after UnoCSS:

:root { --spacing: 0.2rem; }

Sources: UnoCSS preset-wind4 docs [1], UnoCSS theme spacing tutorial [2].


Note that numeric spacing utilities will still use rem values with this change.

Setting spacing: { DEFAULT: '4px' } affects only non-numeric utilities (e.g. bare p, m). Numeric utilities like p-1, m-2, px-4 will still resolve to the preset-wind4 default scale (where 1 = 0.25rem, 2 = 0.5rem, etc.) since you're not defining those numeric keys.

To convert all spacing utilities to px, the numeric scale must be explicitly defined:

spacing: {
  DEFAULT: '4px',
  0: '0px',
  1: '0.25rem',  // or '4px' if switching to px
  2: '0.5rem',   // or '8px'
  // ... rest of scale
}

This is a valid concern only if the goal is complete conversion; if this is intentionally a first step as noted in the PR, this can be disregarded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nah, you’re wrong. The default value is used to set a custom property called --spacing. The relevant utilities use this custom property as a cascading variable which is multiplied by the step in the scale. For example, a partial sample of the output might look like this:

.pl-2 {
  padding-left: calc(var(--spacing) * 2);
}

.pr-4 {
  padding-right: calc(var(--spacing) * 4);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

@knowler, you're absolutely right—thank you for the correction! I misunderstood how preset-wind4 handles the DEFAULT spacing value. Setting spacing: { DEFAULT: '4px' } creates the --spacing custom property that's then multiplied in the utility classes (e.g., pl-2 becomes calc(4px * 2)), so this change does indeed convert the numeric spacing utilities to pixels as intended. I appreciate the clarification!


✏️ Learnings added
Learnt from: knowler
Repo: npmx-dev/npmx.dev PR: 980
File: uno.config.ts:38-38
Timestamp: 2026-02-05T01:30:40.024Z
Learning: In UnoCSS preset-wind4, setting `spacing: { DEFAULT: '4px' }` in the theme configuration creates a CSS custom property `--spacing: 4px`. Numeric spacing utilities like `pl-2` or `pr-4` generate CSS using `calc(var(--spacing) * N)` where N is the numeric value, so `pl-2` becomes `padding-left: calc(var(--spacing) * 2)`. This means changing the DEFAULT value from rem to px affects all numeric spacing utilities.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@essenmitsosse
Copy link
Contributor

I expected a massive diff but that seems reasonable. I m just a bit worried about two things (but we can still roll back later if they turn out to be true):

  • using rem for spacing has been the defacto standard for some reason. It might not be the best but it might also be that we are trying to be smart about this. I worry this might come back on one way or the other to bite us in the ass

  • not entirely sure if this is a good idea from a design standpoint. Increasing text size while leaving spacing fixed might make things a little tight. Even with low vision people still depend on visual contrast and proper spacing as well, so isn't that making things worse?

    Also to reraise what I said in the Discord thread: do people who want larger font size really want shorter line length? With our current design people with a very large screen would just get larger text while the text width would stay fixed.

Mainly I would just like to avoid adding complexity to solve a problem I still haven't fully understood.

@essenmitsosse
Copy link
Contributor

Also just to be sure: which browser would support this as of now? Regular CMD + + zoom on desktop as well as page zoom on mobile still seems to work as before, right?

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