Skip to content

fix: expand bare vw sizes to all screen breakpoints#2180

Open
daresTheDevil wants to merge 2 commits intonuxt:mainfrom
daresTheDevil:fix/bare-vw-sizes-1433
Open

fix: expand bare vw sizes to all screen breakpoints#2180
daresTheDevil wants to merge 2 commits intonuxt:mainfrom
daresTheDevil:fix/bare-vw-sizes-1433

Conversation

@daresTheDevil
Copy link
Copy Markdown

@daresTheDevil daresTheDevil commented Mar 21, 2026

Summary

Fixes #1433. sizes="100vw" generated 1w/2w srcset entries instead of proper viewport-scaled widths.

Root cause: parseSizes mapped bare values (no breakpoint prefix) to a "1px" key. For fluid vw values, getSizesVariant then calculated Math.round((100/100) * 1) = 1 pixel width. The fluid calculation depends on screenMaxWidth, and parseInt("1px") = 1.

The fix: Bare fluid values (vw) are now expanded to all configured screen breakpoints, so the vw→px math uses each screen's actual pixel width. Bare fixed pixel values keep the existing 1px sentinel behavior (which was already correct since the pixel calculation doesn't depend on screenMaxWidth).

Input Before After
sizes="100vw" 1w, 2w 640w, 768w, 1024w, 1280w, 1536w
sizes="50vw" 1w, 2w 320w, 384w, 512w, 640w, 768w
sizes="100vw lg:480px" 1w, 2w, 480w, 960w 640w, 768w, 480w, 960w, 1280w, 1536w
sizes="200,500:500,900:900" unchanged unchanged

Credit to @dbismut for identifying the root cause in the parseSizes function.

Test plan

  • New test: bare 100vw generates proper viewport-scaled srcset widths
  • New test: 100vw lg:480px fills remaining screens with 100vw
  • All 34 component tests pass (32 existing + 2 new)
  • All 45 unit tests pass (bundle size snapshot updated: +0.2k from expansion logic)

When `sizes="100vw"` is used without a breakpoint prefix, parseSizes
mapped it to a `1px` key. The fluid width calculation then produced
`Math.round((100/100) * 1) = 1`, generating useless 1w/2w srcset
entries instead of proper viewport-scaled widths.

Bare fluid values (ending in `vw`) are now expanded to all configured
screen breakpoints that aren't explicitly specified, so the vw→px
calculation uses each screen's actual width. Fixed pixel values keep the
original 1px sentinel behavior which was already correct.

Examples of corrected output:
- `sizes="100vw"` → srcset with 640w, 768w, 1024w, 1280w, 1536w
- `sizes="50vw"` → srcset with 320w, 384w, 512w, 640w, 768w
- `sizes="100vw lg:480px"` → 100vw for all screens except lg which gets 480px
- `sizes="200,500:500,900:900"` → unchanged (fixed px, not affected)

Closes nuxt#1433
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 21, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/image@2180

commit: 972d0c6

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 21, 2026

📝 Walkthrough

Walkthrough

A new exported constant SIZES_DEFAULT_KEY = 'default' is introduced and parseSizes stores unprefixed size entries under this key. getSizes now imports that sentinel, detects SIZES_DEFAULT_KEY in parsed sizes, deletes the sentinel, and expands it: if the sentinel value ends with vw it copies that fluid value to any configured breakpoints missing a size; otherwise (fixed pixel) it adds a 1px key using the fixed value so it sorts before breakpoint variants. Two integration tests were added to assert width-descriptor srcset output for bare 100vw inputs, and a bundle-size snapshot updated from 12.6k to 12.8k.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main fix: expanding bare vw sizes to all screen breakpoints, which directly addresses the root cause identified in issue #1433.
Linked Issues check ✅ Passed The PR fully addresses issue #1433 by implementing viewport-scaled width calculation for bare vw values and preserving correct behavior for fixed pixel values and prefixed sizes.
Out of Scope Changes check ✅ Passed All changes are in scope: two files implement the fix (new constant, parsing logic, expansion logic), one test file validates the fix with 2 new tests, and one snapshot is updated for bundle size.
Description check ✅ Passed The pull request description is directly related to the changeset, explaining the root cause, fix, and impact on behavior with concrete before/after examples.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.33333% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 31.85%. Comparing base (5be826f) to head (972d0c6).

Files with missing lines Patch % Lines
src/runtime/image.ts 0.00% 6 Missing and 4 partials ⚠️
src/runtime/utils/index.ts 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2180      +/-   ##
==========================================
- Coverage   32.52%   31.85%   -0.68%     
==========================================
  Files           7        7              
  Lines         372      383      +11     
  Branches      131      136       +5     
==========================================
+ Hits          121      122       +1     
- Misses        194      200       +6     
- Partials       57       61       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

Image size set to 1w if sizes is set to 100vw

2 participants