oddbird/susy

"SassError: $number: ... is not a number" when compiling with webpack and sass-loader

Jones-S opened this issue · 2 comments

Hi there

I am currently trying to update all devDependencies of a project which uses susy grid.
Because of the size it would be a bad idea to remove susy although it would be possible in the meantime as IE11-support was dropped and we could work with css-grids.

I replace node-sass with dart sass but now I get this error:

Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: $number: calc(((100% - 36px) / 4 * 1)) is not a number.

27 │ @if ($length == 0) or ($string) or index($_svg-units, unit($length)) {
│ ^^^^^^^^^^^^^

node_modules/susy/sass/plugins/svg-grid/_svg-utilities.scss 27:57 -susy-svg-validate-units()
node_modules/susy/sass/plugins/svg-grid/_svg-utilities.scss 59:11 -susy-svg-rect()
node_modules/susy/sass/plugins/svg-grid/_svg-api.scss 110:18 susy-svg-grid()
src/styles/_susy-grid.scss 84:21 grid-debug()
src/components/molecules/table/styles/servicestable.scss 147:13 @content
src/styles/_susy-grid.scss 144:9 @content
src/styles/_susy-grid.scss 97:13 @content
src/styles/_susy-grid.scss 77:5 susy-use()
src/styles/_susy-grid.scss 96:9 grid-mobile()
src/styles/_susy-grid.scss 143:5 grid-all()
src/components/molecules/table/styles/servicestable.scss 146:9 @import
src/styles/_molecules.scss 83:9 @import
src/app.scss 162:9 root stylesheet

Following the call stack I find my file _susy-grid.scss line 84 where I have

@mixin grid-debug() {
    @if map-get($gridLayout, debug) {
        background: susy-svg-grid() no-repeat scroll;
    }
}

But I can't really understand where my actual problems lies.

My servicestable.scss at line 147:

...
    &__debug-grid {
        @include grid-all {
            @include grid-debug();
        }
    }
...

and

// just uses the grid-debug mixin in all different grid definitions:
@mixin grid-all() {
    @include grid-mobile {
        @content;
    }

    @include grid-desktop {
        @content;
    }

    @include grid-widescreen {
        @content;
    }
}

and all the different grid setups look like (here just the mobile example). They differ in mediaqueries

$mq-1: 'only screen and (max-width: #{$breakpoint-1 - 1px})';

@mixin grid-mobile() {
    @media #{$mq-1} {
        @include susy-use(map-get($gridLayout, mobile)) {
            @content;
        }
    }
}

If somebody has an idea what the reason for my problem could be, I would be very glad to get any hints.
I am also not sure if the susy implementation is not compatible with the newest dart sass version or not playing well together with sass-loader...

The problem only appeared after upgrading... of course.

Thanks for any help.
Cheers

Is this maybe related to:
https://css-tricks.com/when-sass-and-new-css-features-collide/

I understand that sass has its own calc implementation and it may collide with the css calc feature?
Maybe this was not a problem as long

Oh no, I found something;

within _svg-utilities we have

  @if ($length == 0) or ($string) or index($_svg-units, unit($length)) {
      @return $length;
  }

-> https://github.com/oddbird/susy/blob/master/sass/plugins/svg-grid/_svg-utilities.scss#L27

And the $length in this case is a calculation (which I found by logging: #{type-of($length)}.
The problem is, that sass's unit expects a number:
https://sass-lang.com/documentation/modules/math#unit

I guess the type checking and the type expected for unit is now more rigid and a calculation does not go through anymore.
But nonetheless it would work:

A quick fix is:

  @if ($length == 0) or ($string) or type-of($length) == 'calculation' or index($_svg-units, unit($length)) {
      @return $length;
  }

And I get an svg background which looks like:

  .container--debug {
	background: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" fill="url(%23susy-svg-gradient)" 
	width="100%" %3E%3Cdefs%3E%3ClinearGradient spreadMethod="pad" 
	id="susy-svg-gradient" x1="0%" y1="0%" x2="100%" y2="0%"%3E%3Cstop offset="0%" 
	style="stop-color:hsla(120deg, 50%, 50%, 0.5);" /%3E%3Cstop offset="100%" 
	style="stop-color:hsla(120deg, 50%, 75%, 0.5);" /%3E%3C/linearGradient%3E%3C/defs%3E%3Crect x="0" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(12px + ((100% - 132px) / 12 * 1))"
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(24px + ((100% - 132px) / 12 * 2))"
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(36px + ((100% - 132px) / 12 * 3))"
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(48px + ((100% - 132px) / 12 * 4))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(60px + ((100% - 132px) / 12 * 5))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(72px + ((100% - 132px) / 12 * 6))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(84px + ((100% - 132px) / 12 * 7))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(96px + ((100% - 132px) / 12 * 8))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(108px + ((100% - 132px) / 12 * 9))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(120px + ((100% - 132px) / 12 * 10))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3Crect x="calc(132px + ((100% - 132px) / 12 * 11))" 
	width="calc(((100% - 132px) / 12 * 1))" height="100%"/%3E%3C/svg%3E') no-repeat scroll;
}

Do you have any idea how to overcome this problem?
Thanks a lot in advance.
Cheers