SASS/SCSS

SCSS Syntax Fundamentals & First Stylesheet

20 min Lesson 3 of 30

SCSS Syntax Fundamentals & First Stylesheet

Now that SASS is installed and your environment is ready, it's time to dive deep into SCSS syntax! In this lesson, we'll explore the fundamental syntax rules of SCSS, understand how it relates to CSS, and write our first comprehensive stylesheet that demonstrates SASS's power.

SCSS: A Superset of CSS

The most important thing to understand about SCSS is that it's a superset of CSS. This means:

  • Every valid CSS file is also a valid SCSS file
  • You can copy-paste CSS into an SCSS file and it will work
  • You can gradually add SASS features without rewriting everything
  • Learning curve is minimal if you already know CSS
Tip: Because SCSS is a superset of CSS, you can start by writing plain CSS in your .scss files and gradually introduce SASS features as you learn them. There's no pressure to use everything at once!

File Extensions: .scss vs .sass

SASS supports two different syntaxes with different file extensions:

.scss Files (Sassy CSS)

  • Uses braces {} and semicolons ;
  • Looks and feels like CSS with extra features
  • Industry standard - used in 95%+ of projects
  • Easier to learn and integrate with existing CSS

SCSS Syntax Example

$primary: #3498db;

.button {
  background: $primary;
  padding: 10px 20px;

  &:hover {
    background: darken($primary, 10%);
  }
}

.sass Files (Indented Syntax)

  • No braces or semicolons - uses indentation (like Python)
  • More concise but less familiar
  • Rarely used in modern projects
  • Cannot mix with CSS - requires full rewrite

SASS Syntax Example (Indented)

$primary: #3498db

.button
  background: $primary
  padding: 10px 20px

  &:hover
    background: darken($primary, 10%)
Note: We'll use SCSS syntax (.scss files) exclusively in this course, as it's the industry standard. When people say "SASS," they usually mean SCSS.

Comments in SCSS: Single-Line and Multi-Line

SCSS supports two types of comments, and they behave differently during compilation:

Single-Line Comments (//)

Single-line comments use double slashes and are completely stripped from the compiled CSS output. They're perfect for developer notes that shouldn't appear in production.

Single-Line Comments

// This is a single-line comment
// It will NOT appear in the compiled CSS

$primary: #3498db; // Inline comment also works

.button {
  // TODO: Add more button styles later
  background: $primary;
}

Multi-Line Comments (/* */)

Multi-line comments use /* */ syntax (just like CSS) and are preserved in the compiled output (unless using compressed style).

Multi-Line Comments

/*
 * This is a multi-line comment
 * It WILL appear in the compiled CSS
 * Use it for copyright notices, documentation, etc.
 */

.header {
  background: #333; /* This inline comment also preserved */
}

Compiled CSS Output

/*
 * This is a multi-line comment
 * It WILL appear in the compiled CSS
 * Use it for copyright notices, documentation, etc.
 */
.header {
  background: #333; /* This inline comment also preserved */
}
Tip: Use single-line comments (//) for internal notes and TODOs. Use multi-line comments (/* */) only for copyright notices or essential documentation that should remain in the final CSS.

Writing Your First SCSS File

Let's write a comprehensive SCSS file that demonstrates basic features. Create a file called styles.scss:

styles.scss - Complete Example

// ===========================================
// Variables
// ===========================================

// Colors
$primary-color: #3498db;
$secondary-color: #2ecc71;
$danger-color: #e74c3c;
$text-color: #333;
$light-gray: #ecf0f1;

// Typography
$font-family: 'Helvetica Neue', Arial, sans-serif;
$base-font-size: 16px;
$heading-font-size: 32px;

// Spacing
$base-padding: 16px;
$base-margin: 16px;

// ===========================================
// Base Styles
// ===========================================

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: $font-family;
  font-size: $base-font-size;
  color: $text-color;
  line-height: 1.6;
  padding: $base-padding;
  background-color: $light-gray;
}

// ===========================================
// Typography
// ===========================================

h1 {
  font-size: $heading-font-size;
  color: $primary-color;
  margin-bottom: $base-margin;

  // Nested selector for emphasis
  span {
    color: $secondary-color;
    font-weight: normal;
  }
}

p {
  margin-bottom: $base-margin;
  line-height: 1.8;
}

// ===========================================
// Components
// ===========================================

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: $base-padding * 2;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.button {
  display: inline-block;
  padding: $base-padding / 2 $base-padding;
  background: $primary-color;
  color: white;
  text-decoration: none;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: $base-font-size;
  transition: all 0.3s ease;

  // Nested pseudo-class
  &:hover {
    background: darken($primary-color, 10%);
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  }

  // Nested pseudo-class
  &:active {
    transform: translateY(0);
  }

  // Nested modifier class
  &.secondary {
    background: $secondary-color;

    &:hover {
      background: darken($secondary-color, 10%);
    }
  }

  // Nested modifier class
  &.danger {
    background: $danger-color;

    &:hover {
      background: darken($danger-color, 10%);
    }
  }
}

.card {
  background: white;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: $base-padding;
  margin-bottom: $base-margin;

  .card-header {
    font-size: 20px;
    font-weight: bold;
    margin-bottom: $base-margin / 2;
    color: $primary-color;
  }

  .card-body {
    font-size: 14px;
    color: #666;
  }

  .card-footer {
    margin-top: $base-margin;
    padding-top: $base-padding / 2;
    border-top: 1px solid #eee;
    font-size: 12px;
    color: #999;
  }
}

Compiling and Viewing the Output

Now let's compile this SCSS file and see what CSS is generated. Run the compile command:

Compile Command

sass styles.scss styles.css

Here's a portion of the generated CSS output:

Generated CSS (Excerpt)

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  color: #333;
  line-height: 1.6;
  padding: 16px;
  background-color: #ecf0f1;
}

h1 {
  font-size: 32px;
  color: #3498db;
  margin-bottom: 16px;
}
h1 span {
  color: #2ecc71;
  font-weight: normal;
}

.button {
  display: inline-block;
  padding: 8px 16px;
  background: #3498db;
  color: white;
  text-decoration: none;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s ease;
}
.button:hover {
  background: #217dbb;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.button:active {
  transform: translateY(0);
}
.button.secondary {
  background: #2ecc71;
}
.button.secondary:hover {
  background: #25a25a;
}
.button.danger {
  background: #e74c3c;
}
.button.danger:hover {
  background: #d62c1a;
}
Note: Notice how all the variables were replaced with their actual values, all the nesting was flattened into proper CSS selectors, and the & symbol was replaced with the parent selector. This is SASS's compilation magic!

Understanding How Nesting Maps to CSS

One of the most powerful features of SCSS is nesting. Let's understand exactly how nested SCSS translates to CSS:

Basic Nesting

SCSS Input

.card {
  padding: 20px;

  .card-title {
    font-size: 24px;
  }
}

CSS Output

.card {
  padding: 20px;
}

.card .card-title {
  font-size: 24px;
}

The nested .card-title becomes .card .card-title (a descendant selector).

The Parent Selector (&)

The ampersand & is a special character that references the parent selector. It's incredibly useful for pseudo-classes, pseudo-elements, and modifiers:

SCSS with & Symbol

.button {
  background: blue;

  &:hover {
    background: darkblue;
  }

  &:focus {
    outline: 2px solid blue;
  }

  &.active {
    background: navy;
  }

  &::before {
    content: "→";
  }
}

CSS Output

.button {
  background: blue;
}
.button:hover {
  background: darkblue;
}
.button:focus {
  outline: 2px solid blue;
}
.button.active {
  background: navy;
}
.button::before {
  content: "→";
}
Tip: The & symbol is replaced with the exact parent selector during compilation. It's not just for classes - it works with any selector!

Multiple Levels of Nesting

Deep Nesting SCSS

.navigation {
  background: #333;

  ul {
    list-style: none;

    li {
      display: inline-block;

      a {
        color: white;
        padding: 10px;

        &:hover {
          color: #3498db;
        }
      }
    }
  }
}

CSS Output

.navigation {
  background: #333;
}
.navigation ul {
  list-style: none;
}
.navigation ul li {
  display: inline-block;
}
.navigation ul li a {
  color: white;
  padding: 10px;
}
.navigation ul li a:hover {
  color: #3498db;
}
Warning: While deep nesting is possible, avoid going more than 3-4 levels deep. Over-nesting creates overly specific selectors that are hard to override and can impact performance.

Basic Variable Usage with $

Variables in SCSS start with a dollar sign $. They allow you to store values and reuse them throughout your stylesheet:

Declaring and Using Variables

// Variable declarations
$primary-color: #3498db;
$font-size-base: 16px;
$spacing-unit: 8px;

// Using variables
body {
  color: $primary-color;
  font-size: $font-size-base;
  padding: $spacing-unit * 2; // Variables support math!
}

.header {
  background: $primary-color;
  margin-bottom: $spacing-unit * 3;
}

.button {
  padding: $spacing-unit $spacing-unit * 2;
  font-size: $font-size-base;
}

Compiled CSS

body {
  color: #3498db;
  font-size: 16px;
  padding: 16px;
}

.header {
  background: #3498db;
  margin-bottom: 24px;
}

.button {
  padding: 8px 16px;
  font-size: 16px;
}

Notice how the variables are replaced with their actual values, and mathematical operations are calculated during compilation.

Tip: Variable names should be descriptive and follow kebab-case convention: $primary-color, not $primaryColor or $primary_color.

Creating an HTML File to Test Your Styles

To see your compiled CSS in action, create a simple HTML file that links to the generated CSS:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My First SCSS Project</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="container">
    <h1>Welcome to <span>SCSS</span></h1>

    <p>This page is styled with CSS compiled from SCSS!</p>

    <div class="card">
      <div class="card-header">Card Title</div>
      <div class="card-body">
        This is a card component styled with nested SCSS selectors.
      </div>
      <div class="card-footer">Card footer information</div>
    </div>

    <button class="button">Primary Button</button>
    <button class="button secondary">Secondary Button</button>
    <button class="button danger">Danger Button</button>
  </div>
</body>
</html>

Open this HTML file in your browser, and you'll see your SCSS-compiled styles in action!

Watching Files During Development

Instead of manually compiling after every change, use watch mode for automatic compilation:

Start Watch Mode

sass --watch styles.scss:styles.css

Now every time you save styles.scss, the CSS file will automatically update. Keep your browser open and refresh to see changes instantly!

Tip: Combine SASS watch mode with a browser live-reload extension (like Live Server in VS Code) for the ultimate development experience - save your SCSS and see changes instantly in the browser without manual refresh!

Common Beginner Mistakes to Avoid

1. Forgetting Semicolons

Unlike the indented .sass syntax, SCSS requires semicolons:

Wrong (Will Cause Error)

.button {
  background: blue  // Missing semicolon
  color: white
}

Correct

.button {
  background: blue;
  color: white;
}

2. Misusing the & Symbol

The & must be used carefully - it references the entire parent selector:

Wrong Usage

.card {
  & .header {  // This creates ".card .header"
    font-size: 20px;
  }
}

// Better without &:
.card {
  .header {  // Also creates ".card .header"
    font-size: 20px;
  }
}

Correct Usage

.button {
  &:hover {     // Creates ".button:hover"
  }

  &.active {    // Creates ".button.active"
  }

  &-primary {   // Creates ".button-primary" (BEM style)
  }
}

3. Over-Nesting

Just because you can nest doesn't mean you should nest everything 10 levels deep:

Over-Nested (Bad)

.page {
  .container {
    .content {
      .article {
        .heading {
          .title {
            color: blue;
          }
        }
      }
    }
  }
}

// This compiles to:
// .page .container .content .article .heading .title { color: blue; }
// Way too specific!

Better Approach

.article {
  .article-title {
    color: blue;
  }
}

// Compiles to: .article .article-title { color: blue; }
// Much more maintainable!

Conclusion

You now understand the fundamental syntax of SCSS! You've learned that SCSS is a superset of CSS, how to use comments, how nesting works, how to declare and use variables, and how to see the compiled CSS output. These fundamentals are the foundation for all the powerful features we'll explore in upcoming lessons.

In the next lesson, we'll dive deep into variables - data types, scope, naming conventions, and advanced variable techniques.

Exercise 1: Convert CSS to SCSS

Take the following CSS and convert it to SCSS using nesting:

.navigation { background: #333; }
.navigation .nav-list { list-style: none; }
.navigation .nav-list .nav-item { display: inline-block; }
.navigation .nav-list .nav-item .nav-link { color: white; }
.navigation .nav-list .nav-item .nav-link:hover { color: #3498db; }

Create an SCSS file, compile it, and verify the output matches the original CSS.

Exercise 2: Create a Styled Component

Create an SCSS file that styles a "pricing card" component:

  1. Define variables for colors, spacing, and border-radius
  2. Create a .pricing-card class with nested elements: .card-header, .card-price, .card-features, .card-button
  3. Use the & selector to add a :hover effect to the button
  4. Create HTML to display your styled card
  5. Compile and view in the browser

Exercise 3: Experiment with Comments

Create an SCSS file with both types of comments:

  1. Add single-line comments (//) explaining your code
  2. Add a multi-line comment (/* */) at the top with a copyright notice
  3. Compile to CSS and open the output file
  4. Notice which comments appear in the CSS and which don't
  5. Try compiling with --style=compressed and see how it affects comments