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

SASS Expected identifier: Does Not accept number and letters in same map key? #2956

Closed
devhoussam opened this issue Nov 19, 2020 · 13 comments
Closed

Comments

@devhoussam
Copy link

How can I use number and letter in same map key?

$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  2xl: 1400px // Expected identifier
) !default;
@dennisfrijlink
Copy link

Same problem here . I try to declare a mixin:

@mixin 2xl {}

But get the error Identifier expected

@devhoussam
Copy link
Author

yeah I googling this problem with different tricks but didn't work I wish the sass support team looking to this problem.

@dennisfrijlink
Copy link

Yeah let's hope. Of course there is a simple solution to rename it (e.g. 'xxl' or 'xl2), but I don't like that name-giving. On some pages I read that Sass/SCSS simply doesn't support mixins that start with an number/integer. But I dont' get it how libraries like TailwindCSS use the variable '2xl':

//example of tailwind configure

screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
    }

As you can see they declare the 2xl different from the others as a string

@devhoussam
Copy link
Author

yeah but it still the same problem even If I declared it as a string
Identifier expected

$breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  '2xl': 1400px
) !default;
@Awjin
Copy link
Contributor

Awjin commented Nov 20, 2020

Although they may look similar, these are two different issues.

@dennisfrijlink A mixin's name needs to be a valid Sass identifier. Since 2xl starts with a number, it is not a valid identifier.

@devhoussam This is supported behavior. What version of Sass are you using? Are you sure that the $breakpoints map declaration is breaking? It could be the case that your code is breaking somewhere else by trying to use $breakpoints incorrectly.

@dennisfrijlink
Copy link

@Awjin First thanks for your anwser. So if declare the breakpoints into an array like:

$breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  '2xl': 1400px
) !default;

I can use a Sass map function to declare a mixin for every breakpoint (even for '2xl')?

@Awjin
Copy link
Contributor

Awjin commented Nov 20, 2020

No, dynamic mixin invocation is not yet supported. See the issue here: #626

@dennisfrijlink
Copy link

Aaah okay. You maybe know an altnernative to use the name '2xl'?

I use the mixins for defining the viewports so for example:

// Large devices
@mixin xl {
    @media (min-width: #{$screen-xl-min}) {
        @content;
    }
}

With the variable: $screen-xl-min: 1280px;

@devhoussam
Copy link
Author

devhoussam commented Nov 20, 2020

Here is A full example :

Sass Version : "sass": "^1.29.0",

@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
  $min: map-get($breakpoints, $name);
  @return if($min != 0, $min, null);
}

@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
	@return if(breakpoint-min($name, $breakpoints) == null, "", "#{$name}");
}

@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name, $breakpoints);
  @if $min {
    @media (min-width: $min) {
      @content;
    }
  } @else {
    @content;
  }
}
$grid-breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  '2xl': 1400px
) !default;

@each $breakpoint in map-keys($grid-breakpoints) {
    @include media-breakpoint-up($breakpoint) {
        $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
        
       // Error: Expected Edentifer Here
        .#{$infix}-color-red {
            color: red;
        }
    }
}
@mirisuzanne
Copy link
Contributor

The problem is that you are using the map keys to generate a class name – and CSS does not allow class names to start with a number. If you put a prefix on the class-name (like .media-#{$infix}-color-red) it will work fine. (with or without the quotes in your map).

@dennisfrijlink
Copy link

Maybe an idea how tailwindCSS uses the classname .2xl (check image below)?

Screenshot 2020-11-23 at 16 21 52

@Awjin
Copy link
Contributor

Awjin commented Nov 23, 2020

@mirisuzanne is correct here. Since Sass is a superset of CSS, class names cannot start with a number.

@Awjin Awjin closed this as completed Nov 23, 2020
@zaydek
Copy link

zaydek commented Nov 25, 2021

@devhoussam I just came across this.

@use "sass:list";
@use "sass:map";
@use "sass:string";

$-number-map: (
  "0": 0,
  "1": 1,
  "2": 2,
  "3": 3,
  "4": 4,
  "5": 5,
  "6": 6,
  "7": 7,
  "8": 8,
  "9": 9,
);

// https://mathiasbynens.be/notes/css-escapes
$-escape-chars: (
  "!",
  "\"",
  "#",
  "$",
  "%",
  "&",
  "'",
  "(",
  ")",
  "*",
  "+",
  ",",
  "-",
  ".",
  "/",
  ":",
  ";",
  "<",
  "=",
  ">",
  "?",
  "@",
  "[",
  "\\",
  "]",
  "^",
  "`",
  "{",
  "|",
  "}",
  "~",
);

@function -escape-impl($str) {
  $output: "";
  @for $str-index from 1 through string.length($str) {
    $ch: string.slice($str, $str-index, $str-index);
    @if $str-index == 1 and map.has-key($-number-map, $ch) {
      $output: $output + "\\3" + $ch + " ";
    } @else if list.index($-escape-chars, $ch) != null {
      $output: $output + "\\" + $ch;
    } @else {
      $output: $output + $ch;
    }
  }
  @return $output;
}

@function escape($value) {
  @return -escape-impl("" + $value);
}

.#{escape(2xl)} {
  foo: bar;
}
// .\32 xl {
//   foo: bar;
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants