not supported Feature is not supported supported Feature is supported twitter Twitter icon github GitHub icon mixed support Feature is partially supported

Sass Compatibility

Reporting incompatibilities between different Sass engines.

Tweet it Contribute

& SassScript

§

Description

The ability to use &, the reference to the current selector, in SassScript. This basically means that & can be manipulated, inspected and updated manually.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "`&` SassScript" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
tests/ampersand_sassscript
Support

Angle conversion

§

Description

Angles can be emitted in four different units:

  • Degrees: deg
  • Radians: rad
  • Gradians: grad
  • Turns: turn

Sass should be able to auto-convert angles from one unit to another.

Work-around

@function convert-angle($value, $unit) {
  $convertable-units: deg grad turn rad;
  $conversion-factors: 1 10grad/9deg 1turn/360deg 3.1415926rad/180deg;
  @if index($convertable-units, unit($value)) and index($convertable-units, $unit) {
    @return $value
             / nth($conversion-factors, index($convertable-units, unit($value)))
             * nth($conversion-factors, index($convertable-units, $unit));
  }
  @error "Cannot convert `#{unit($value)}` to `#{$unit}`.";
}

Tests and support

Feature "Angle conversion" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_666/angle
Support

@at-root directive

§

Description

The @at-root directive causes one or more rules to be emitted at the root of the document, rather than being nested beneath their parent selectors.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "`@at-root` directive" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass/at-root/ampersand
spec/libsass/at-root/basic
spec/libsass/at-root/extend
spec/libsass/at-root/keyframes
spec/libsass/at-root/media
spec/libsass/at-root/nested
spec/libsass/at-root/with_without
spec/libsass/at-root/135_test_simple_at_root
spec/libsass/at-root/136_test_at_root_with_selector
spec/libsass/at-root/137_test_at_root_in_mixin
spec/libsass/at-root/138_test_at_root_in_media
spec/libsass/at-root/139_test_at_root_in_bubbled_media
spec/libsass/at-root/140_test_at_root_in_unknown_directive
spec/libsass/at-root/141_test_at_root_with_parent_ref
spec/libsass/at-root/142_test_multi_level_at_root_with_parent_ref
spec/libsass/at-root/143_test_multi_level_at_root_with_inner_parent_ref
Support

call function

§

Description

The call function makes it possible to call a function dynamically, by referencing its name.

Work-around

Unfortunately, the call function is not easily polyfilled. You would have to create a function with a switch case for every existing function in the global scope; Sass default functions such as quote or invert, and your own functions as well. That’s a pain and kind of defeats the initial purpose.

Tests and support

Feature "`call` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/basic/60_call
Support

Forbid cross-media @extend

§

Description

As of today, the @extend directive cannot be used across different media contexts.

Work-around

Use a mixin instead.

Tests and support

Feature "Forbid cross-media `@extend`" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
tests/cross_media_extend
Support

Deep @extend

§

Description

Deep extend names the situation where the @extend directive is being used from a compound selector, for instance .a .b .c.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "Deep `@extend`" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_592
Support

Downward @for

§

Description

For long, there was no way to have decrementing @for loops. They could only go upward. No error was thrown, but it simply did not iterate.

Work-around

@for $i from -10 through -1 {
  $i: abs($i);
  // Do something
}

Tests and support

Feature "Downward `@for`" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_703
Support

@error directive

§

Description

The @error directive throws the value of a SassScript expression as a fatal error, including a nice stack trace. It’s useful for validating arguments to mixins and functions.

Work-around

@if ($condition) {
  @warn $error;
  @return null;
}

Tests and support

Feature "`@error` directive" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
tests/error_directive
Support

Feature detection functions

§

Description

Feature detection functions include feature-exists, variable-exists, global-variable-exists, function-exists and mixin-exists.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "Feature detection functions" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_702
spec/basic/55_variable_exists
spec/basic/56_global_variable_exists
spec/basic/57_function_exists
spec/basic/58_mixin_exists
Support

Fixed if function

§

Description

The if function returns one of two values, depending on whether or not $condition is true. Just like in @if, all values other than false and null are considered to be true.

There has long been a bug with this function where all arguments where evaluated, no matter the result of the condition.

Work-around

Use a conditional statement (@if / @else).

// Instead of:
// $value: if(length($list) > 2, nth($list, 3), nth($list, 1));

$value: nth($list, 1);

@if length($list) > 2 {
  $value: nth($list, 3);
}

Tests and support

Feature "Fixed `if` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_338
Support

inspect function

§

Description

The inspect function returns a string containing the value as its Sass representation. It is especially useful when printing lists and maps as CSS values.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "`inspect` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_701
Support

list-separator function

§

Description

The list-separator function returns the separator of a list. If the list doesn’t have a separator due to having fewer than two elements, returns space.

Work-around

@function _list-separator($list) {
  @if function-exists("list-separator") == true {
    @return list-separator($list);
  }

  $test-list: ();
  @each $item in $list {
    $test-list: append($test-list, $item, space);
  }

  @return if($test-list == $list, space, comma);
}

Tests and support

Feature "`list-separator` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_506
Support

Map API

§

Description

The Map API includes the map Sass data type and functions map-get, map-merge, map-remove, map-keys, map-values, map-has-key and keywords.

Work-around

Maps can be faked with bi-dimensional lists such as:

$map: (
  a 1,
  b 2,
  c 3
);

Then, Sass List-Maps from Lu Nelson can be used to polyfill the whole Map API.

Tests and support

Feature "Map API" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/maps/map-get
spec/maps/map-has-key
spec/maps/map-keys
spec/maps/map-merge
spec/maps/map-remove
spec/maps/map-values
Support

Media queries merge

§

Description

While nested media queries are valid CSS, they are quite uncommon. Also, some browsers (Internet Explorer and Opera) do not support nested media queries. Because of this, Sass is supposed to merge compatible nested media queries into a single one.

Work-around

Don’t nest media queries and merge them manually.

// Instead of:
// @media (min-width: 600px) {
//   @media (max-width: 800px) { .. }
// }

@media (min-width: 600px) and (max-width: 800px) { .. }

Tests and support

Feature "Media queries merge" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_185/hoisting
spec/libsass-closed-issues/issue_185/media_level_4
spec/libsass-closed-issues/issue_185/media_wrapper_selector
spec/libsass-closed-issues/issue_185/merge_no_repeat
spec/libsass-closed-issues/issue_185/mixin
spec/libsass-closed-issues/issue_185/selector_wrapper_media
Support

Multi assignment @each

§

Description

It is possible to assign several variables at once in an @each loop, which turns out to be especially useful when iterating over maps. For instance, @each $key, $value in $map. Learn more about multi-assignment.

Work-around

Use a regular loop.

@each $item in $map {
  $key: nth($item, 1);
  $value: nth($item, 2);
  // Do something
}

Tests and support

Feature "Multi assignment `@each`" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_492
Support

Multi keys map-remove

§

Description

Some engines cannot remove multiple keys of a map at once with the map-remove function.

Work-around

@function map-multi-remove($map, $keys...) {
  @each $key in $keys {
    $map: map-remove($map, $key);
  }
  @return $map;
}

Tests and support

Feature "Multi keys `map-remove`" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_510
Support

Negative indexes

§

Description

All list functions support negative indexes in order to start from the last item in the list rather than the first. For instance, nth($list, -1) returns the last item from $list.

Work-around

Substract indexes to the result of length function.

// Instead of:
// $value: nth($list, -3);

$value: nth($list, length($list) - 2);

Tests and support

Feature "Negative indexes" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_224
Support

Nested interpolations

§

Description

Interpolations (#{..}) can be nested.

Work-around

Not only nested interpolations are quite uncommon, but it also turns out to be easy to refactor the code so it doesn’t happen.

Tests and support

Feature "Nested interpolations" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_615
Support

random function

§

Description

The random function returns a decimal between 0 and 1, inclusive. When given an argument, it returns a decimal between 0 and the given number.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "`random` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_657/limit
spec/libsass-closed-issues/issue_657/default
Support

rebeccapurple color

§

Description

The rebeccapurple CSS color can safely be used, yet it cannot be manipulated as a color.

Work-around

Use #663399. You could stuff it in a variable.

$rebeccapurple: #663399;

Tests and support

Feature "`rebeccapurple` color" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_699
Support

Reserved function names

§

Description

Sass is supposed to throw an error if one tries to create and call functions named or, not or and.

Work-around

Name your functions differently.

Tests and support

Feature "Reserved function names" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
tests/reserved_function_names/not
tests/reserved_function_names/and
tests/reserved_function_names/or
Support

Selector manipulation functions

§

Description

Selector manipulation functions include selector-nest, selector-append, selector-extend, selector-replace, selector-unify, is-superselector, simple-selectors and selector-parse.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "Selector manipulation functions" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
tests/selector_manipulation_functions
Support

set-nth function

§

Description

The set-nth function returns a new list, based on the list provided, but with the nth element changed to the value given.

Work-around

@function update-nth($list, $n, $value) {
  @if function-exists("set-nth") == true {
    @return set-nth($list, $n, $value);
  }
  $new-list: ();
  @for $i from 1 through length($list) {
    $new-list: append($new-list, if($i == $n, $value, nth($list, $i)));
  }
  @return $new-list;
}

Tests and support

Feature "`set-nth` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_578
Support

Shadow DOM styling

§

Description

Shadow DOM selectors for Web Components allow a slightly different syntax than usual CSS selectors.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "Shadow DOM styling" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_452
Support

Spaces around minus symbol

§

Description

Spaces around the minus symbol should not be mandatory if the value before the - sign is a function call.

Work-around

Wrap the minus symbol with spaces to prevent any issue and easy readibility.

.foo {
  content: getter() - 1;
}

Tests and support

Feature "Spaces around minus symbol" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_733
Support

String manipulation functions

§

Description

String manipulation functions include str-length, str-insert, str-index, str-slice, to-upper-case and to-lower-case.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "String manipulation functions" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/basic/43_str_length
spec/basic/45_str_insert
spec/basic/46_str_index
spec/basic/48_case_conversion
spec/libsass-todo-tests/47_str_slice
spec/libsass-closed-issues/issue_760
spec/libsass-closed-issues/issue_763
spec/libsass-closed-issues/issue_815
Support

transparent color

§

Description

The transparent CSS color can safely be used, yet it cannot be manipulated as a color.

Work-around

Use rgba(0, 0, 0, 0). You could stuff it in a variable.

$transparent: rgba(0, 0, 0, 0);

Tests and support

Feature "`transparent` color" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_700
Support

unique-id function

§

Description

The unique-id function returns a unique CSS identifier. The identifier is returned as an unquoted string. The identifier returned is only guaranteed to be unique within the scope of a single Sass run.

Work-around

There is no known polyfill or work-around for this.

Tests and support

Feature "`unique-id` function" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_636
Support

Variable scoping

§

Description

Not all engines work with the same variable scoping mechanism. Actually, some don’t have variable scoping at all, which means all variables live in the same global environment (and can overlap). Some engines do have the new variable scoping system, where a variable is restricted to its scope (function, mixin…) if it’s not set with the !global flag.

Work-around

This can be detected with:

feature-exists("global-variable-shadowing") == true

Tests and support

Feature "Variable scoping" support
Test Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
spec/libsass-closed-issues/issue_613
Support

Tests statistics §

Caution! Those stats are computed based on the few tests we run here on Sass-Compatibility. They do not reflect the current status of support for each engine. Please do not communicate those stats to compare different engines, it would be unfair.

Section Ruby Sass 3.2 Ruby Sass 3.3 Ruby Sass 3.4 LibSass 3.1 LibSass 3.2 LibSass 3.3
Passed 8 54 68 33 67 68
Failed 60 14 0 35 1 0
Percentage 11.76% 79.41% 100.0% 48.53% 98.53% 100.0%