Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IS_NON_DIMENSIONAL has false positives and false negatives #2607

Closed
kripod opened this issue Jul 8, 2020 · 4 comments · Fixed by #2608
Closed

IS_NON_DIMENSIONAL has false positives and false negatives #2607

kripod opened this issue Jul 8, 2020 · 4 comments · Fixed by #2608
Labels
discussion known issue The issue is known and may be left as-is.

Comments

@kripod
Copy link

kripod commented Jul 8, 2020

Recently, I wrote some tests for a regular expression with functionality similar to IS_NON_DIMENSIONAL. Out of curiosity, I ran the same tests against Preact's implementation and found the following results:

False positives

When given a number, it should be postfixed with 'px' for the CSS properties below:

  • grid-auto-columns
  • grid-auto-rows
  • grid-template-columns
  • grid-template-rows

The properties above don't accept unitless values. However, IS_NON_DIMENSIONAL matches them, so they're not postfixed with 'px' when given a number.

False negatives

When given a number, it should not be postfixed with 'px' for the CSS properties below:

  • flex-grow
  • flex-shrink
  • font-size-adjust
  • font-weight
  • line-height
  • line-clamp
  • -webkit-line-clamp
  • animation
  • border-image
  • border-image-outset
  • border-image-slice
  • border-image-width
  • shape-image-threshold
  • scale
  • mask-border
  • mask-border-outset
  • mask-border-slice
  • mask-border-width
  • max-lines
  • tab-size
  • columns
  • column-count
  • initial-letter

The properties above accept unitless values. However, IS_NON_DIMENSIONAL doesn't match them, so they're mistakenly postfixed with 'px' when given a number.

Details of the test

✓ regexp matches unitless-valued 'flex' CSS property (1 ms)
✕ regexp matches unitless-valued 'flex-grow' CSS property (2 ms)
✕ regexp matches unitless-valued 'flex-shrink' CSS property
✕ regexp matches unitless-valued 'font-size-adjust' CSS property (1 ms)
✕ regexp matches unitless-valued 'font-weight' CSS property
✓ regexp matches unitless-valued 'grid-area' CSS property
✓ regexp matches unitless-valued 'grid-column' CSS property
✓ regexp matches unitless-valued 'grid-column-end' CSS property (1 ms)
✓ regexp matches unitless-valued 'grid-column-start' CSS property
✓ regexp matches unitless-valued 'grid-row' CSS property
✓ regexp matches unitless-valued 'grid-row-end' CSS property
✓ regexp matches unitless-valued 'grid-row-start' CSS property
✓ regexp matches unitless-valued 'z-index' CSS property
✓ regexp matches unitless-valued 'opacity' CSS property (1 ms)
✓ regexp matches unitless-valued 'order' CSS property
✓ regexp matches unitless-valued 'orphans' CSS property
✕ regexp matches unitless-valued 'line-height' CSS property
✕ regexp matches unitless-valued 'line-clamp' CSS property (1 ms)
✕ regexp matches unitless-valued '-webkit-line-clamp' CSS property
✕ regexp matches unitless-valued 'animation' CSS property
✓ regexp matches unitless-valued 'animation-iteration-count' CSS property
✕ regexp matches unitless-valued 'border-image' CSS property
✕ regexp matches unitless-valued 'border-image-outset' CSS property
✕ regexp matches unitless-valued 'border-image-slice' CSS property (1 ms)
✕ regexp matches unitless-valued 'border-image-width' CSS property
✕ regexp matches unitless-valued 'shape-image-threshold' CSS property
✕ regexp matches unitless-valued 'scale' CSS property (1 ms)
✕ regexp matches unitless-valued 'mask-border' CSS property
✕ regexp matches unitless-valued 'mask-border-outset' CSS property (4 ms)
✕ regexp matches unitless-valued 'mask-border-slice' CSS property
✕ regexp matches unitless-valued 'mask-border-width' CSS property (1 ms)
✕ regexp matches unitless-valued 'max-lines' CSS property
✕ regexp matches unitless-valued 'tab-size' CSS property
✕ regexp matches unitless-valued 'columns' CSS property
✕ regexp matches unitless-valued 'column-count' CSS property (1 ms)
✓ regexp matches unitless-valued 'widows' CSS property
✕ regexp matches unitless-valued 'initial-letter' CSS property
✓ regexp does not match non-unitless-valued 'background' CSS property
✓ regexp does not match non-unitless-valued 'background-position' CSS property
✓ regexp does not match non-unitless-valued 'background-position-x' CSS property
✓ regexp does not match non-unitless-valued 'background-position-y' CSS property
✓ regexp does not match non-unitless-valued 'background-size' CSS property
✓ regexp does not match non-unitless-valued 'block-size' CSS property
✓ regexp does not match non-unitless-valued 'border' CSS property
✓ regexp does not match non-unitless-valued 'border-block' CSS property
✓ regexp does not match non-unitless-valued 'border-block-width' CSS property
✓ regexp does not match non-unitless-valued 'border-block-end' CSS property
✓ regexp does not match non-unitless-valued 'border-block-end-width' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'border-block-start' CSS property
✓ regexp does not match non-unitless-valued 'border-block-start-width' CSS property
✓ regexp does not match non-unitless-valued 'border-bottom' CSS property
✓ regexp does not match non-unitless-valued 'border-bottom-left-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-bottom-right-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-bottom-width' CSS property
✓ regexp does not match non-unitless-valued 'border-end-end-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-end-start-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-inline' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'border-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'border-inline-width' CSS property
✓ regexp does not match non-unitless-valued 'border-inline-end-width' CSS property
✓ regexp does not match non-unitless-valued 'border-inline-start' CSS property
✓ regexp does not match non-unitless-valued 'border-inline-start-width' CSS property
✓ regexp does not match non-unitless-valued 'border-left' CSS property
✓ regexp does not match non-unitless-valued 'border-left-width' CSS property
✓ regexp does not match non-unitless-valued 'border-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-right' CSS property
✓ regexp does not match non-unitless-valued 'border-right-width' CSS property
✓ regexp does not match non-unitless-valued 'border-spacing' CSS property
✓ regexp does not match non-unitless-valued 'border-start-end-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-start-start-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-top' CSS property
✓ regexp does not match non-unitless-valued 'border-top-left-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-top-right-radius' CSS property
✓ regexp does not match non-unitless-valued 'border-top-width' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'border-width' CSS property
✓ regexp does not match non-unitless-valued 'bottom' CSS property
✓ regexp does not match non-unitless-valued 'column-gap' CSS property
✓ regexp does not match non-unitless-valued 'column-rule' CSS property
✓ regexp does not match non-unitless-valued 'column-rule-width' CSS property
✓ regexp does not match non-unitless-valued 'column-width' CSS property
✓ regexp does not match non-unitless-valued 'flex-basis' CSS property
✓ regexp does not match non-unitless-valued 'font-size' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'gap' CSS property
✕ regexp does not match non-unitless-valued 'grid-auto-columns' CSS property
✕ regexp does not match non-unitless-valued 'grid-auto-rows' CSS property
✕ regexp does not match non-unitless-valued 'grid-template-columns' CSS property (1 ms)
✕ regexp does not match non-unitless-valued 'grid-template-rows' CSS property
✓ regexp does not match non-unitless-valued 'height' CSS property
✓ regexp does not match non-unitless-valued 'inline-size' CSS property
✓ regexp does not match non-unitless-valued 'inset' CSS property
✓ regexp does not match non-unitless-valued 'inset-block' CSS property
✓ regexp does not match non-unitless-valued 'inset-block-end' CSS property
✓ regexp does not match non-unitless-valued 'inset-block-start' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'inset-inline' CSS property
✓ regexp does not match non-unitless-valued 'inset-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'inset-inline-start' CSS property
✓ regexp does not match non-unitless-valued 'left' CSS property
✓ regexp does not match non-unitless-valued 'letter-spacing' CSS property
✓ regexp does not match non-unitless-valued 'line-height-step' CSS property
✓ regexp does not match non-unitless-valued 'margin' CSS property
✓ regexp does not match non-unitless-valued 'margin-block' CSS property
✓ regexp does not match non-unitless-valued 'margin-block-end' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'margin-block-start' CSS property
✓ regexp does not match non-unitless-valued 'margin-bottom' CSS property
✓ regexp does not match non-unitless-valued 'margin-inline' CSS property
✓ regexp does not match non-unitless-valued 'margin-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'margin-inline-start' CSS property
✓ regexp does not match non-unitless-valued 'margin-left' CSS property
✓ regexp does not match non-unitless-valued 'margin-right' CSS property
✓ regexp does not match non-unitless-valued 'margin-top' CSS property
✓ regexp does not match non-unitless-valued 'mask' CSS property
✓ regexp does not match non-unitless-valued 'mask-position' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'mask-size' CSS property
✓ regexp does not match non-unitless-valued 'max-block-size' CSS property
✓ regexp does not match non-unitless-valued 'max-height' CSS property
✓ regexp does not match non-unitless-valued 'max-inline-size' CSS property
✓ regexp does not match non-unitless-valued 'max-width' CSS property
✓ regexp does not match non-unitless-valued 'min-block-size' CSS property
✓ regexp does not match non-unitless-valued 'min-height' CSS property
✓ regexp does not match non-unitless-valued 'min-inline-size' CSS property
✓ regexp does not match non-unitless-valued 'min-width' CSS property
✓ regexp does not match non-unitless-valued 'object-position' CSS property
✓ regexp does not match non-unitless-valued 'offset' CSS property
✓ regexp does not match non-unitless-valued 'offset-anchor' CSS property
✓ regexp does not match non-unitless-valued 'offset-distance' CSS property
✓ regexp does not match non-unitless-valued 'offset-position' CSS property
✓ regexp does not match non-unitless-valued 'outline' CSS property
✓ regexp does not match non-unitless-valued 'outline-offset' CSS property
✓ regexp does not match non-unitless-valued 'outline-width' CSS property
✓ regexp does not match non-unitless-valued 'padding' CSS property
✓ regexp does not match non-unitless-valued 'padding-block' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'padding-block-end' CSS property
✓ regexp does not match non-unitless-valued 'padding-block-start' CSS property
✓ regexp does not match non-unitless-valued 'padding-bottom' CSS property
✓ regexp does not match non-unitless-valued 'padding-inline' CSS property
✓ regexp does not match non-unitless-valued 'padding-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'padding-inline-start' CSS property
✓ regexp does not match non-unitless-valued 'padding-left' CSS property
✓ regexp does not match non-unitless-valued 'padding-right' CSS property
✓ regexp does not match non-unitless-valued 'padding-top' CSS property
✓ regexp does not match non-unitless-valued 'perspective' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'perspective-origin' CSS property
✓ regexp does not match non-unitless-valued 'right' CSS property
✓ regexp does not match non-unitless-valued 'row-gap' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-block' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-block-start' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-block-end' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-bottom' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-inline' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-inline-start' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'scroll-margin-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-left' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-right' CSS property
✓ regexp does not match non-unitless-valued 'scroll-margin-top' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-block' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-block-start' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-block-end' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-bottom' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-inline' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-inline-start' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-inline-end' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-left' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-right' CSS property
✓ regexp does not match non-unitless-valued 'scroll-padding-top' CSS property
✓ regexp does not match non-unitless-valued 'shape-margin' CSS property
✓ regexp does not match non-unitless-valued 'text-decoration' CSS property
✓ regexp does not match non-unitless-valued 'text-decoration-thickness' CSS property
✓ regexp does not match non-unitless-valued 'text-indent' CSS property
✓ regexp does not match non-unitless-valued 'text-underline-offset' CSS property
✓ regexp does not match non-unitless-valued 'top' CSS property (1 ms)
✓ regexp does not match non-unitless-valued 'transform-origin' CSS property
✓ regexp does not match non-unitless-valued 'translate' CSS property
✓ regexp does not match non-unitless-valued 'vertical-align' CSS property
✓ regexp does not match non-unitless-valued 'width' CSS property
✓ regexp does not match non-unitless-valued 'word-spacing' CSS property

A potential fix

The implementation of otion passes all the tests, while also checking strings in a more performant manner (matching only from the start instead of at any position):

// otion's variant (modified to work with non-hyphenated object syntax)
/^(-|f[lo].*[^se]$|g.{5,}[^ps]$|z|o[pr]|(W.{5})?[lL]i.*(t|mp)$|an|(bo|s).{4}Im|sca|m.{6}[ds]|ta|c.*[st]$|wido|ini)/

// Preact's variant
/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i

Unlike Preact's 67-byte solution, however, it weighs in at 115 bytes, adding 48 bytes to the bundle size.

@marvinhagemeister
Copy link
Member

Closing, we merged this in the v11 release line 🎉

@fabiospampinato
Copy link

Was the change reverted at some point?

export const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;

@rschristian
Copy link
Member

@fabiospampinato Merged into v11, the master branch is X / v10.

@fabiospampinato
Copy link

Oh I see, thanks for the clarification 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion known issue The issue is known and may be left as-is.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants