node-sass icon indicating copy to clipboard operation
node-sass copied to clipboard

The "not" pseudo-selector (:not()) missing from compiled code

Open dennisbaskin opened this issue 7 years ago • 21 comments

Hello,

I am experiencing a very strange problem that I could not pinpoint wether it's libsass or node-sass. But one thing I know for a fact is the different versions of node-sass where the bug (maybe feature?) was introduced. The difference was between versions 4.7.2 and 4.8.1.

I checked sassmeister and everything compiles correctly there. But when compiling via node I am seeing the following:

Example with v4.8.1

package.js:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "node-sass": "4.8.1"
  }
}

index.js:

const fs = require('fs')
const sass = require('node-sass')

sass.render({
  file: 'test.scss',
}, (error, result) => {
  if(error) return console.log(error)
  fs.writeFile('test-out.css', result.css, (err) => {
    if(!err) console.log(err)
  })
})

test.scss

.btn,
.button {
  &.disabled:not(&-default):not(&-outline),
  &:disabled:not(&-default):not(&-outline) {
    background: #fefefe !important;
    color: #111111 !important;
  }
}

And the following is the output I am getting:

.btn.disabled, .btn:disabled,
.button.disabled,
.button:disabled {
  background: #fefefe !important;
  color: #111111 !important; }

The above is also reproducible with latest master.

When I switch versions to 4.7.2 and below I get the expected output:

Example with v4.7.2

package.json:

  ...
  "devDependencies": {
    "node-sass": "4.7.2"
  }
  ...

output:

.btn.disabled:not(.btn-default,
.button-default, .btn-default,
.button-default):not(.btn-outline,
.button-outline, .btn-outline,
.button-outline), .btn:disabled:not(.btn-default,
.button-default, .btn-default,
.button-default):not(.btn-outline,
.button-outline, .btn-outline,
.button-outline),
.button.disabled:not(.btn-default,
.button-default, .btn-default,
.button-default):not(.btn-outline,
.button-outline, .btn-outline,
.button-outline),
.button:disabled:not(.btn-default,
.button-default, .btn-default,
.button-default):not(.btn-outline,
.button-outline, .btn-outline,
.button-outline) {
  background: #fefefe !important;
  color: #111111 !important; }

Check that the version of node-sass you're trying to install supports your version of Node by looking at the release page for that version https://github.com/sass/node-sass/releases

Verified above issue on MacOSX and Debian

Read the common workarounds in the TROUBLESHOOTING.md

The only thing I could gather that might help diagnose where this is occurring is the following:

# with version 4.7.2
$ node -p "require('node-sass').info"
node-sass	4.7.2	(Wrapper)	[JavaScript]
libsass  	3.5.0.beta.2	(Sass Compiler)	[C/C++]

# with version 4.8.1
$ node -p "require('node-sass').info"
node-sass	4.8.1	(Wrapper)	[JavaScript]
libsass  	3.5.0	(Sass Compiler)	[C/C++]

So my guess is that this could be libsass?

Search for duplicate or closed issues

I might just be horrible at searching GIT issues, but I was unable to find a matching problem.

Validate that it runs with both Ruby Sass and LibSass

Sassmeister works as expected

Prepare a reduced test case for any bugs

Please see above examples

Read the contributing guidelines

I have recreated and pinpointed the issue to specific versions and verified that it still exists in master.

When encountering a syntax, or compilation issue:

Open an issue on LibSass. You may link it back here, but any change will be required there, not here

I have a feeling this is a libsass issue, but my examples are using node-sass. If nothing else I hope I can keep this issue for reference and open an issue with libsass if requested to do so.

  • NPM version (npm -v): 5.6.0
  • Node version (node -v): v8.10.0
  • Node Process (node -p process.versions):
{ http_parser: '2.7.0',
  node: '8.10.0',
  v8: '6.2.414.50',
  uv: '1.19.1',
  zlib: '1.2.11',
  ares: '1.10.1-DEV',
  modules: '57',
  nghttp2: '1.25.0',
  openssl: '1.0.2n',
  icu: '60.1',
  unicode: '10.0',
  cldr: '32.0',
  tz: '2017c' }
  • Node Platform (node -p process.platform): darwin
  • Node architecture (node -p process.arch): x64
  • node-sass version (node -p "require('node-sass').info"):
node-sass	4.8.1	(Wrapper)	[JavaScript]
libsass  	3.5.0	(Sass Compiler)	[C/C++]

(working version info mentione at top)

  • npm node-sass versions (npm ls node-sass):
[email protected] /test
└── [email protected] 

dennisbaskin avatar Apr 12 '18 22:04 dennisbaskin

Can you try with 4.8.3, there was a libsass bump to fix some issues

nschonni avatar Apr 12 '18 23:04 nschonni

I just tried on CodePen (which is supposed to be running 4.8.3) and got

.btn.disabled:not(.btn-default):not(
.button-default):not(.btn-outline):not(
.button-outline), .btn:disabled:not(.btn-default):not(
.button-default):not(.btn-outline):not(
.button-outline),
.button.disabled:not(.btn-default):not(
.button-default):not(.btn-outline):not(
.button-outline),
.button:disabled:not(.btn-default):not(
.button-default):not(.btn-outline):not(
.button-outline) {
  background: #fefefe !important;
  color: #111111 !important;
}

nschonni avatar Apr 12 '18 23:04 nschonni

Hi Nick,

Thanks for the quick reply. I just tried it with 4.8.3 as well with same results as in 4.8.1

I wonder if libsass changed something, or I am doing something completely wrong (Maybe I should stop writing my sass this way?).

To give you a bit more background, I found the issue through gulp-sass, but was able to recreate it through node-sass. I really don't think this helps any, but thought I'd mention it.

dennisbaskin avatar Apr 13 '18 00:04 dennisbaskin

Could you please compare against dart-sass? Sassmeister is very out of date.

npx dart-sass index.scss

Note: if you have npm >= 5 you'll have npx installed already

xzyfer avatar Apr 13 '18 00:04 xzyfer

$ npx dart-sass test.scss
npx: installed 1 in 1.124s
.btn.disabled:not(.btn-default,
.button-default):not(.btn-outline,
.button-outline), .btn:disabled:not(.btn-default,
.button-default):not(.btn-outline,
.button-outline),
.button.disabled:not(.btn-default,
.button-default):not(.btn-outline,
.button-outline),
.button:disabled:not(.btn-default,
.button-default):not(.btn-outline,
.button-outline) {
  background: #fefefe !important;
  color: #111111 !important;
}

Seems to be the correct output

I also put up a test repo here just in case: https://github.com/dennisbaskin/node-sass-no-not-example

dennisbaskin avatar Apr 13 '18 00:04 dennisbaskin

Thanks for the report, this is certainly a regression in LibSass. I'll create an upstream issue.

It appears, although noisier, the output us semantically identical so this should break any CSS.

image

xzyfer avatar Apr 13 '18 01:04 xzyfer

Thanks @xzyfer 😸

I didn't quite understand what you meant by the last sentence though. Were you comparing dart-sass to expected output, or the broken libsass?

Thanks again for the quick response!

dennisbaskin avatar Apr 13 '18 02:04 dennisbaskin

I just wanted to compare the output to an up to date version of Sass to cross check. Dart Sass is easier to install than Ruby Sass.

In this case. The LibSass output is wrong, but not broken. It does the right in so far as

.btn.disabled
:not(.btn-default, .button-default)

is the same as the following as far as the browser is concerned

.btn.disabled
:not(.btn-default, .button-default, .btn-default, .button-default)

The second one just has some duplication. So yes it's a bug, but it shouldn't not break anything as far as the browser is concerned.

xzyfer avatar Apr 13 '18 04:04 xzyfer

I see. @xzyfer the bug I am reporting does break the output though, and not just how the code is styled.

It comes out to be:

.btn.disabled, .btn:disabled,
.button.disabled,
.button:disabled {
  background: #fefefe !important;
  color: #111111 !important; }

As you can see it drops the :not()

I added an example here: https://github.com/dennisbaskin/node-sass-no-not-example

dennisbaskin avatar Apr 13 '18 04:04 dennisbaskin

Sorry I was looking at the 4.7.2 output. I can see the issue now.

xzyfer avatar Apr 13 '18 05:04 xzyfer

Created an upstream issue in https://github.com/sass/libsass/issues/2630

xzyfer avatar Apr 13 '18 05:04 xzyfer

Thank you :)

dennisbaskin avatar Apr 13 '18 05:04 dennisbaskin

Also noticed the output above for :not uses the selector list argument feature of :not which is introduced in css4, but not well supported yet. Maybe some folks running into this issue while using :not?

https://caniuse.com/#feat=css-not-sel-list image

admosity avatar May 30 '18 17:05 admosity

I believe this can be closed out, the upstream issue at https://github.com/sass/libsass/issues/2630 has been resolved. I had the problem in the past and can no longer reproduce. (I had been using 4.7.2 previously to avoid this issue and have upgraded to 4.12.0.)

EDIT I confirmed what the comments below say, I was wrong: this issue is NOT fixed in 4.12.0.

seankwilliams avatar Jun 12 '19 17:06 seankwilliams

I'm using node-sass 4.12.0 and the issue is still reproduced

ossinkine avatar Jun 18 '19 10:06 ossinkine

As I undersand node-sass 4.12.0 uses libsass 3.5.4 but the issue is fixed in 3.6.0

ossinkine avatar Jun 18 '19 10:06 ossinkine

Is definitely still an issue with 4.12.0. Encountered this trying to migrate from node 8 to 10, and node-sass from 4.5.2 to 4.12.0. Unfortunately the lowest version to support node 10 still has this issue, so we are unable to update until this gets fixed.

whscullin avatar Jul 15 '19 19:07 whscullin

Good news! If I don't miss anything, this selector is supported by all latest major browsers (https://developer.mozilla.org/en-US/docs/Web/CSS/:not) and therefore is ready to be implemented.

dearlordylord avatar Aug 30 '20 07:08 dearlordylord

This is fixed in libsass 3.6+. Do we have any news on an update with that version included?

calvinjuarez avatar Sep 15 '20 22:09 calvinjuarez

follow https://github.com/sass/node-sass/issues/2685 for updates on libsass 3.6

commonpike avatar Oct 16 '20 12:10 commonpike

#2685 is locked for 3 years, is there a chance to get this fixed?

andreyvolokitin avatar Oct 03 '22 22:10 andreyvolokitin