Video: Enhance your CSS with preprocessors
Resource: Sass Official Web Site
Final Exercise: View Completed File
IMPORTANT NOTE: You have to define a web site and it has to be the active site in order for the CSS preprocessor to work.
Sass is the most mature, stable, and powerful professional grade CSS extension language in the world. (According to their official web site)
Sass stands for Syntactically Awesome Stylesheet. It is open-source CSS extension called CSS pre-processor and is compatible with all versions of CSS.
Sass is:
Sass is a stylesheet language that gets compiled to fully CSS-compatible CSS which keeps large stylesheets well-organized. Advantages of using Sass pre-processor in Dreamweaver:
If you are using large, complex style sheets, then Sass may be exactly what you need. Like traditional CSS, Sass extend the functionalities of CSS by adding new "programmatic" features:
Like traditional programming languages, there are two types of comments that can be used:
Also, like traditional programming, the preprocessor files have to be converted or compiled into CSS files using a compiler. The good new is that Dreamweaver has built-in compilers so there is no need to download and install them. Simply press CTRL+S to auto-compile the CSS or select Tools > Compile (or press F9) to manually compile individual CSS files.
A browser does not understand Sass, so it has to be converted (transpiling) into standard CSS before it can be used.
NOTE: Transpiling is taking a source code written in one language (*.scss) and using a pre-processor (e.g., Sass, Less, or Stylus) to convert it (or translate it) into another language (standard CSS).
Before we get started, we need to ensure that Sass is setup correctly within Dreamweaver so that when we save the Sass file it will first automatically CREATE a standard CSS file and every time there after when the Sass file is save, it will UPDATE the CSS file.
The easiest concept to understand for most beginners especially if they don't have any programming background is the concept of variables in Sass (or any other preprocessor or program).
ADVANTAGE: Like all programming languages, a variable is used to STORE A REFERENCE of longer code so that it can be used later in the code as a shortcut code that refers to the longer code but with a more meaningful name. For example, instead of having to remember a hexadecimal value for a color, that value could be stored into a variable for easier use and recognition.
Another advantage of using a variable is that if a value needs to be changed that has been declared in multiple places throughout the code, only the variable declaration needs to be updated and all instances in the code will reflect that change when the CSS is re-compiled.
For example, if a web site/app has three main theme colors, instead of defining these colors over and over again throughout the web site or app, you can use Sass variables. So, if you need to change any of the colors, you just change the variable value in ONE PLACE and ALL of the color values that matches that variable will change automatically. This is how themes in most applications work. See upcoming examples in the Sass Variables section.
It is important to note that variable declarations do not get compiled only the CSS instances of the variables. Variables are defined (assigned or declared) at the top of the code so that they can be loaded into memory and used later.
Variables are PLACEHOLERS for STORING different types of DATA so that they can be RE-USED later. Below is a list of data type that Sass supports:
Like many programming languages (e.g., jQuery and JavaScript), Sass variables always start with a dollar sign ($) and end with a variable name (e.g., $primary_color).
However, unlike all programming languages because this is CSS the variable uses the colon (:) like CSS rules instead of an equal sign (=) to ASSIGN a value to the variable (e.g., $primary_color:red instead of $primary_color = red).
Let's look at an example that creates thee variables that will be used.
/* define variables at top of code */NOTE: Sass supports standard comment (e.g., /* comment */) or in-line comment (e.g., //single line comment).
$mainFont: Helvetica, sans-serif;
$mainFontColor: blue;
$mainFontSize: 18px;
/* use variables throughout code */
body {
font-family: $mainFont;
color: $mainFontColor; //Must use this color
font-size: $mainFontSize;
}
/* define variables at top of code */NOTE: When the Sass file was saved, it converted the variables ($mainFont, $maintFontColor, and $mainFontSize) and outputed standard CSS with the variable values in the CSS.
/* use variables throughout code */
body {
font-family: Helvetica, sans-serif;
color: blue;
font-size: 18px; }
<!doctype html>
<html>
<head> <meta charset="utf-8">
<title>Sass Training</title>
<link rel="stylesheet" href="my_custom_styles.css">
</head>
<body>
<h1>Hello, World</h1>
</body>
</html>
By default, Sass variables are only available at the level of nesting where they are defined. Let's see how this works:
/* define variables at top of code */NOTE: Notice the the variable ($mainFontColor) is DEFINED as blue at the top of the code and then AGAIN REDEFINED as red in the p selector.
$mainFont: Helvetica, sans-serif;
$mainFontColor: blue;
$mainFontSize: 18px;
/* use variables throughout code */
p{$mainFontColor:red;
color:$mainFontColor;}
body {
font-family: $mainFont;
color: $mainFontColor; //Must use this color
font-size: $mainFontSize;
}
/* define variables at top of code */
/* use variables throughout code */
p {
color: red; }
body {
font-family: Helvetica, sans-serif;
color: blue;
font-size: 18px; }
The default behavior for variable scope can be overridden by using the !global switch with makes the variable global and accessible on all levels.
TIP: Global variables should be defined OUTSIDE of any rules. It is best practice to define all global variables in its own file, named "_globals.scss", and include the file with the @include keyword.
/* define variables at top of code */
$mainFont: Helvetica, sans-serif;
$mainFontColor: blue;
$mainFontSize: 18px;
/* use variables throughout code */
p{$mainFontColor:red !global;
color:$mainFontColor;}
body {
font-family: $mainFont;
color: $mainFontColor; //Must use this color
font-size: $mainFontSize;
}
/* define variables at top of code */
/* use variables throughout code */
p {
color: red; }
body {
font-family: Helvetica, sans-serif;
color: red;
font-size: 18px; }
Sass allows you to nest CSS selectors that follows the same visual HTML hierarchy. Sass allows you to nest rules and properties.
Sass allows you to nest CSS selectors in the same way as HTML. Let's look at how to create a horizontal menu using Sass nesting.
ADVANTAGE: It makes more sense to group together (nest) elements that are related to reduce that amount of code that you have to write. For example, most web site header will have a header, logo and navigation bar in it so it makes sense to have that as one group of code instead of three.
CAUTION: Avoid nesting more than four levels deep which may makes it harder to read and may affect speed.
<body>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Login</a></li>
</ul>
</nav>
body {NOTE: Notice how the ul , li , and a elements are ALL NESTED inside of the nav element just like it would be in HTML syntax. Note also that the a element is nested inside of the li element which is nested inside of the ul element which is nested inside of the nav element.
font-family: $mainFont;
color: $mainFontColor;
font-size: $mainFontSize;
}
nav {
ul{
li{
a{ }
}
}
}
<nav>
<ul>
<li>
<a></a>
</li>
</ul>
</nav>
nav{
ul{list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color:#333;
li{
a{}
}
}
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
nav{
ul{list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color:#333;
li{float:left;
a{ }
}
}
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
nav li {
float: left; }
nav{
ul{list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color:#333;}
li{float:left;
a{display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial;}
}
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
nav li {
float: left; }
nav li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial; }
nav{
ul{list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color:#333;}
li{float:left;
a{display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial; }
}
li a:hover {background-color: red;}
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
nav li {
float: left; }
nav li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial; }
nav li a:hover {
background-color: green; }
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li class="active"><a href="#">Services</a></li>
<li class="right"><a href="#">Login</a></li>
</ul>
</nav>
nav{
ul{list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color:#333;}
li{float:left;
a{display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial;
}
}
li a:hover {background-color: red;}
.active { background-color: red; font-weight: bold;}
li.right{float:right;}
li {border-right: 1px solid white;}
li:last-child {border-right: none;}
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
nav li {
float: left; }
nav a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial; }
nav li a:hover {
background-color: red; }
nav .active {
background-color: red;
font-weight: bold; }
nav li.right {
float: right; }
nav li {
border-right: 1px solid white; }
nav li:last-child {
border-right: none; }
Several CSS properties have the same prefix, (font.* or text.*). Sass allows you to nest them properties. Let's look at an example:
font: {
family: Helvetica, sans-serif;
size: 18px;
weight: bold;
}
text: {
align: center;
transform: uppercase;
overflow: hidden;
}
font-family: Helvetica, sans-serif;NOTE: This compiled to standard CSS syntax where the the main selector will compile to a tag selector and the others will compile to contextual selectors based off of the first selector:
font-size: 18px;
font-weight: bold;
text-align: center;
text-transform: lowercase;
text-overflow: hidden;
ADVANTAGE: Like traditional programming where variables hold a SINGLE value, arrays can hold multiple values in a single variable (container). Using mixins allow for multiple CSS declarations to be used.
The @mixin directive is used to create CSS code can be reused throughout the website.
The @include directive is used to "(include" the mixin.
<p class="highlight">This is a test</p>
@mixin highlighted-text {
color: black;
font-weight: bold;
border: 1px solid blue;}
.highlight {
@include highlighted-text;
background-color: yellow;}
.highlight {NOTE: Notice that the three rules from the mixin was include the highlight selector.
color: black;
font-weight: bold;
border: 1px solid blue;
background-color: yellow; }
Like a function, a mixin can accept arguments that can be passed into the mixin as variable.
<p class="primaryNote">Primary Note goes here... </p>
<p class="secondaryNote">Secondary Note goes here...</p>
</body>
@mixin custom_border ($color, $width) {NOTE: Notice that the border property has two variables ($width and $color) and one static property (solid)
border:$width solid $color;}
.primaryNote {
@include custom_border(blue, 1px);}
.secondaryNote {
@include custom_border(red, 2px);}
.primaryNote {
border: 1px solid blue; }
.secondaryNote {
border: 2px solid red; }
It is also possible to define default values for mixin variables:
<p class="custom_border">Primary Note goes here.../p>
<p class="custom_border">Secondary Note goes here...</p> <p class="regularNote">Regular Note goes here...</p>
</body>
@mixin custom_border ($color, $width) {NOTE: Notice that the border property has two variables ($width and $color) WITH THEIR DEFAULT VALUES and one static property (solid)
border:$width solid $color;}
.primaryNote {
@include custom_border(blue, 1px);}
.secondaryNote {
@include custom_border(red, 2px);}
@mixin standard_border ($color:black, $width:3px) {
border:$width solid $color;}
.regularNote{
@include standard_border($color:purple); }
.primaryNote {
border: 1px solid blue; }
.secondaryNote {
border: 2px solid red; }
.regularNote {
border: 3px solid purple; }
@mixin standard_border ($color:black, $width:3px) {
border:$width solid $color;}
.regularNote{
@include standard_border($color:purple); }
.primaryNote {
border: 1px solid blue; }
.secondaryNote {
border: 2px solid red; }
.regularNote {
border: 3px solid black; }
Until vendor prefixes become standard CSS, you can use Mixin to create them:
@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
transform: $property;
}
.myBox {
@include transform(rotate(45deg));
}
.myBox {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
The @extend directive allows you share a common CSS properties from one selector with several selectors. This is similar to using the concept of inheritance in Object Oriented Programming (OOP). It is useful if you have almost identically styled elements that only differ in some small details.
The goal is to create a class that use properties that are common to all of the other objects you want to create and then use this class as a basis for the all of the objects you create through inheritance using the @extend directive.
<button class="button_basic">More Info...</button>
<button class="button_basic">Login In</button>
</body>
.button_basic {
border-radius: 16px;
padding: 5px;
background-color:red;
color: white;
font-weight: bold; -webkit-box-shadow: 5px 5px 5px black;
box-shadow: 5px 5px 5px black;
cursor:pointer;
}
.button_basic {
border-radius: 16px;
padding: 5px;
background-color: red;
text-shadow: 0px 0px;
color: white;
font-weight: bold;
-webkit-box-shadow: 5px 5px 5px black;
box-shadow: 5px 5px 5px black;
cursor: pointer; }
.button_moreInfo {
@extend .button_basic;
background-color: green;
}
.button_Login {
@extend .button_basic;
background-color:lightgray;
color:black;
}
.button_basic, .button_moreInfo, .button_Login {NOTE: Notice the pre-processor created a group selector (e.g., .button_basic, .button_moreInfo, .button_Login) and individual class for what is DIFFERENT about each button.
border-radius: 16px;
padding: 5px;
background-color: red;
color: white;
font-weight: bold;
-webkit-box-shadow: 5px 5px 5px black;
box-shadow: 5px 5px 5px white;
cursor: pointer; }
.button_moreInfo {
background-color: green; }
.button_Login {
background-color: lightgray;
color: black;}
<button class="button_moreInfo">More Info...</button>
<button class="button_Login">Login In</button>
It is best practice to keep related code in separate files (e.g., navigation, reset, tables, font, color, etc.). Sass @import directive allow you do this.
The @use rule loads mixins, functions, and variables from other Sass stylesheets, and combines CSS from multiple stylesheets together. Stylesheets loaded by @use are called "modules". Sass also provides built-in modules full of useful functions.
IMPORTANT NOTES:
A stylesheet’s @use rules must come before any rules other than @forward,
including style rules. However, you can declare variables before
@use rules to use when configuring modules.
The Sass team discourages the continued use of the @import rule.
Sass will gradually phase it out over the next few years, and
eventually remove it from the language entirely.
Use the @use rule instead.
How Do I Migrate? Use the Sass migration tool that will
automatically converts most @import-based code to @use-based code.
EXAMPLE:
_code.scss file:
mycode {
padding: .25em;
line-height: 0;
}
_custom_list.scss file:
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
standard_styles.scss file:
@use "code";
@ use "custom_list ;
standard_styles.css file:
code { padding: .25em; line-height: 0; } ul, ol { text-align: left; } ul ul, ol ol { padding-bottom: 0; padding-left: 0; }
NOTES:
So, when the standard_styles.css file is created, it will yield:
html, body, ul, ol { margin: 0; padding: 0;}
body {
font-family: Helvetica, sans-serif;
font-size: 18px;
color: red;
}
Sass files that are only meant to be imported but not compiled on their own should starts with and underscore ( _ ) (e.g., _mycode.scss) are called Partials. You can leave off the _ when importing a partial.
EXAMPLE:
_colors.scss file:
$primaryColor: blue;
$secondaryColor: red;
NOTE: This file will not be converted to "colors.css."
If the partial file is imported (underscore omitted), Sass know to import the "_colors.scss."
@import "colors";
body {
font-family: Helvetica, sans-serif;
font-size: 18px;
color: red;}
There are a host of functions that can be used with Sass. This is an advanced concept beyond the scope of this training. However, below is a list of resources:
W3School:
Sass Web Site: