SASS
Table of Contents
Syntax
Wrap variables in calc functions
The variable \$app-variable-width should be enclosed in curly braces {} to be evaluated properly. Here's the corrected line of code:
max-width: calc(#{\$app-variable-width} - 50px);
By wrapping the variable in #{}, it will be interpolated within the calc() function, and its value will be correctly substituted.
However, it's worth noting that SCSS is a preprocessor that compiles into CSS. The issue you're experiencing might not be related to the SCSS syntax itself, but rather to the generated CSS or how it's being used in your HTML. Additionally, browser compatibility issues can sometimes arise due to the usage of certain CSS features that are not supported in older versions of browsers.
If the corrected code still doesn't work in Chrome, please provide more context or any error messages you're encountering so that I can assist you further.
the difference between mixins and extends
Mixins allow for the reuse of blocks of code, while extends allow for the inheritance of styles from one selector to another.
Import
SCSS allow you to import other SCSS stylesheet into a SCSS file using @import
@import "button.scss" or @import "button"
Partials
Partials are SCSS files you don't what to be compiled to CSS but you want to import them(using @import) into another file. To create a partial you just need to add an underscore to the beginning of the file name _font.scss, then you can import them with or without the underscore.
Partials helps to modularize your code and separate concerns.
For example in my projects I partials for colors, fonts, buttons e.t.c then I import them into a main.scss file.
/* _colors.scss(partial) */
\$light-gray: #F2F2F2
\$dark-gray: #737373
/*EOF colors.scss*/
/* _buttons.scss(partial) */
.button-primary{
color: #4c7396;
background-color: #ffffff;
}
.button-secondary{
background: #4c7396;
color: #FFFFFF;
}
/*EOF buttons.scss*/
/* main.scss */
@import "_buttons.scss"
@import "_colors.scss"
Operators
Scss offers you different kind of operators that you can use in your CSS. Arithmetic operators like :
- Addition(+)- Subtraction(-)- Division(/)- Multiplication(*) e.t.c
@mixin top-margin (\$margin){
margin-top: 30px + \$margin;
}
.container{
width: 800px - 80px;
@include top-margin(10px);
}
//Compiled CSS
.container {
width: 720px;
margin-top: 40px;
}
Note that arithmetic operators only work when both values use the same unit i.e rem, em, px
They also support comparison operators like ==, !=, <, >, >=, <= and logical operators and, or, not.
You can check out this article for more on Operators
Color Functions
Scss provides some function that can be used to manipulate colors. Some of them include:
- mix($colorX, $colorY, weight) : This function is used to mix two color together. First argument is the first color, second is the second color and the third argument is the percentage of first color you want to mix.
mix(blue, grey, 30%) /*results 30% blue and 70% grey*/
- lighten($color, $amount): this function is used to return a lighter color. The first argument is the color and the second is the percentage of how much you want to lighten it.
lighten(#ff0000, 30 ) /*results #ff9999/*
- darken($color, $amount): Takes similar arguments as lighten function but this returns a darker color specified.
darken(#ff0000, 30 ) /*results #660000*/
-
opacify(\$color, \$amount): This function returns a color with the opacity increase. The first argument is the color and the second is value between 0 and 1.transparentize(\$color, \$amount): This function makes a color more transparent, it takes similar arguments to opacify. It returns a color with the opacity reduced. You can say it is the opposite of opacify.
These are just some of the color functions available in Scss, you can check the docs for more.
Other functions
Scss still offers other functions that might be useful to you
str-length(\$string): This function returns the number of characters in a string.percentage(\$number): This function converts number without unit to a percentage.round(\$number): This function rounds a number to the nearest whole number.min(\$number1, \$number2, \$number3, .....): this function returns the minimum value from a set of numbers.random(): This returns a random number and takes no arguments.quote(\$string): This function adds quotes to a string.unquote(\$string): This function removes quotes from a string.to-lower-case(\$string): This function converts a string to lowercase.to-upper-case(\$string): This function converts a string to uppercase.
Loops
We can use for loops in our css thanks again to Scss. This can be really useful in creating utility class. You can create classes for your color, font-size , margin , padding and a lot of other properties.
Below are some examples of loops I used to create utility classes in my projects
/* Generate utility classes for font-size */
@for \$x from 1 through 70 {
.font-size-#{\$x} {
font-size: 0px + \$x;
}
}
So I can easily have a class of font-size-20 if I need that on an element.
/* Generate utility classes for margin */
@for \$i from 0 through 500 {
.m#{\$i} {
margin: 0px + \$i;
}
.mt#{\$i} {
margin-top: 0px + \$i;
}
.mb#{\$i} {
margin-bottom: 0px + \$i;
}
.ml#{\$i} {
margin-left: 0px + \$i;
}
.mr#{\$i} {
margin-right: 0px + \$i;
}
}
If you have used loops to create utility classes in your projects please share in the comments so others can adopt them. Loops are like my favorite scss feature
Conditionals
Another awesome feature of scss is the ability to use If/else statements in css. I have not really used this feature in any of my projects but I think they are awesome.
\$bg: pink;
\$bg-mobile: red;
p {
@if \$bg == pink {
color: blue;
} @else if \$bg-mobile == red {
color: green;
} @else {
color: grey;
}
}
This is just a simple use case for if else statements, if you have used it in a project please share a code snippet in the comment.
Scss has a lot more features than what is covered in this article but these are the commonly used ones. You can check out their docs.
media queries
\$large-screen: 1000px;
\$med-screen: 700px;
\$small-screen: 400px;
\$ht:300px
div {
@media screen and (min-width: \$med-screen) {
}
@media screen and (max-width: \$med-screen) {
@media screen and (
inheritance
- nested rules
@import
-
to include the variables, mixing, etc. of another .scss stylesheet
-
@extend
@function
SCSS @function is a directive in the SCSS (Sass) preprocessor that allows you to define a custom function in your stylesheet. Functions are used to perform calculations, manipulate values, and generate dynamic content. They can be called from within other styles, just like built-in functions such as rgb() or calc().
The syntax for defining a function is as follows:
@function function-name(\$parameter1, \$parameter2, ...) {
// Function body
@return value;
}
Here, function-name is the name of your function, and \$parameter1, \$parameter2, etc. are the parameters that your function takes. The function body contains the code that performs the desired operation, and the @return directive is used to return a value from the function.
For example, the following function takes two parameters and returns their sum:
@function add(\$a, \$b) {
@return \$a + \$b;
}
// Usage
.element {
width: add(10px, 20px);
}
In this example, the .element selector has a width property that is set to the value returned by the add() function, which is 30px.
Functions can also be used to generate dynamic content, such as generating CSS class names based on input parameters, or generating gradients with varying colors. The possibilities are endless, and the flexibility of SCSS functions allows you to create powerful and reusable styles in your projects.
- @if @where @for
- @keyframes
Nested Rules / Nested Definitions
ul {
list-style-type: none;
li {
display: inline;
a {
}
AND
& (ampersand)
- special indicator to refer to the parent of the selector
What is the difference between Mixins and Extends in SASS?
Mixins and extends are both powerful features in Sass for creating code reuse and reducing duplication. However, they work in different ways and have different use cases.
Mixins are used to define a set of styles that can be reused throughout a stylesheet. Mixins are similar to functions in programming, as they take arguments and can be called with different values. Mixins are defined using the @mixin directive and can be included in other selectors using the @include directive. Mixins allow you to reuse a block of code with different values, making them very flexible and powerful.
Extends, on the other hand, are used to inherit styles from one selector to another. When you extend a selector, the styles are copied from the original selector to the new selector, effectively creating a new class that inherits the styles of the original. Extends are defined using the @extend directive and can be used to create a class that inherits the styles of another class. Extends are a powerful tool for creating reusable styles, but they can also create complex and hard-to-maintain code if overused.
Here are some key differences between mixins and extends in Sass:
-
Arguments: Mixins can take arguments, while extends cannot. This makes mixins more flexible and powerful for creating reusable styles with different values.
-
Code Reuse: Mixins are used for code reuse, while extends are used for inheritance. Mixins allow you to reuse a block of code with different values, while extends allow you to inherit styles from one selector to another.
-
Performance: Mixins can sometimes result in redundant code, while extends can result in more efficient code. When you use a mixin, the styles are copied into the new selector, which can result in redundant code. When you use an extend, the styles are shared between the original and new selectors, resulting in more efficient code.
-
Maintainability: Mixins can be easier to maintain than extends. When you use a mixin, the styles are contained within the mixin, making it easier to modify or update the styles. When you use an extend, the styles are spread across multiple selectors, making it harder to modify or update the styles.
In general, mixins are best for creating reusable blocks of code with different values, while extends are best for creating classes that inherit styles from other classes. However, the choice between mixins and extends ultimately depends on the specific use case and the nature of the code being written.
@extend
The @extend directive in SCSS is a powerful feature that allows one selector to inherit the styles of another selector. This is particularly useful for reducing CSS redundancy and keeping your stylesheets DRY (Don't Repeat Yourself). By using @extend, you can share a set of CSS properties from one selector to another, making your styles more maintainable and easier to update.
Basic Usage
To use @extend, simply include the directive within a selector block, followed by the selector you wish to inherit from. For example:
.button {
padding: 10px 15px;
border: none;
background-color: blue;
color: white;
font-size: 16px;
}
.button-secondary {
@extend .button;
background-color: green;
}
Variable
- sassScript variables begin with $ sign
//numbers
\$margin: 0;
// colors
\$bg-color: #ccc;
\$color-primary: hsl(220, 90%, 56%);
//strings
\$my-text: "hello, Sass!";
//boolean
\$flag:true;
.link {
color: \$color-primary;
}
.some-text:after {
content: \$my-text;
@if \$flag { color: #f00; }
}
\$color-primary: blue;
\$color-text: black;
\$color-bg: white;
/* invert */
\$color-primary-invert: red;
\$color-text-invert: white;
\$color-bg-invert: black;
.component {
color: \$color-text;
background-color: \$color-bg;
a {
color: \$color-primary;
}
}
.component--dark {
color: \$color-text-invert;
background-color: \$color-bg-invert;
a {
color: \$color-primary-invert;
}
}
Nested properties
p {
font: {
family:
size:
weight:
}
}
Control Directives
\$dark-grey: #222;
\$grey: #ccc;
\$red: #f00;
\$type: success;
.p-if {
background-color: \$grey;
@if \$type == info {
color: \$grey;
}
@for \$1 from 1 through 3 {
.li#{\$i} { font-size: #{* * \$i}px; }|
}
@each \$c in "red", "green", "blue", "purple" {
.color-#{\$c} { color: \$c };
\$i: 4;
@mixin
@includes are a part of SCSS, it's called Mixin. In Sass, a mixin is a group of CSS declarations that can be reused throughout the style sheet. It allows you to have a Function inside your Stylesheet.
- has parameters
Newer CSS features take time before they are fully adopted and ready to use in all browsers. As features are added to browsers, CSS rules using them may need vendor prefixes.
- Looping mixins
- Mixin guards
@mixin border-radius(\$radius) {
-webkit-border-radius: \$radius;
-moz-border-radius: \$radius;
-ms-border-radius: \$radius;
border-radius: \$radius;
}
@mixin my-rounded-border {
border-radius: 10px
}
to use it in your element(s), you should use @include followed by your Mixin name, as following:
.box {
@include border-radius(10px);
@include centered-text;
}
@includes are a shortcut to storing especially things like vendor prefixes. The CSS output of the above will be:
.box {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}
when to choose between classes or scss mixins for shared functionality
Choosing between classes and SCSS mixins for shared functionality depends on the specific use case and the nature of the shared functionality. In general, if the shared functionality is relatively simple and only needs to be applied to a few elements, classes may be a better choice. If the shared functionality is complex and needs to be reused across multiple elements or components, or if it needs to be customizable, mixins may be a better choice.
To elaborate further, classes and mixins are both powerful features of SCSS that allow you to reuse code and avoid repetition in your stylesheets. Classes are used to define a set of styles that can be applied to one or more HTML elements. Mixins, on the other hand, are reusable blocks of code that can be called within other SCSS rules or selectors.
Classes are useful when you want to apply a set of styles to multiple elements, or when you want to group elements with similar styles together. For example, you might have a class called "button" that defines the styles for all buttons on your site. You can then apply the "button" class to any button element on your site to give it the same styles.
Mixins, on the other hand, are useful when you want to reuse a block of code in multiple places, but you don't want to create a new class for each use. Mixins can take arguments, which makes them more flexible than classes. For example, you might have a mixin that defines the styles for a button with a specific color. You can then call that mixin with different arguments to create buttons with different colors.
In general, classes are best for defining styles that will be applied to multiple elements, while mixins are best for creating reusable blocks of code that can be customized for different uses. However, the choice between classes and mixins ultimately depends on the specific use case and the nature of the shared functionality.
-
Reusability: If the shared functionality is going to be reused across multiple elements or components, mixins can be more efficient since they can be included in multiple selectors, reducing duplication. Classes, on the other hand, can be applied to multiple elements but require the class to be added to each element.
-
Complexity: Mixins are useful when the shared functionality is complex and requires multiple lines of code. Using a mixin can help keep the code DRY and make it easier to maintain.
-
Customizability: If the shared functionality needs to be customizable, mixins are a better choice than classes. Mixins can take arguments and parameters, allowing for more flexibility in customization.
-
Scope: If the shared functionality is only needed within a specific scope, such as a single component, it may be better to use a class rather than a mixin. This can help keep the code more organized and easier to understand.
Sass Structure
sass/
|
|- abstracts/
| |- _mixins // Sass Mixins Folder
| |- _variables.scss // Sass Variables
|
|- core/
| |- _reset.scss // Reset
| |- _typography.scss // Typography Rules
|
|- components/
| |- _buttons.scss // Buttons
| |- _carousel.scss // Carousel
| |- _slider.scss // Slider
|
|- layout/
| |- _navigation.scss // Navigation
| |- _header.scss // Header
| |- _footer.scss // Footer
| |- _sidebar.scss // Sidebar
| |- _grid.scss // Grid
|
|- pages/
| |- _home.scss // Home styles
| |- _about.scss // About styles
|
|- sections/ (or blocks/)
| |- _hero.scss // Hero section
| |- _cta.scss // CTA section
|
|- vendors/ (if needed)
| |- _bootstrap.scss // Bootstrap
|
- app.scss // Main Sass file
In the Abstract partial, there is a file with all the variables, mixins, and similar components.
The Core partial contains files like typography, resets, and boilerplate code, used across the whole website. Once you write this code, there is no further overwriting.
The Components partial contains styles for all components that are to be created for one website, including buttons, carousels, tabs, modals, and the like.
The Layout partial has all styles necessary for the layout of the site, i.e., header, footer.
The Pages partial contains the styles for every individual page. Almost every page needs to have specific styles that are to be used only for that particular page.
For every section to be reusable and the sass code to be easily accessible, there is the Section/Blocks partial. Also, it is important to have this partial so that you don’t need to search whether particular code is in the home.sass or about.sass files in the Pages partial.
It is a good idea to put each section in a separate .sass file. Thus, if you have two different hero sections, put the code in the same file to know that there you can find the code for the two sections. And if you follow this pattern, you will have the majority of files in this folder.
The Vendors partial is intended for bootstrap frameworks so, if you use one in your project, create this partial.
I recommend you use app.sass as the main folder. Here is how it should look:
// Abstract files
@import "abscracts/all";
// Vendor Files
@import "vendor/bootstrap.scss";
// Core files
@import "core/all";
// Components
@import "components/all";
// Layout
@import "layout/all";
// Sections
@import "sections/all";
// Pages
@import "pages/all";