2023-03-01 20:46:05 +01:00
|
|
|
---
|
2023-03-09 17:19:39 +01:00
|
|
|
title: "Feature Watch: CSS Imports and CSS Compatibility"
|
2023-03-01 20:46:05 +01:00
|
|
|
author: Natalie Weizenbaum
|
2023-03-03 16:39:31 +01:00
|
|
|
date: 2018-08-13 14:17:00 -8
|
2023-03-01 20:46:05 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
Dart Sass 1.11 has just been released, and with it a handful of new features.
|
|
|
|
This is an exciting moment, because it marks the first major new feature that's
|
|
|
|
been added to the language since Dart Sass was launched. It's also the first
|
|
|
|
release with features that have gone through the new process, from
|
|
|
|
[proposal](https://github.com/sass/language/blob/main/accepted/css-imports.md)
|
|
|
|
to [tests](https://github.com/sass/sass-spec/pull/1277) to
|
|
|
|
[implementation](https://github.com/sass/dart-sass/pull/436).
|
|
|
|
|
|
|
|
### CSS Imports
|
|
|
|
|
|
|
|
The biggest feature in Dart Sass 1.11 is support for importing plain CSS files.
|
|
|
|
This is a long-awaited feature, and while we'd initially planned on waiting on
|
|
|
|
it until we launched the upcoming module system, we ended up deciding to
|
|
|
|
[implement it earlier](/blog/request-for-commentsimporting-css-files).
|
|
|
|
|
|
|
|
You can now import a CSS file, say `styles.css`, just by writing `@import
|
|
|
|
"styles"`. That file will be parsed as plain CSS, which means that any Sass
|
|
|
|
features like variables or mixins or interpolation will be disallowed. The CSS
|
|
|
|
it defines will become part of your stylesheet, and can be `@extend`ed just like
|
|
|
|
any other styles.
|
|
|
|
|
|
|
|
There are a couple caveats: because SCSS is a superset of plain CSS, it will
|
|
|
|
still compile `@import "styles.css"` (with an explicit extension) to a CSS
|
|
|
|
`@import` rule. If you want to import a CSS file into your Sass compilation, you
|
|
|
|
must omit the extension.
|
|
|
|
|
|
|
|
Also, this feature isn't fully [implemented in
|
|
|
|
LibSass](https://github.com/sass/libsass/issues/2699) yet. It still has its old
|
|
|
|
behavior, where it imports CSS files but parses them as SCSS, with all the extra
|
|
|
|
Sass features allowed. This behavior will be deprecated soon, and eventually it
|
|
|
|
will produce errors for anything other than plain CSS, just like Dart Sass does
|
|
|
|
today.
|
|
|
|
|
|
|
|
### CSS `min()` and `max()`
|
|
|
|
|
|
|
|
Dart Sass 1.11 also adds support for CSS's `min()` and `max()` mathematical
|
|
|
|
functions. For those unfamiliar, these functions work a lot like `calc()`,
|
|
|
|
except they return the minimum or maximum of a series of values. For example,
|
|
|
|
you can write `width: max(50%, 100px)` to make your element either 50% of the
|
|
|
|
parent's width or 100px wide, whichever is greater.
|
|
|
|
|
|
|
|
Because Sass has its own functions named `min()` and `max()`, it was difficult
|
|
|
|
to use these CSS functions... until now. Dart Sass 1.11 will intelligently
|
|
|
|
decide whether to use the plain CSS functions or the built-in Sass functions
|
|
|
|
based on whether or not you're passing in dynamic Sass values. For example:
|
|
|
|
|
2023-03-09 17:19:39 +01:00
|
|
|
* The Sass function will be called if you pass a variable, like `max($width,
|
|
|
|
100px)`.
|
|
|
|
* The Sass function will be called if you call another Sass function, like
|
2023-03-01 20:46:05 +01:00
|
|
|
`max(compute-width(), 100px)`.
|
2023-03-09 17:19:39 +01:00
|
|
|
* It will compile to a plain CSS function if you just use plain CSS numbers,
|
2023-03-01 20:46:05 +01:00
|
|
|
like `max(50% + 10px, 100px)`.
|
2023-03-09 17:19:39 +01:00
|
|
|
* It will still compile to a plain CSS function even if you use interpolation,
|
2023-03-01 20:46:05 +01:00
|
|
|
like `max(50% + #{$width / 2}, #{$width})`.
|
|
|
|
|
|
|
|
This preserves backwards-compatibility with existing uses of the Sass functions,
|
|
|
|
while also users to use the CSS functions the same way they would in plain CSS.
|
|
|
|
|
|
|
|
This feature isn't yet implemented in
|
|
|
|
[LibSass](https://github.com/sass/libsass/issues/2701) or [Ruby
|
|
|
|
Sass](https://github.com/sass/ruby-sass/issues/77).
|
|
|
|
|
|
|
|
### Range-Format Media Queries
|
|
|
|
|
|
|
|
CSS Media Queries Level 4 defines a [range
|
|
|
|
syntax](https://www.w3.org/TR/mediaqueries-4/#mq-range-context) for defining
|
|
|
|
certain media queries:
|
|
|
|
|
|
|
|
```css
|
|
|
|
@media (width > 500px) {
|
|
|
|
/* ... */
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Dart Sass 1.11 adds support for this syntax. It works just like existing media
|
|
|
|
query support: you can either use interpolation or plain Sass expressions to
|
|
|
|
inject Sass logic into the query, and they can still be nested.
|
|
|
|
|
|
|
|
```scss
|
|
|
|
@media (width > $width) {
|
|
|
|
@media (height < #{$height}) {
|
|
|
|
/* ... */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
This feature isn't yet implemented in
|
|
|
|
[LibSass](https://github.com/sass/libsass/issues/2698) or [Ruby
|
|
|
|
Sass](https://github.com/sass/ruby-sass/issues/75).
|
|
|
|
|
|
|
|
### Normalized Identifier Escapes
|
|
|
|
|
|
|
|
The last compatibility improvement is a bit of an edge case, but it's still
|
|
|
|
worth mentioning: the way Sass parses escapes in identifiers has been improved
|
|
|
|
to better match the CSS spec.
|
|
|
|
|
|
|
|
Escapes are now normalized to a standard format, which means that (for example)
|
|
|
|
`éclair` and `\E9clair` are parsed to the same value (in this case, `éclair`).
|
|
|
|
Prior to this change, if an escape was written, it would always be preserved
|
|
|
|
as-is, so `str-length(\E9clair)` would return `8` even though that identifier
|
|
|
|
means exactly the same thing to CSS as `éclair`.
|
|
|
|
|
|
|
|
We don't anticipate this affecting many users, but we always strive to bring
|
|
|
|
Sass as close to the semantics of CSS as possible. This is a small but important
|
|
|
|
step on that path.
|
|
|
|
|
|
|
|
This feature isn't yet implemented in
|
|
|
|
[LibSass](https://github.com/sass/libsass/issues/2700) or [Ruby
|
|
|
|
Sass](https://github.com/sass/ruby-sass/issues/76).
|