Cascading Style Sheets
have a very poor syntax.
Neither variables nor constants, not even arithmetic calculations.
With CSS, you can not define your styles in a structured way like with a programming language.
But redundancy is what developers want to avoid, see the agile
DRY principle, or the
OnceAndOnlyOnce requirement.
For that purpose CSS preprocessors have been invented.
- Sass is such one, spelled "Syntactically Awesome Stylesheets", written in Ruby, having a fast sibling written in C++,
- Less is another one, written in JavaScript.
background-color
of your portal
with just one text modification, instead of engaging a software developer for
a week to carefully rewrite external, internal and inline CSS of all HTML pages :-)
Using Sass, your CSS would always be external,
mixed together (preprocessed) from one or several files by the Sass interpreter.
Given that, you should try to put as much styling logic as possible into
*.scss
files (these are the Sass source files),
and minimize the amount of styling logic in HTML (where the content should be).
For example, there should be no more than one CSS class on an element.
Mixing CSS classes together should happen in SCSS, not in HTML.
The stronger the separation of concerns is, the smaller the software maintenance effort will be.
If you already have an installed Sass, you may want to jump to the feature description.
Installing Sass
Visit the Sass Install Page to get going. It can be installed on WINDOWS, MAC and LINUX operating systems. The following I had to do on my Ubuntu 12.04 LINUX to get Sass/Ruby installed:
sudo apt-get install ruby-full rubygems # install ruby sudo gem install sass # install Sass sass -v # check if it works
Sass 3.4.8 (Selective Steve)
sass --help # read help
Usage: sass [options] [INPUT] [OUTPUT] Description: Converts SCSS or Sass files to CSS. Common Options: -I, --load-path PATH Specify a Sass import path. -r, --require LIB Require a Ruby library before running Sass. --compass Make Compass imports available and load project configuration. -t, --style NAME Output style. Can be nested (default), compact, compressed, or expanded. -?, -h, --help Show this help message. -v, --version Print the Sass version. Watching and Updating: --watch Watch files or directories for changes. The location of the generated CSS can be set using a colon: sass --watch input.sass:output.css sass --watch input-dir:output-dir --poll Check for file changes manually, rather than relying on the OS. Only meaningful for --watch. --update Compile files or directories to CSS. Locations are set like --watch. -f, --force Recompile every Sass file, even if the CSS file is newer. Only meaningful for --update. --stop-on-error If a file fails to compile, exit immediately. Only meaningful for --watch and --update. Input and Output: --scss Use the CSS-superset SCSS syntax. --sourcemap=TYPE How to link generated output to the source files. auto (default): relative paths where possible, file URIs elsewhere file: always absolute file URIs inline: include the source text in the sourcemap none: no sourcemaps -s, --stdin Read input from standard input instead of an input file. This is the default if no input file is specified. -E, --default-encoding ENCODING Does not work in Ruby 1.8. --unix-newlines Use Unix-style newlines in written files. Always true on Unix. -g, --debug-info Emit output that can be used by the FireSass Firebug plugin. -l, --line-numbers Emit comments in the generated CSS indicating the corresponding source line. --line-comments Miscellaneous: -i, --interactive Run an interactive SassScript shell. -c, --check Just check syntax, don't evaluate. --precision NUMBER_OF_DIGITS How many digits of precision to use when outputting decimal numbers. Defaults to 5. --cache-location PATH The path to save parsed Sass files. Defaults to .sass-cache. -C, --no-cache Don't cache parsed Sass files. --trace Show a full Ruby stack trace on error. -q, --quiet Silence warnings and status messages during compilation.
Impressive! What to do with it now?
A quick way to learn things is to read the
user guide
and play around with it at the same time.
But first I need to find out how to translate .scss
files using the
Sass compiler. The web page provides a
reference
where this is described (which also contains a more technical user guide).
So I create my input.scss ...
1 2 3 4 5 6 7 | $fontfamily: sans-serif; $bgcolor: #33CCFF; body { font-family: $fontfamily; background-color: $bgcolor; } |
... run the translation ...
sass input.scss output.css # translate input.scss to output.css
... and get my output.css:
1 2 3 4 5 | body { font-family: sans-serif; background-color: #33CCFF; } /*# sourceMappingURL=output.css.map */ |
You can also tell Sass to watch the .scss file (or whole directory trees) for changes. It then blocks and translates any time a file is saved.
sass --watch input.scss:output.css # translate input.scss to output.css
>>> Sass is watching for changes. Press Ctrl-C to stop. [Listen warning]: Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback. >>> Change detected to: input.scss write output.css write output.css.map
The output.css.map
JSON file and .sass-cache
directory,
created and updated when the compiler runs,
seem to be Sass-internals.
The command to translate all .sccs
files in current directory is:
sass --update .:.
But this works too:
sass --update .
Mind that, by default, for a file input.scss, a file input.css is generated (same name, different extension).
$ ls -l -rwxrwx--- 1 root plugdev 98 Nov 15 17:18 _partial.scss -rwxrwx--- 1 root plugdev 166 Nov 15 17:28 test1.scss $ sass --update . write ./test1.css write ./test1.css.map $ ls -l -rwxrwx--- 1 root plugdev 98 Nov 15 17:18 _partial.scss -rwxrwx--- 1 root plugdev 157 Nov 15 17:42 test1.css -rwxrwx--- 1 root plugdev 232 Nov 15 17:42 test1.css.map -rwxrwx--- 1 root plugdev 166 Nov 15 17:28 test1.scss
Sass Features
The Sass guide is easy to read and understand,
although it is quite short and lacks links to deeper insights.
For example, what happens when I define a variable several times?
Is this a compile error?
Any valid CSS code is valid SCSS code, but not vice versa. SCSS is spelled "Superset of Cascading Style Sheets".
Here is a short outline of Sass features.
Both Types of Comment
One nice thing I mentioned is that both slash-star and slash-slash comments can be used, in contrary to CSS where slash-slash does not work (and could lead to undetected errors).
1 2 3 4 5 6 7 8 9 10 | /* This comment * will appear in the CSS output. */ body { color: black; } // This comment won't appear in the CSS output a { color: green; } |
$Variables
1 2 3 4 5 | $fontfamily: sans-serif; body { font-family: $fontfamily; } |
These are really variables and not constants. They can get a new value at any time.
For instance, when you define a variable,
and then after it import a file that contains another definition
of that variable, the import wins. But when you import it before
the local variable definition, the local definition wins.
A variable is known only within the { context } it is defined.
Variables outside of any context are visible everywhere.
Local variables can be made global by a !global
suffix.
Nestings
Instead of writing CSS path expressions like
1 2 3 4 5 6 7 | ul li { list-style-type: none; } ul li a { color: green; } |
you nest the path parts into each other:
1 2 3 4 5 6 7 8 | ul { li { list-style-type: none; a { color: green; } } } |
@Import
Sass introduces the component-concept of partials. Such is a shared/reused SCSS file that has a leading underscore in its name:
_mypartial.scss
The underscore tells the Sass compiler to not translate this file
because it will be imported.
The import then happens without the underscore:
1 2 3 4 5 6 7 | @import "mypartial"; body { font-family: $fontfamily; background-color: $bgcolor; color: $fgcolor; } |
@Mixin
Another name would have been "Parameterizable Macro". It is mixed-in by an include statement.
1 2 3 4 5 6 7 8 9 10 | @mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; -ms-border-radius: $radius; border-radius: $radius; } .roundedborder { @include border-radius(10px); } |
@Extend
The declarations block of another rule set can be included by addressing it via a single identifier (no complex selectors are possible here):
1 2 3 4 5 6 7 8 9 10 11 12 13 | .message { border: 1px solid #ccc; } .success { @extend .message; border-color: green; } .error { @extend .message; border-color: red; } |
&Parent Selector
This is a shortcut that avoids to repeat the parent selector. This ...
1 2 3 4 5 6 | a { font-weight: bold; &:hover { color: red; } } |
... is compiled to:
1 2 3 4 5 6 7 | a { font-weight: bold; } a:hover { color: red; } |
Arithmetic operations
You can write arithmetic calculations, even using $variables. Possible operators are:
+ - * / %
Thus you can make your layout algorithm a little more transparent.
More
Of course there is more in it:
- you can use variables even in selectors and property names by #{} interpolation syntax
- it has data types and structures like lists and maps
- it's a programming language with conditions and loops (SassScript)
SASS versus SCSS Syntax
The SASS syntax is a different from SCSS syntax in that it leaves out the curly braces. It replaces them by precise indentation, like Python does.
When you go to the Sass guide page you can look at examples in both shapes, look out for the switch on top right corner of any example panel.
The Sass compiler recognizes the syntax by the file's extension. If you really want to leave out the curly braces, name your files .sass. Staying save means setting curly braces and naming the files .scss.
Keine Kommentare:
Kommentar veröffentlichen