Conversation
|
So as I told you yesterday, I'm slightly concerned about using a "release candidate" in PROD. I've learnt the hard way in the past around things like this. Especially as we don't check the contents of the compiled source from our preprocessors. On the other hand, I do like the idea of live reload in Chrome and making our workflow faster. Therefore if we were to use this, I would make sure we do a full regression on this branch to catch any incosistencies. One things that stood out to me from the release notes was:
I believe we are still doing this in a few places, but we have been silencing the warnings in the past. |
|
Thanks for the feedback, these are completely legitimate concerns. In this pull request I've made the problematic extends optional (using the I ran a diff between the CSS in master and this branch, and found no differences (so, no need for a regression test). I hope this dissipates any concerns you had. |
Yes this dissipates my concerns 😉 👍 SHIP IT |
Revert "Merge pull request #1989 from guardian/sass33"
Sass 3.3 is a major upgrade of Sass, and it brings support for Sourcemaps. The RC1 was just released and it's ready to use.
Source maps won't work for now for two reasons:
/*# sourceMappingURL=football.min.css.map */(the file has no hash)@phamann's work (in an unreleased branch) will address those issues, enabling us to have a much faster front-end development process (native live reload in Chrome!)
Sass Changelog
3.3.0
Using
&in SassScriptFor a long time, Sass has supported a special
{file:SASS_REFERENCE.md#parent-selector "parent selector",
&}, which is usedwhen nesting selectors to describe how a nested selector relates to the
selectors above it. Until now, this has only been usable in selectors, but now
it can be used in SassScript as well.
In a SassScript expression,
&refers to the current parent selector. It's acomma-separated list of space-separated lists. For example:
The value of
$selectoris now((".foo.bar" ".baz.bang"), ".bip.qux"). Thecompound selectors are quoted here to indicate that they're strings, but in
reality they would be unquoted.
The SassScript
&may be used in selectors using#{}interpolation. Bytreating it as a SassScript value, you can do different things with it than you
can when treating it as a selector. When
&is used as a selector, it can onlyappear at the beginning of a compound selector, similarly to a type selector
like
aorh1. When used with#{}, it can go anywhere. For example:Produces:
@at-rootWhat's that
@at-rootthing in the previous example? It's a way to tell Sassthat you don't want that selector to be nested. When you use
&as a selector,Sass can tell automatically that you don't want nesting, but when you use it
with
#{}you have to be explicit. After all, you might have put it in avariable, returned it from a function, or turned it into a string and reversed
the characters.
In addition to using
@at-rooton a single selector, you can also use it on awhole block of them. For example:
Also produces:
@at-root (without: ...)and@at-root (with: ...)By default,
@at-rootjust excludes selectors to allow#{&}to worksimilarly to just including
&in a selector. However, it's alsopossible to use
@at-rootto move outside of nested directives suchas
@mediaas well. For example:produces:
You can use
@at-root (without: ...)to move outside of anydirective. You can also do it with multiple directives separated by a
space:
@at-root (without: media supports)moves outside of both@mediaand@supportsqueries.There are two special values you can pass to
@at-root. "rule" refersto normal CSS rules;
@at-root (without: rule)is the same as@at-rootwith no query.@at-root (without: all)means that thestyles should be moved outside of all directives and CSS rules.
If you want to specify which directives or rules to include, rather
than listing which ones should be excluded, you can use
withinsteadof
without. For example,@at-root (with: rule)will move outsideof all directives, but will preserve any CSS rules.
Source Maps
Sass now has the ability to generate standard JSON source maps of a format
that will soon be supported in most major browsers. These source maps tell the
browser how to find the Sass styles that caused each CSS style to be generated.
They're much more fine-grained than the old Sass-specific debug info that was
generated; rather than providing the source location of entire CSS rules at a
time, source maps provide the source location of each individual selector and
property.
Source maps can be generated by passing the
--sourcemapflag to thesassexecutable, by passing the {file:SASS_REFERENCE.md#sourcemap-option
:sourcemapoption} to {Sass::Plugin}, or by using the
{Sass::Engine#render_with_sourcemap} method. By default, Sass assumes that
the source stylesheets will be made available on whatever server you're using,
and that their relative location will be the same as it is on the local
filesystem. If this isn't the case, you'll need to make a custom class that
extends {Sass::Importers::Base} or {Sass::Importers::Filesystem} and overrides
{Sass::Importers::Base#public_url
#public_url}.Thanks to Alexander Pavlov for implementing this.
SassScript Maps
SassScript has a new data type: maps. These are associations from SassScript
values (often strings, but potentially any value) to other SassScript values.
They look like this:
Unlike lists, maps must always be surrounded by parentheses.
()is now anempty map in addition to an empty list.
Maps will allow users to collect values into named groups and access those
groups dynamically. For example, you could use them to manage themes for your
stylesheet:
There are a variety of functions for working with maps:
map-get($map, $key)function} returnsthe value in the map associated with the given key. If no value is found, it
returns
null.map-merge($map1, $map2)function}merges two maps together into a new map. If there are any conflicts, the
second map takes precedence, making this a good way to modify values in a map
as well.
map-keys($map)function} returns allthe keys in a map as a comma-separated list.
map-values($map)function} returnsall the values in a map as a comma-separated list.
map-has-key($map, $key)function}returns whether or not a map contains a pair with the given key.
All the existing list functions also work on maps, treating them as lists of
pairs. For example,
nth((foo: 1, bar: 2), 1)returnsfoo 1. Maps can also beused with
@each, using the new multiple assignment feature (see below):Produces:
Variable Keyword Arguments
Maps can be passed as variable arguments, just like lists. For example, if
$mapis(alpha: -10%, "blue": 30%), you can writescale-color($color, $map...)and it will do the same thing asscale-color($color, $alpha: -10%, $blue: 30%). To pass a variable argument list and map at the same time, just dothe list first, then the map, as in
fn($list..., $map...).You can also access the keywords passed to a function that accepts a variable
argument list using the new {Sass::Script::Functions#keywords
keywords($args)function}. For example:
Lists of Pairs as Maps
The new map functions work on lists of pairs as well, for the time being. This
feature exists to help libraries that previously used lists of pairs to simulate
maps. These libraries can now use map functions internally without introducing
backwards-incompatibility. For example:
Since it's just a migration feature, using lists of pairs in place of maps is
already deprecated. Library authors should encourage their users to use actual
maps instead.
Smaller Improvements
It's no longer bundled with Sass.
{Sass::Script::Functions#str_length
str-length} will return the length of astring; {Sass::Script::Functions#str_insert
str-insert} will insert onestring into another; {Sass::Script::Functions#str_index
str-index} willreturn the index of a substring within another string;
{Sass::Script::Functions#str_slice
str-slice} will slice a substring from astring; {Sass::Script::Functions#to_upper_case
to-upper-case} willtransform a string to upper case characters; and
{Sass::Script::Functions#to_lower_case
to-lower-case} will transform astring to lower case characters.
list-separator} function has beenadded to determine what separator a list uses. Thanks to Sam
Richard.
allows them the same power as Sass-based functions with respect to
reading and setting variables defined elsewhere in the stylesheet.
set-nth($list, $n, $value)function lets you construct a newlist based on
$list, with the nth element changed to the valuespecified.
Wierzbowski.
unique-id()} that willreturn a CSS identifier that is unique within the scope of a single CSS file.
nth().feature-exists($feature-name). There are no detectable features in thisrelease, this is provided so that subsequent releases can begin to
use it. Additionally, plugins can now expose their functionality
through
feature-existsby callingSass.add_feature(feature_name). Featuresexposed by plugins must begin with a dash to distinguish them from
official features.
constructs using these new functions:
variable-exists($name)checks if a variable resolves in thecurrent scope.
global-variable-exists($name)checks if a global variable of thegiven name exists.
function-exists($name)checks if a function exists.mixin-exists($name)checks if a mixin exists.call function. For example,
call(nth, a b c, 2)returnsb.converted using
sass-convert.@eachnow supports "multiple assignment", which makes it easier to iterateover lists of lists. If you write
@each $var1, $var2, $var3 in a b c, d e f, g h i, the elements of the sub-lists will be assigned individually to thevariables.
$var1,$var2, and$var3will bea,bandc; thend,e, andf; and theng,h, andi. For more information, see{file:SASS_REFERENCE.md#each-multi-assign the
@eachreference}.Sass values from within ruby extensions.
if()function now only evaluates the argument corresponding tothe value of the first argument.
1, 2, 3,). This also allows you to use a trailing comma to distinguish alist with a single element from that element itself -- for example,
(1,)is explicitly a list containing the value1.contain more CSS rules or properties are now bubbled up through
their parent rules.
Backwards Incompatibilities -- Must Read!
Sass will now throw an error when
@extendis used to extend a selectoroutside the
@mediacontext of the extending selector. This means thefollowing will be an error:
Sass will now throw an error when an
@extendthat has no effect is used. The!optionalflag may be used to avoid this behavior for a single@extend.Sass will now throw an error when it encounters a single
@importstatementthat tries to import more than one file. For example, if you have
@import "screen"and bothscreen.scssand_screen.scssexist, a warning will beprinted.
greyandtransparentare no longer interpreted as strings; they're nowinterpreted as colors, as per the CSS spec.
The automatic placement of the current working directory onto the Sass
load path is now deprecated as this causes unpredictable build
processes. If you need the current working directory to be available,
set
SASSPATH=.in your shell's environment.Sass::Compiler.on_updating_stylesheethas been removed.Sass::Plugin.options=has been removed.Sass::Script::Number::PRECISIONhas been removed.Many classes in the {Sass::Script} have been rearranged. All the value
classes have been moved into {Sass::Script::Value} (e.g.
{Sass::Script::Value::Color}, {Sass::Script::Value::String}, etc). Their
base class is now {Sass::Script::Value::Base} instead of
Sass::Script::Literal. All the parse tree classes have been moved into{Sass::Script::Tree} (e.g. {Sass::Script::Tree::Node},
{Sass::Script::Tree::Operation}, etc).
The old names will continue to work for the next couple releases, but they
will be removed eventually. Any code using them should upgrade to the new
names.
As part of a migration to cleaner variable semantics, assigning to
global variables in a local context by default is deprecated. If
there's a global variable named
$colorand you write$color: bluewithin a CSS rule, Sass will now print a warning; in thefuture, it will create a new local variable named
$color. You maynow explicitly assign to global variables using the
!globalflag;for example,
$color: blue !globalwill always assign to the global$colorvariable.