Sass (Syntactically Awesome Stylesheets) is a CSS preprocessor that adds power and elegance to the basic CSS. SCSS (Sassy CSS) is a syntax of Sass that uses a more CSS-like syntax with curly braces and semicolons. It allows variables, nesting, mixins, functions, and more to make writing styles easier and more maintainable. SCSS files typically end with the `.scss` extension.
// Defining a variable for primary color
$primary-color: blue;
// Nesting styles for a button
.button {
color: white;
background-color: $primary-color;
&:hover {
background-color: darken($primary-color, 10%);
}
}
Output:
.button { color: white; background-color: blue; } .button:hover { background-color: #0000cc; }
Sass has two syntaxes: the older indented syntax (often referred to as "Sass") and the newer SCSS syntax. Sass (the indented syntax) does not use curly braces or semicolons, while SCSS is more similar to standard CSS and does use them. SCSS is more popular today because of its CSS-like structure, making it easier for most developers to adapt.
// SCSS Syntax
.card {
padding: 10px;
background: white;
}
// Sass Syntax (indented)
// .card
// padding: 10px
// background: white
Output:
.card { padding: 10px; background: white; }
SCSS allows developers to write more organized, reusable, and maintainable styles. Features like variables, nesting, partials, mixins, and inheritance help to reduce redundancy and simplify changes across large stylesheets. It makes CSS dynamic and easier to manage, especially in large projects.
$font-stack: Helvetica, sans-serif;
$base-color: #333;
body {
font: 100% $font-stack;
color: $base-color;
}
Output:
body { font: 100% Helvetica, sans-serif; color: #333; }
Sass can be installed in several ways. The most common are using the Sass command-line interface (CLI), installing `node-sass` via npm (Node.js), or using Dart Sass, the primary implementation. Dart Sass is the recommended method today and supports the latest features. You install it globally and use commands like `sass input.scss output.css` to compile files.
// Install Sass globally via Dart Sass
npm install -g sass
// Compile a file
sass style.scss style.css
Output:
style.scss compiled to style.css
To use SCSS in your project, you create `.scss` files and include them in your build process. If you're not using a framework or bundler, you can manually compile SCSS to CSS using the Sass CLI. Then link the compiled CSS file in your HTML. For projects with Webpack or tools like Vite, SCSS can be directly integrated and compiled automatically on save.
// style.scss file
$bg-color: lightgray;
.box {
width: 100px;
height: 100px;
background-color: $bg-color;
}
// Terminal
sass style.scss style.css
// HTML
<link rel="stylesheet" href="style.css">
Output:
.box { width: 100px; height: 100px; background-color: lightgray; }
To use SCSS in the browser, it needs to be compiled to standard CSS. This is done using the Sass CLI or through build tools like Webpack. Compilation transforms variables, nesting, and functions into plain CSS the browser understands. After compiling, link the resulting CSS file in your HTML to apply styles.
// SCSS file: main.scss
$text-color: darkgreen;
p {
color: $text-color;
}
// Compile using CLI
sass main.scss main.css
// Link in HTML
<link rel="stylesheet" href="main.css">
Output:
p { color: darkgreen; }
SCSS syntax is similar to CSS but includes enhanced features like variables, nesting, mixins, and functions. It uses curly braces `{}` and semicolons `;` just like standard CSS, making it easier for developers to transition. SCSS files end with `.scss`, and everything written inside will be compiled to valid CSS.
$main-color: teal;
.title {
color: $main-color;
font-size: 24px;
}
Output:
.title { color: teal; font-size: 24px; }
Nesting in SCSS allows selectors to be nested within other selectors, reflecting the HTML structure. However, over-nesting should be avoided as it can create overly specific selectors and lead to difficult-to-maintain code. A best practice is to nest only 2–3 levels deep.
.nav {
background-color: #eee;
ul {
list-style: none;
li {
display: inline-block;
padding: 10px;
}
}
}
Output:
.nav { background-color: #eee; } .nav ul { list-style: none; } .nav ul li { display: inline-block; padding: 10px; }
Variables in SCSS store values like colors, sizes, and fonts. They start with a dollar sign `$` and help keep styles consistent and easier to update across the stylesheet. Changing the value of a variable will automatically update it wherever it's used.
$font-color: navy;
$padding-size: 15px;
.box {
color: $font-color;
padding: $padding-size;
}
Output:
.box { color: navy; padding: 15px; }
SCSS supports two types of comments. Single-line comments using `//` are not included in the compiled CSS. Block comments using `/* */` are included in the output CSS. This allows you to document your code without bloating the final CSS file with notes if not needed.
// This is a developer comment and will not appear in CSS
$bg: #ccc;
/* This will appear in the output CSS */
.section {
background: $bg;
}
Output:
/* This will appear in the output CSS */ .section { background: #ccc; }
SCSS allows basic arithmetic operations like addition (+), subtraction (-), multiplication (*), and division (/) on numbers and units. This is useful for calculations related to sizes, spacing, and layouts directly inside the SCSS code.
$base-margin: 10px;
.content {
margin-top: $base-margin * 2;
width: 100% - 20px;
}
Output:
.content { margin-top: 20px; width: 80%; }
SCSS supports multiple data types: Strings (`"text"`), Numbers (`12`, `14px`), Colors (`#fff`, `red`), Booleans (`true`, `false`), and null values. These data types help create dynamic logic using functions and conditions in SCSS.
$name: "header";
$height: 50px;
$color: #ffcc00;
$visible: true;
$nothing: null;
.#{$name} {
height: $height;
background-color: $color;
display: if($visible, block, none);
}
Output:
.header { height: 50px; background-color: #ffcc00; display: block; }
Nesting selectors in SCSS allows you to reflect the HTML structure directly inside your styles. Instead of writing the full selector repeatedly, you can nest child elements inside their parent selectors. This makes the code shorter and more readable, especially for deeply structured components.
.card {
border: 1px solid #ccc;
.title {
font-weight: bold;
}
.description {
color: #666;
}
}
Output:
.card { border: 1px solid #ccc; } .card .title { font-weight: bold; } .card .description { color: #666; }
The ampersand `&` in SCSS refers to the parent selector. It is especially useful for creating modifiers, pseudo-classes, or when referencing the full selector inside nesting. It allows more control and precise targeting of styles.
.button {
color: white;
background: blue;
&.primary {
background: navy;
}
&:hover {
background: darkblue;
}
}
Output:
.button { color: white; background: blue; } .button.primary { background: navy; } .button:hover { background: darkblue; }
Placeholder selectors in SCSS are defined with a `%` and used with `@extend` to share common styles without producing unnecessary output in the final CSS. They’re not compiled on their own unless extended, which keeps your CSS cleaner and more efficient.
%box-style {
border: 1px solid #000;
padding: 10px;
}
.info-box {
@extend %box-style;
background: #eef;
}
.alert-box {
@extend %box-style;
background: #fee;
}
Output:
.info-box, .alert-box { border: 1px solid #000; padding: 10px; } .info-box { background: #eef; } .alert-box { background: #fee; }
SCSS supports CSS attribute selectors like `[type="text"]` and pseudo-classes like `:hover`, `:first-child`, etc. These can be nested within selectors just like normal rules, and allow targeting specific elements or states with ease.
input {
&[type="text"] {
border: 1px solid #aaa;
}
}
a {
&:hover {
text-decoration: underline;
}
}
Output:
input[type="text"] { border: 1px solid #aaa; } a:hover { text-decoration: underline; }
Combining nested rules allows you to group selectors for shared styles while still maintaining structure. It’s useful when styling multiple elements inside a container or applying similar rules to related components. Grouping keeps code organized and reduces repetition.
.menu {
ul, ol {
list-style: none;
padding: 0;
}
li {
display: inline-block;
}
}
Output:
.menu ul, .menu ol { list-style: none; padding: 0; } .menu li { display: inline-block; }
In SCSS (Sassy CSS), variables are used to store reusable values like colors, font sizes, margins, and more. By defining variables, we avoid repeating values and make our stylesheets easier to maintain. Variables are defined using a dollar sign (`$`) followed by a name and value. Once defined, these variables can be used throughout your SCSS code wherever the value is needed.
$primary-color: blue;
// Define a variable called primary-color with the value "blue"
body {
background-color: $primary-color;
// Use the variable to set background-color
}
The body will have a blue background.
SCSS variables can have either global or local scope. A global variable is available everywhere in your SCSS files, while a local variable is only available within the block or selector where it’s defined. If you define a variable inside a selector or mixin, it will not affect the same-named variable outside that block unless explicitly made global.
$color: red;
// Global variable
.button {
$color: green;
// Local variable inside .button
color: $color;
}
.text {
color: $color;
// This will still use the global variable
}
.button will have green text
.text will have red text
The `!default` flag in SCSS lets you assign a value to a variable only if it hasn’t already been defined. This is helpful when building themes or libraries where you want to provide fallback values but still allow users to override them.
$font-size: 16px !default;
// Set default only if $font-size is not already defined
body {
font-size: $font-size;
}
The body will use 16px font-size unless $font-size was defined earlier.
Maps in SCSS are like dictionaries or objects in other languages. They store key-value pairs, which can represent related settings like themes, breakpoints, or sizes. You create a map using parentheses and access items using SCSS functions.
$theme-colors: (
primary: blue,
secondary: gray,
);
// Create a map of theme colors
A SCSS map storing primary and secondary colors.
The `map-get()` function is used to retrieve a value from a map using a key. The `map-merge()` function allows you to combine two maps, or add/update values in an existing map. These are useful for working with theme settings, responsive breakpoints, or config maps dynamically.
$colors: (
primary: blue,
secondary: green,
);
$primary-color: map-get($colors, primary);
// Get the value for key "primary" from the map
$new-colors: map-merge($colors, (danger: red));
// Merge a new key "danger" into the existing $colors map
$primary-color = blue
$new-colors = (primary: blue, secondary: green, danger: red)
Mixins in SCSS are reusable blocks of styles that can be defined once and included in multiple selectors. They help eliminate redundancy and make code more maintainable. Think of mixins as functions in programming that encapsulate logic to be reused wherever needed.
@mixin rounded {
border-radius: 10px;
}
.box {
@include rounded;
background: lightblue;
}
Output:
.box { border-radius: 10px; background: lightblue; }
To create a mixin, you use the `@mixin` directive followed by a name and a block of CSS rules. Mixins can optionally accept parameters. They are like style containers you can inject into other rules using `@include`.
@mixin shadow-box {
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}
.panel {
@include shadow-box;
}
Output:
.panel { box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); }
To use a mixin in SCSS, you call it using the `@include` directive followed by the mixin’s name. This tells SCSS to insert the mixin's code block into the selector. It's a simple way to reuse complex or common styling logic.
@mixin border-style {
border: 2px dashed green;
}
.note {
@include border-style;
padding: 20px;
}
Output:
.note { border: 2px dashed green; padding: 20px; }
SCSS mixins can accept arguments just like functions. This allows you to customize the output depending on the values you pass in, making your styles more dynamic and flexible.
@mixin text-color($color) {
color: $color;
}
.success {
@include text-color(green);
}
.error {
@include text-color(red);
}
Output:
.success { color: green; } .error { color: red; }
Mixins can include default parameter values, which are used when no argument is passed during `@include`. This helps create flexible and reusable styles with fallback values.
@mixin padding-box($size: 15px) {
padding: $size;
}
.default-padding {
@include padding-box;
}
.custom-padding {
@include padding-box(30px);
}
Output:
.default-padding { padding: 15px; } .custom-padding { padding: 30px; }
Content blocks allow you to insert custom CSS into a mixin using `@content`. This is useful when you want to create a mixin that wraps around other styles or lets you inject custom blocks inside a reusable structure.
@mixin card {
border: 1px solid #000;
padding: 10px;
@content;
}
.profile-card {
@include card {
background: #f0f0f0;
color: #333;
}
}
Output:
.profile-card { border: 1px solid #000; padding: 10px; background: #f0f0f0; color: #333; }
SCSS provides several built-in functions that make it easier to manipulate values. Functions such as those for colors, strings, lists, and maps help developers achieve the desired styles and values without manually processing them.
Example of color function:
$base-color: #ff6347;
/* Defining a base color */
$lighter-color: lighten($base-color, 20%);
/* Lighten the base color by 20% */
body {
background-color: $lighter-color;
/* Apply the lighter color as background */
}
Output: The body background color will be a lighter shade of #ff6347.
In SCSS, custom functions allow developers to extend the built-in functionality. These functions can take parameters and return values, providing flexibility and reuse in style sheets.
Example of a custom function to calculate the contrast ratio between two colors:
@function contrast($color1, $color2) {
$lum1: luminance($color1);
/* Calculate luminance of color1 */
$lum2: luminance($color2);
/* Calculate luminance of color2 */
@return abs($lum1 - $lum2);
/* Return the absolute difference in luminance */
}
$color1: #ff6347;
/* Define color 1 */
$color2: #4682b4;
/* Define color 2 */
$contrast-ratio: contrast($color1, $color2);
/* Call the custom contrast function */
body {
background-color: $color1;
color: $color2;
font-size: 16px;
font-weight: bold;
}
Output: The body will have a background color of #ff6347, text color #4682b4, and the contrast ratio is calculated.
In SCSS, functions can return values such as numbers, colors, or other data types. This allows for more modular and dynamic style sheet code.
Example of a function returning a color based on a condition:
@function get-text-color($background-color) {
@if lightness($background-color) > 50% {
@return black;
/* Return black for light backgrounds */
}
@else {
@return white;
/* Return white for dark backgrounds */
}
}
$bg-color: #ff6347;
/* Define background color */
$text-color: get-text-color($bg-color);
/* Call the function to get text color */
body {
background-color: $bg-color;
color: $text-color;
}
Output: The background color is #ff6347, and the text color is black because the background is light.
SCSS supports arithmetic and logical operations. Arithmetic operations include addition, subtraction, multiplication, and division, while logical operators include comparison and conditional checks.
Example of arithmetic operators:
$width: 100px;
$padding: 20px;
$total-width: $width + $padding * 2;
/* Add width and twice the padding */
div {
width: $total-width;
/* Set width of div */
}
Output: The total width will be 140px (100px + 2 * 20px).
Example of logical operators:
$height: 50px;
$width: 50px;
@if $height == $width {
.square {
background-color: green;
/* If it's a square, set green background */
}
}
Output: The square class will have a green background if the height and width are equal.
SCSS provides string manipulation functions such as concatenation, length calculation, and substring extraction to handle text-based operations in styles.
Example of string manipulation using the `str-length` and `str-insert` functions:
$greeting: "Hello, ";
$name: "World";
$message: str-insert($greeting, $name, 8);
/* Insert name after "Hello, " */
body {
content: $message;
/* Display the message */
}
Output: The body will display "Hello, World".
The @extend
directive in SCSS allows one selector to inherit the styles of another.
This helps avoid repetition by reusing styles across multiple selectors.
It’s similar to inheritance in object-oriented programming—styles are passed from one class to another.
This results in a cleaner and more maintainable stylesheet.
/* Define a base class */
%button-style {
padding: 10px;
border: none;
background-color: blue;
color: white;
}
/* Reuse the base style using @extend */
.button-primary {
@extend %button-style;
}
.button-primary { padding: 10px; border: none; background-color: blue; color: white; }
Placeholder selectors are defined using the %
symbol in SCSS.
They are like templates that can be extended using @extend
.
These placeholders do not generate any CSS on their own unless extended.
This makes them useful for defining reusable style chunks without cluttering the final CSS.
/* Create a placeholder */
%card-style {
box-shadow: 0 0 10px gray;
padding: 20px;
background: white;
}
/* Extend the placeholder in a real class */
.profile-card {
@extend %card-style;
}
.profile-card { box-shadow: 0 0 10px gray; padding: 20px; background: white; }
The @extend
directive reduces repetition and makes styles easier to maintain by centralizing them.
However, it can lead to unexpected behavior if not used carefully, such as generating overly complex CSS selectors.
Also, it ties styles together tightly, which may cause side effects when one class is updated.
It is powerful but should be used when you need full inheritance rather than small, flexible chunks.
/* Common button style */
%btn-common {
font-size: 16px;
padding: 10px;
}
/* Two buttons extending the same placeholder */
.btn-ok {
@extend %btn-common;
color: green;
}
.btn-cancel {
@extend %btn-common;
color: red;
}
.btn-ok, .btn-cancel { font-size: 16px; padding: 10px; } .btn-ok { color: green; } .btn-cancel { color: red; }
When deciding between mixins and @extend
, consider flexibility vs. simplicity.
Mixins allow parameterization (passing values), so they're great for dynamic reuse.
@extend
is cleaner for shared, fixed styles.
Use mixins when you need variables or conditional logic.
Use @extend
for flat reuse where styles don't change.
/* Using a mixin with parameter */
@mixin button-style($color) {
padding: 10px;
border: none;
background-color: $color;
color: white;
}
/* Apply mixin with a custom color */
.btn-custom {
@include button-style(red);
}
.btn-custom { padding: 10px; border: none; background-color: red; color: white; }
Refactoring with inheritance involves identifying repeated code and moving it into placeholders.
This promotes DRY (Don’t Repeat Yourself) principles.
Using @extend
and %placeholders
, you can refactor long repetitive classes into reusable parts.
This improves organization, reduces file size, and simplifies updates.
/* Repeated styles moved to a placeholder */
%common-box {
border: 1px solid #ccc;
margin: 10px;
padding: 10px;
}
/* Apply the refactored style */
.box1 {
@extend %common-box;
}
.box2 {
@extend %common-box;
}
.box1, .box2 { border: 1px solid #ccc; margin: 10px; padding: 10px; }
The @if
and @else
directives are used to control the flow of rendering based on conditional logic.
These are especially useful in template engines like Blade (Laravel) or Sass for conditional styles.
In simple terms, if a condition is true, one block of code executes; otherwise, the alternative block runs.
This helps in dynamically adjusting the content or styling depending on variables or logic.
<!-- Simple real-world HTML rendering logic -->Output: Welcome back, user!
<?php
$isLoggedIn = true; // Simulate a user login status
if ($isLoggedIn) {
echo "Welcome back, user!"; // Show greeting if logged in
} else {
echo "Please log in."; // Ask user to log in if not
}
?>
The @for
directive is a looping structure commonly used in templating or scripting languages.
It lets you repeat a block of code a fixed number of times.
This is especially handy when you know exactly how many times you need to loop, such as displaying a list of numbers or rendering a set of cards.
<!-- Simple @for example in PHP -->Output:
<?php
for ($i = 1; $i <= 3; $i++) {
echo "Product $i <br>"; // Print each product number
}
?>
The @each
directive is used to loop through collections like arrays or lists.
It is especially powerful in Blade templating for repeating a view partial for each item in a collection.
It helps break down logic into reusable templates and keeps code clean.
<!-- Simulating @each behavior in plain PHP -->Output:
<?php
$fruits = ["Apple", "Banana", "Cherry"];
foreach ($fruits as $fruit) {
echo "Fruit: $fruit <br>"; // Print each fruit
}
?>
The @while
directive runs a block of code repeatedly as long as a certain condition is true.
Unlike the @for
loop, it is ideal when you don’t know how many times the loop should run in advance.
It’s commonly used for processes like waiting for a condition to change.
<!-- Example of a while loop -->Output:
<?php
$count = 1;
while ($count <= 3) {
echo "Step $count <br>"; // Print current step
$count++; // Increment counter
}
?>
Looping over lists and maps allows you to handle collections of data dynamically. Lists are simple arrays of items, while maps (also called associative arrays) have key-value pairs. Looping through these structures is vital for displaying or manipulating dynamic data like user details, orders, or settings.
<!-- Looping through a map (associative array) -->Output:
<?php
$user = [
"name" => "John",
"email" => "john@example.com",
"role" => "Admin"
];
foreach ($user as $key => $value) {
echo ucfirst($key) . ": " . $value . "<br>"; // Print key-value pairs
}
?>
Partials in SCSS allow you to break up your stylesheet into smaller, manageable pieces. A partial is a SCSS file named with a leading underscore, like `_variables.scss`. SCSS will not compile these partials directly, but they can be imported into other SCSS files.
// _variables.scss
$primary-color: blue;
$font-size: 16px;
// main.scss
@import 'variables';
body {
color: $primary-color;
font-size: $font-size;
}
Output:
body { color: blue; font-size: 16px; }
The `@use` directive is the modern way to load SCSS files into others, replacing `@import`. It helps prevent namespace pollution by loading files in a controlled way. `@forward` allows you to make a partial’s content available to other files, providing a clean way to expose certain styles or variables.
// _colors.scss
$primary-color: blue;
// _index.scss
@forward 'colors';
// main.scss
@use 'index';
body {
color: index.$primary-color;
}
Output:
body { color: blue; }
One of the benefits of using `@use` is that it automatically namespaces all the variables, mixins, and functions within a file. This helps avoid conflicts and ensures that you only access the parts of a file that you need. You can also give the namespace a custom name.
// _colors.scss
$primary-color: blue;
// main.scss
@use 'colors' as c;
body {
color: c.$primary-color;
}
Output:
body { color: blue; }
In SCSS, you can share variables, mixins, and functions across multiple files. By organizing them into partials and using `@use` or `@forward`, you can structure your code in a way that allows you to easily reuse common styles and logic across your project.
// _variables.scss
$primary-color: blue;
// _mixins.scss
@mixin border-radius($radius) {
border-radius: $radius;
}
// main.scss
@use 'variables';
@use 'mixins';
.box {
color: variables.$primary-color;
@include mixins.border-radius(5px);
}
Output:
.box { color: blue; border-radius: 5px; }
SCSS architecture involves organizing your SCSS files in a way that makes your code scalable and maintainable. A good approach is to break your code into logical modules (e.g., variables, mixins, components), and use partials and `@use` to structure it. This makes the codebase easier to navigate, reduces duplication, and enhances reusability.
// _variables.scss
$primary-color: blue;
// _mixins.scss
@mixin button-style {
padding: 10px 15px;
background-color: $primary-color;
}
// _buttons.scss
@use 'mixins';
.button {
@include mixins.button-style;
}
Output:
.button { padding: 10px 15px; background-color: blue; }
BEM (Block, Element, Modifier) is a methodology that helps in creating reusable components and code sharing in front-end development. BEM works well with SCSS to manage styles in a modular and structured manner.
Example of using BEM in SCSS:
.block {
background-color: #f5f5f5;
/* Define background color for block */
padding: 10px;
/* Add padding inside the block */
}
.block__element {
color: #333;
/* Set color for the block element */
font-size: 16px;
/* Set font size for the block element */
}
.block--modifier {
background-color: #e0e0e0;
/* Change background color for modified block */
}
Output: A block with a gray background, padding, and a modified version of the block with a lighter background color.
OOCSS is an approach to CSS that focuses on reusability and separating structure from skin. The idea is to create reusable objects that can be applied across different parts of the site without duplication of code.
Example of OOCSS with SCSS:
.object {
display: block;
/* Make the object a block element */
margin: 10px;
/* Add margin around the object */
}
.skin {
background-color: #f5f5f5;
/* Define background color for skin */
border-radius: 5px;
/* Apply rounded corners to the skin */
}
.object-with-skin {
@extend .object;
/* Extend the object class */
@extend .skin;
/* Extend the skin class */
}
Output: A reusable object with a gray background and rounded corners, applied to multiple elements.
SMACSS is a style guide that focuses on organizing CSS rules into categories such as base, layout, module, state, and theme. It aims to improve scalability and maintainability of large CSS codebases.
Example of SMACSS in SCSS:
/* Base styles */
html, body {
font-family: Arial, sans-serif;
/* Set base font family */
margin: 0;
/* Remove default margin */
}
/* Layout styles */
.container {
max-width: 1200px;
/* Set maximum width for container */
margin: 0 auto;
/* Center container */
}
/* Module styles */
.card {
background-color: #fff;
/* Set background for card */
padding: 20px;
/* Add padding inside card */
}
/* State styles */
.is-active {
opacity: 1;
/* Set active state opacity */
}
.is-hidden {
display: none;
/* Hide the element in hidden state */
}
Output: A scalable and modular CSS setup with base, layout, and module styles.
ITCSS is a CSS architecture that promotes organizing styles in a way that scales from generic to specific. It follows the "inverted triangle" model, with more general styles at the top and more specific styles at the bottom.
Example of ITCSS in SCSS:
/* Global Styles */
* {
margin: 0;
/* Remove margin for all elements */
padding: 0;
/* Remove padding for all elements */
}
/* Generic Styles */
.container {
width: 100%;
/* Set container width to full */
}
/* Components */
.card {
background-color: #fff;
/* Set background color for card */
padding: 20px;
/* Add padding inside card */
}
/* Utilities */
.is-hidden {
display: none;
/* Hide elements with this class */
}
Output: An ITCSS structure where global styles are at the top, followed by more specific styles for components and utilities.
Utility-first SCSS focuses on using small utility classes and functions/mixins to apply styles. This approach makes the code more reusable and easier to maintain by applying styles in a more modular way.
Example of utility-first SCSS with mixins and functions:
@mixin center($width) {
display: flex;
justify-content: center;
align-items: center;
width: $width;
/* Set width dynamically with the provided parameter */
}
.container {
@include center(100%);
/* Use mixin to center content */
}
.bg-primary {
background-color: #007bff;
/* Set background to primary color */
color: white;
/* Set text color to white */
}
.text-center {
text-align: center;
/* Align text to the center */
}
Output: A centered container with a background color, using utility-first SCSS principles with mixins for modularity.
Color variables in SCSS allow you to define reusable colors that can be applied across your stylesheet. This makes it easier to maintain and update your color scheme. You can create a color palette by defining multiple variables for different shades or tones of a color. This approach enhances consistency and makes the code more flexible, allowing you to change colors globally from one central place.
/* Define color variables */
$primary-color: #3498db;
$secondary-color: #2ecc71;
$background-color: #f0f0f0;
/* Apply the color variables */
body {
background-color: $background-color;
color: $primary-color;
}
button {
background-color: $secondary-color;
color: white;
}
body { background-color: #f0f0f0; color: #3498db; } button { background-color: #2ecc71; color: white; }
SCSS provides several built-in color functions, such as lighten
, darken
, and mix
, to manipulate colors dynamically. These functions allow you to adjust the brightness of a color, combine two colors to create a new one, and more. By using these functions, you can create color variations without having to manually define each shade.
/* Define a base color */
$base-color: #3498db;
/* Lighten the base color by 20% */
.lighten-color {
background-color: lighten($base-color, 20%);
}
/* Darken the base color by 20% */
.darken-color {
background-color: darken($base-color, 20%);
}
/* Mix two colors */
$color1: #3498db;
$color2: #2ecc71;
.mixed-color {
background-color: mix($color1, $color2, 50%);
}
.lighten-color { background-color: #5dade2; } .darken-color { background-color: #1d5b8a; } .mixed-color { background-color: #55a8a1; }
SCSS allows you to use maps to organize related values, such as colors, into a structured collection. A map in SCSS is a set of key-value pairs, which you can use to store and retrieve different colors for a theme. Theming with maps makes it easy to manage multiple color schemes or switch between them by simply updating the map values.
/* Define a color map */
$theme-colors: (
primary: #3498db,
secondary: #2ecc71,
background: #f0f0f0
);
/* Access a value from the map */
.button {
background-color: map-get($theme-colors, primary);
color: white;
}
.footer {
background-color: map-get($theme-colors, secondary);
}
.button { background-color: #3498db; color: white; } .footer { background-color: #2ecc71; }
Dynamic themes allow you to change a website's color scheme on the fly. SCSS variables and functions can help achieve this by defining different sets of color variables and switching between them using logic. You can use functions to calculate or modify color values based on user preferences or system settings, enabling a dynamic and responsive user experience.
/* Define default colors */
$light-theme: (
background: #ffffff,
text: #333333
);
$dark-theme: (
background: #333333,
text: #ffffff
);
/* Choose the theme based on a condition (e.g., user preference) */
$theme: if($is-dark-mode, $dark-theme, $light-theme);
/* Apply the dynamic theme */
body {
background-color: map-get($theme, background);
color: map-get($theme, text);
}
body { background-color: #ffffff; color: #333333; }
Variables are a powerful tool in SCSS (Sassy CSS) that allow you to store values for later use. When applied to animations, variables can make your CSS more flexible and easier to manage. You can define variables for animation durations, timing functions, and other properties to reuse across multiple animations, keeping your code DRY (Don’t Repeat Yourself).
<!-- Using variables for animation duration and timing function in SCSS -->Output:
$duration: 2s; // Define the animation duration
$timing-function: ease-in-out; // Define the timing function
.animated-box {
width: 100px;
height: 100px;
background-color: red;
animation: moveBox $duration $timing-function;
}
@keyframes moveBox {
0% { left: 0; }
100% { left: 100px; }
}
Keyframes define the intermediate steps in an animation sequence.
SCSS allows you to create these keyframes with the @keyframes
rule, specifying the changes in CSS properties at different points of the animation.
Keyframes are useful for creating complex animations like sliding, fading, or rotating elements, with precise control over timing and transitions between each state.
<!-- Creating keyframes for a bouncing effect in SCSS -->Output:
.bounce {
animation: bounce 1s infinite; // Apply the bounce animation
}
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-20px); }
100% { transform: translateY(0); }
}
Mixins in SCSS allow you to define reusable chunks of CSS code that can be applied to multiple selectors. When working with animations, mixins are particularly helpful because they allow you to define complex animation properties and reuse them across different elements. Instead of repeating animation code, you can define it in a mixin and simply include it in any class or ID.
<!-- Defining an animation mixin in SCSS -->Output:
@mixin bounceAnimation($duration, $timing) {
animation: bounce $duration $timing;
}
.box1 {
@include bounceAnimation(2s, ease-out); // Apply bounce with custom duration and timing
}
.box2 {
@include bounceAnimation(1.5s, linear); // Apply bounce with different duration and timing
}
@keyframes bounce {
0% { transform: translateY(0); }
50% { transform: translateY(-20px); }
100% { transform: translateY(0); }
}
Timing functions control the speed curve of an animation or transition. In CSS, the transition-timing-function
and animation-timing-function
properties define how intermediate steps are spaced during the animation. Common timing functions include ease
, linear
, ease-in
, and ease-out
, each controlling how the transition occurs over time.
You can also create custom cubic-bezier timing functions for even more control.
<!-- Example of using transition-timing-function in CSS -->Output:
.box {
width: 100px;
height: 100px;
background-color: blue;
transition: transform 2s ease-in-out; // Transition with ease-in-out timing
}
.box:hover {
transform: scale(1.5); // Scale the box when hovered
}
Good file organization is essential for maintaining large SCSS codebases. A common approach is to separate your SCSS into smaller files based on functionality. This makes it easier to find and update specific styles. Group related styles into partials like `_variables.scss`, `_mixins.scss`, `_layout.scss`, and `_components.scss`.
// _variables.scss
$primary-color: blue;
// _buttons.scss
.button {
background-color: $primary-color;
}
// main.scss
@use 'variables';
@use 'buttons';
body {
font-family: Arial, sans-serif;
}
Output:
body { font-family: Arial, sans-serif; } .button { background-color: blue; }
Naming conventions are crucial for keeping your code readable and maintainable. For example, you can use the BEM (Block, Element, Modifier) methodology for class names. Also, it is important to use clear and descriptive names for variables, mixins, and functions, which will make the code easier to understand.
// _variables.scss
$button-padding: 10px 20px;
// _buttons.scss
.btn {
padding: $button-padding;
}
// main.scss
@use 'buttons';
.btn-primary {
background-color: blue;
}
Output:
.btn { padding: 10px 20px; } .btn-primary { background-color: blue; }
Deep nesting can make your SCSS code harder to maintain and may result in overly specific selectors. It's important to keep nesting shallow to avoid complications when overriding styles or modifying elements. Aim to limit nesting to 2 or 3 levels, and consider using mixins and placeholder selectors for reusable components.
// Bad Example - Deep Nesting
.nav {
.nav-item {
.nav-link {
color: red;
}
}
}
// Good Example - Avoiding Deep Nesting
.nav {
display: flex;
}
.nav-item {
margin: 0 10px;
}
.nav-link {
color: red;
}
Output:
.nav { display: flex; } .nav-item { margin: 0 10px; } .nav-link { color: red; }
To avoid repeating yourself, use mixins and functions to encapsulate reusable styles. By creating mixins for commonly used styles, you can maintain DRY (Don’t Repeat Yourself) principles, ensuring that any style changes only need to be made in one place.
// _mixins.scss
@mixin button-style($color) {
padding: 10px 20px;
background-color: $color;
}
// main.scss
@use 'mixins';
.btn-primary {
@include mixins.button-style(blue);
}
.btn-secondary {
@include mixins.button-style(gray);
}
Output:
.btn-primary { padding: 10px 20px; background-color: blue; } .btn-secondary { padding: 10px 20px; background-color: gray; }
Linting tools help enforce code standards and ensure consistency across your SCSS files. By using a SCSS linter like `stylelint`, you can automatically catch errors, enforce naming conventions, and ensure best practices are followed. Code standards make it easier for teams to collaborate and maintain large codebases.
// .stylelintrc.json
{
"extends": "stylelint-config-standard",
"rules": {
"color-hex-case": "lower",
"indentation": 2
}
}
// main.scss
$primary-color: #00ff00;
.button {
color: $primary-color;
padding: 10px 20px;
}
Output:
.button { color: #00ff00; padding: 10px 20px; }
SCSS can be integrated with various build tools like Gulp, Webpack, and Vite to automate tasks like compiling SCSS to CSS, minifying, and adding vendor prefixes. These tools streamline the development process and improve workflow efficiency.
Example of SCSS integration with Gulp:
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
/* Import gulp-sass for compiling SCSS to CSS */
gulp.task('sass', function() {
return gulp.src('src/scss/**/*.scss')
/* Define the source SCSS files */
.pipe(sass().on('error', sass.logError))
/* Compile SCSS to CSS and handle errors */
.pipe(gulp.dest('dist/css'));
/* Output the compiled CSS to the destination folder */
});
gulp.task('default', gulp.series('sass'));
/* Set the default task to run SCSS compilation */
Output: Gulp will compile SCSS files into CSS and place them in the `dist/css` folder.
SCSS can be integrated into various frameworks like React, Angular, and Vue to manage styles more efficiently. This allows for component-level styling and better maintainability of larger applications.
Example of integrating SCSS in React:
// App.js in React
import './App.scss';
/* Import the SCSS file into the React component */
function App() {
return (
Hello, SCSS in React!
);
}
export default App;
// App.scss
.app {
background-color: #f0f0f0;
/* Set background color for the app */
padding: 20px;
/* Add padding inside the app */
}
.app h1 {
color: #333;
/* Set color for h1 inside app */
}
Output: The React component uses SCSS for styling, and styles are applied to the `app` class and `h1` element inside it.
SCSS can be customized with frameworks like Bootstrap and Tailwind. Bootstrap can be customized by overriding its default SCSS variables, while Tailwind can be extended with custom SCSS for more flexible styling.
Example of customizing Bootstrap with SCSS:
// _custom.scss
$primary-color: #007bff;
/* Override Bootstrap's default primary color */
@import 'bootstrap';
/* Import Bootstrap SCSS after overriding variables */
Output: Custom Bootstrap styles will be applied with the overridden primary color.
Example of integrating SCSS with Tailwind:
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
/* Define the source files to watch for Tailwind classes */
theme: {
extend: {
colors: {
customBlue: '#007bff',
/* Add a custom color */
},
},
},
};
// styles.scss
@import 'tailwindcss/base';
/* Import Tailwind's base styles */
@import 'tailwindcss/components';
/* Import Tailwind's components */
@import 'tailwindcss/utilities';
/* Import Tailwind's utilities */
Output: Tailwind classes will be available in the project, and custom SCSS styling is integrated into the Tailwind setup.
Source maps help in debugging SCSS by mapping the compiled CSS back to the original SCSS code. This is especially helpful in large projects where the generated CSS may not directly correspond to the original SCSS structure.
Example of enabling source maps with Gulp:
const gulpSourcemaps = require('gulp-sourcemaps');
/* Import gulp-sourcemaps to enable source maps */
gulp.task('sass', function() {
return gulp.src('src/scss/**/*.scss')
/* Define the source SCSS files */
.pipe(gulpSourcemaps.init())
/* Initialize source maps */
.pipe(sass().on('error', sass.logError))
/* Compile SCSS and handle errors */
.pipe(gulpSourcemaps.write('./maps'))
/* Write the source map to a folder */
.pipe(gulp.dest('dist/css'));
/* Output the compiled CSS to the destination folder */
});
Output: SCSS will be compiled into CSS, and a source map will be created for easier debugging.
Building a responsive navigation bar is a common task in web development. SCSS allows you to use variables, mixins, and media queries to easily create a navigation bar that adjusts its layout based on the screen size. You can use SCSS to manage the structure, responsiveness, and style of the navbar, ensuring it looks good on both desktop and mobile devices.
/* Define a variable for the navbar background color */
$navbar-bg: #333;
/* Base styles for the navigation bar */
.navbar {
background-color: $navbar-bg;
display: flex;
justify-content: space-between;
padding: 10px 20px;
}
/* Style the navbar links */
.navbar a {
color: white;
text-decoration: none;
padding: 10px;
}
/* Make the navbar responsive */
@media (max-width: 768px) {
.navbar {
flex-direction: column;
}
.navbar a {
padding: 15px;
}
}
.navbar { background-color: #333; display: flex; justify-content: space-between; padding: 10px 20px; } .navbar a { color: white; text-decoration: none; padding: 10px; } @media (max-width: 768px) { .navbar { flex-direction: column; } .navbar a { padding: 15px; } }
Theming a dashboard with SCSS involves creating a color scheme that can be easily applied to the entire dashboard. SCSS variables, functions, and maps are useful in organizing color themes and adjusting them dynamically. A typical approach is to define a set of variables for primary, secondary, and background colors, and use these throughout the dashboard’s components to ensure consistency.
/* Define color variables for the dashboard theme */
$primary-color: #3498db;
$secondary-color: #2ecc71;
$background-color: #f0f0f0;
/* Apply colors to the dashboard layout */
.dashboard {
background-color: $background-color;
padding: 20px;
}
.sidebar {
background-color: $primary-color;
width: 250px;
padding: 20px;
color: white;
}
.content {
background-color: white;
padding: 20px;
color: $secondary-color;
}
.dashboard { background-color: #f0f0f0; padding: 20px; } .sidebar { background-color: #3498db; width: 250px; padding: 20px; color: white; } .content { background-color: white; padding: 20px; color: #2ecc71; }
SCSS is great for customizing the look and feel of various UI components. By using SCSS variables and mixins, you can quickly style buttons, input fields, cards, and more. You can also make reusable styles for UI components that are consistent throughout your site. This approach saves time and ensures that your design system is scalable.
/* Define a variable for button color */
$button-bg: #3498db;
/* Create a mixin for button styles */
@mixin button-styles {
background-color: $button-bg;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
/* Apply the mixin to button elements */
button {
@include button-styles;
}
input[type="text"] {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
button { background-color: #3498db; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; } input[type="text"] { padding: 10px; border: 1px solid #ccc; border-radius: 5px; }
A utility SCSS library consists of reusable utility classes that help you quickly style common elements across your web pages. These utility classes can include things like margins, paddings, text alignment, and more. By defining these utilities in SCSS, you can ensure consistency and reduce code repetition in your stylesheets.
/* Utility classes for spacing */
.mt-10 { margin-top: 10px; }
.mb-10 { margin-bottom: 10px; }
.p-20 { padding: 20px; }
/* Utility classes for text alignment */
.text-center { text-align: center; }
.text-right { text-align: right; }
/* Apply utility classes to elements */
Hello World
.mt-10 { margin-top: 10px; } .mb-10 { margin-bottom: 10px; } .p-20 { padding: 20px; } .text-center { text-align: center; }
A full SCSS-based design system is a comprehensive collection of styles, components, and guidelines that dictate the design of a website or application. SCSS variables, mixins, and functions play a central role in building such systems. By defining reusable components, colors, and layout styles in SCSS, you can ensure that your design system is flexible, maintainable, and scalable.
/* Define design system variables */
$primary-color: #3498db;
$secondary-color: #2ecc71;
$font-family: 'Arial', sans-serif;
/* Define reusable button component */
.button {
background-color: $primary-color;
color: white;
padding: 10px 20px;
border-radius: 5px;
font-family: $font-family;
}
/* Define card component */
.card {
background-color: white;
border: 1px solid #ddd;
border-radius: 10px;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.button { background-color: #3498db; color: white; padding: 10px 20px; border-radius: 5px; font-family: 'Arial', sans-serif; } .card { background-color: white; border: 1px solid #ddd; border-radius: 10px; padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
Dynamic component styling in SCSS allows you to create flexible, reusable styles that change based on conditions, such as media queries or input from JavaScript. This enables you to build components that adapt dynamically, responding to different states or screen sizes. By using variables, mixins, and functions, SCSS makes it easy to write styles that react to changes in data or context.
<!-- Dynamic component styling using SCSS variables and mixins -->Output:
$primary-color: blue; // Define primary color variable
$dark-mode: true; // Toggle dark mode
@mixin button($bg-color) {
background-color: $bg-color;
color: white;
padding: 10px 15px;
border-radius: 5px;
}
.button {
@if $dark-mode {
@include button(darkblue); // Apply dark color for dark mode
} @else {
@include button($primary-color); // Apply primary color for light mode
}
}
SCSS functions and nested maps allow for more complex and reusable logic in your styles. Functions enable you to perform calculations or manipulate values dynamically, while nested maps provide a way to store and access structured data. These features can be particularly useful when managing design systems or working with complex styling rules that need to adapt to various conditions.
<!-- Using SCSS functions and nested maps -->Output:
$colors: (
primary: #3498db, // Define primary color
secondary: #2ecc71, // Define secondary color
accent: #e74c3c // Define accent color
);
@function get-color($key) {
@return map-get($colors, $key); // Retrieve color from the map
}
.header {
background-color: get-color(primary); // Use function to get primary color
}
.footer {
background-color: get-color(secondary); // Use function to get secondary color
}
Writing SCSS plugins involves creating reusable functions, mixins, or helpers that extend the functionality of SCSS, making it easier to write modular and scalable styles. Plugins can be packaged into separate files or libraries, which can be shared across multiple projects. SCSS plugins can simplify complex tasks, such as grid systems, responsive utilities, or custom calculations.
<!-- Example of creating an SCSS plugin to center elements -->Output:
@mixin center($width, $height) {
display: flex;
justify-content: center;
align-items: center;
width: $width;
height: $height;
}
.container {
@include center(100%, 100vh); // Use mixin to center the container on the page
}
Performance optimization in SCSS helps ensure that your stylesheets are efficient and fast to load. This can be achieved by reducing the use of deeply nested selectors, minimizing the number of unnecessary mixins or functions, and taking advantage of features like `@use` and `@forward` to optimize imports and avoid redundant code. Optimizing SCSS can result in smaller, faster-loading CSS files, which is especially important for performance-sensitive websites or apps.
<!-- Performance optimization in SCSS -->Output:
// Use @use instead of @import to load partials for better performance
@use 'base/variables'; // Import variables once
@use 'base/mixins'; // Import mixins once
.card {
@include border-radius(10px); // Use mixin to add border radius
background-color: $background-color; // Use variable for background color
}
Modern Sass modules, introduced with the `@use` and `@forward` directives, allow you to organize your SCSS code into modular, maintainable files. These features improve code reusability and make it easier to manage large codebases. By using modules, you can avoid global namespace pollution and ensure that your SCSS is compatible with future Sass versions, improving maintainability and reducing conflicts between different styles.
<!-- Using modern Sass modules -->Output:
// _variables.scss
$primary-color: #3498db;
// _mixins.scss
@mixin border-radius($radius) {
border-radius: $radius;
}
// main.scss
@use 'variables'; // Import variables as a module
@use 'mixins'; // Import mixins as a module
.button {
background-color: variables.$primary-color; // Access module variable
@include mixins.border-radius(5px); // Use mixin from module
}