3

Looking up Bootstrap 5 code, I faced this following statement on bootstrap/scss/mixins/_forms.scss file:

@mixin form-validation-state-selector($state) {
  @if ($state == "valid" or $state == "invalid") {
    .was-validated #{if(&, "&", "")}:#{$state},
    #{if(&, "&", "")}.is-#{$state} {
      @content;
    }
  } @else {
    #{if(&, "&", "")}.is-#{$state} {
      @content;
    }
  }
}

And could not exactly understand the usage of & variable inside the #{if(&, "&", "")} statements. How is it working?

I know the Ampersand (&) character is used, os SASS, to include the parent selector(s), when writing on an indented hierarchy. But I couldn't guess how it has been using on the mentioned statement inside the @mixin, when out of quotes ". Can someone explaning it?

Thanks in advance!

artu-hnrq
  • 1,343
  • 1
  • 8
  • 30

2 Answers2

2

The reason for this syntax is, that this is some kind of parsing / compatibility issue with dartsass. SASS over the years had a lot of different CLI tools to generate the code and there were somehow different levels of strictness when it comes to errors.

Looks like it is there to prevent an issue. I.e. you should not use & at the root level (there is no root of root - probably a NullPointer or something while compiling) because this will produce the error you see here in the screenshot below:

enter image description here

The reason can be found in the comment above the code you linked: https://github.com/sass/sass/issues/1873#issuecomment-152293725

Once you add the rule, the error is gone:

enter image description here

Parser used: https://www.sassmeister.com/

F. Müller
  • 3,969
  • 8
  • 38
  • 49
1

They are using interpolation for part of the selector with the #{if(&, "&", "")}:#{$state} logic.

The if() function works like if(val, res1, res2) where if val is true then res1 is used, else res2, like a ternary. So if the & was truthy e.g. parent selector exists, then it would churn out .was-validated &:valid, using "&", otherwise it would be .was-validated :valid using the empty string.

Here is a CodePen demo which demonstrates the #{if(&, "&", ""} usage.

Tanner Dolby
  • 4,253
  • 3
  • 10
  • 21
  • 2
    The main purpose is different. It's not about the syntax. OP asked for the reason. It's some kind of guard to prevent an error that you cannot use & on root with dartsass - the creators wrote it on a public statement: https://github.com/sass/sass/issues/1873 – F. Müller Nov 22 '22 at 21:36
  • 1
    Nice find. Yeah, after reading that issue thread its more clear they had a reason for doing this. I will drop my answer to keep things succinct. – Tanner Dolby Nov 22 '22 at 21:40
  • 2
    You don't have to. But I think you answered a different question. Up to you. This might still be relevant for other readers. Maybe rephrase it a bit? – F. Müller Nov 22 '22 at 21:41
  • 1
    Agreed, it may be relevant to keep around. Feel free to suggest an edit if you want! – Tanner Dolby Nov 22 '22 at 21:48
  • 1
    Hey guys, thanks for the explanations! I was more trying to get the `&` usage-as-a-variable, pointed by @TannerDolby. Both answers helped my goal – artu-hnrq Nov 24 '22 at 16:30