CSS preprocessors: Sass or Less – Which to choose?
CSS preprocessors can help write more maintainable CSS code. Especially when working with larger codebases. In this article, Sarah compares Sass and Less, two of the most popular choices.
Table of contents
Styling web pages with Cascading Style Sheets (CSS) can become challenging to maintain as the stylesheet expands. CSS preprocessors offer solutions for easier maintenance and dynamic styling without relying on JavaScript.
In this article, we'll examine key differences between two prominent CSS preprocessors, Sass and Less, covering aspects such as syntax, features, and learning curve to determine which of the two preprocessors is the best to choose for your projects.
What are CSS preprocessors?
CSS preprocessors are tools that extend the capabilities of standard CSS by introducing features such as variables, functions, mixins, nesting, and more.
The static nature of conventional CSS lacked effective mechanisms for managing code repetition and dynamic styling throughout complex stylesheets, posing maintenance challenges for developers. This brought about the advent of preprocessors, which promote improved code organization, reusability, and easier maintenance of CSS code.
The source code is compiled into standard CSS before the browser interprets and applies the styles.
Overview of Sass
Sass (Syntactically Awesome Style Sheets) is a scripting language and a superset of CSS. It was designed by Hampton Catlin and developed by Natalie Weizenbaum in 2006. Sass appends additional functionalities and capabilities to CSS.
Syntax
The Sass syntax makes use of an indentation code style. It eliminates the need for curly braces to group style declarations, uses semicolons as an end-of-statement indicator, and uses a line break instead.
selector property: value property: value
Configuration
The following command installs Sass as a global dependency for your project:
npm install -g sass
All Sass files must have the .sass
file extension.
Compile a Sass file into regular CSS:
sass input_file.sass output_file.css
To automatically compile your Sass code, set the watch flag.
sass --watch input_file.sass output_file.css
This compiles the watched Sass file whenever changes are saved.
Sass features
Variables
Allows you to store and reuse values throughout your stylesheet. A Sass variable is declared with the $
sign followed by a variable name and a value.
$primary-color: #4caf50 $regular-text: 16px
To use of a declared variable:
.card background-color: $primary-color font-size: $regular-text
Compiles to:
.card { background-color: #4caf50; font-size: 16px; }
Mixins
Creates a group of reusable styles throughout your site. A Sass mixin is declared using the @
symbol followed by the mixin keyword and an identifier.
@mixin identifier property: value property: value
The mixin syntax also allows for arguments to create a more dynamic and reusable style declaration.
@mixin bg-image($url) background-image: url($url) background-repeat: no-repeat background-cover: cover
To reuse this mixin in another part of your code, reference its identifier with the @include
rule.
.card @include bg-image("link-to-image")
Compiles to:
.card { background-image: url("link-to-image"); background-repeat: no-repeat; background-cover: cover; }
Nesting
Sass allows selector nesting, making it easier for developers to follow the visual hierarchy of the HTML element to apply styling.
<header> <image src="" class="logo" /> </header>
/* Sass code */ header width: 100vw .logo object-fit: contain
Compiles to:
/* CSS code */ header { width: 100vw; } header .logo { object-fit: contain; }
Functions
Allows the creation of dynamic styles. A function is declared using the @function
rule, a function identifier, and an optional parameter. The @return
keyword returns values from the function.
@function calculateTotalWidth($width, $padding) @return $width + 2 * $padding
Call the function with its identifier and arguments as the value of a valid property.
$boxWidth: 200px $boxPadding: 10px .card padding: $boxPadding width: calculateTotalWidth($boxWidth, $boxPadding)
Compiles to:
.card { padding: 10px; width: 220px; }
if and else
These conditional statements let you define styles only when certain conditions are met.
@mixin content-style( $content-width ) width: $content-width @if $content-width > 200px border: 4px solid red @else border:2px solid green /* Use mixin */ .card @include content-style(300px)
Compiles to:
.card {
width: 300px;
border: 2px solid red;
}
The code above utilizes the if
and else
statements to make changes to the border according to the width of the content it is applied to.
Import
Sass employs the @import
rule to include files in a stylesheet. This rule should be placed at the top of the file before any other declaration. When importing a Sass file, you can omit the .sass
extension as Sass recognizes the file without it.
@import "./filename"
Note that Sass has actively been phasing out the @import
rule as it allows for global accessibility of all variables, functions, and mixins in the code base, making it difficult for developers to figure out where precisely they are defined. Using the @use
rule to load specific rules is recommended rather than loading the entire stylesheet.
@use "path/filename"
Importing a file with the @use
rule establishes a namespace for the imported file, requiring each mixin or function to be referenced with the namespace.
/* _cards.sass file */ @mixin background background-color: blue @mixin border border: 2px solid #000
Import styles in another file:
@use "./_cards" .postCard @include cards.background @include border /* throws an error: border was not referenced by the cards namespace. */
You can also import an entire stylesheet using @use
with the as
keyword and *
symbol.
@use "./card" as * .postCard @include border @include background
Sass offers many more features than what is listed here. The complete list can be found in the official Sass features documentation.
SCSS variant of Sass
Sass has two syntaxes: the original "indented syntax," using indentation and newlines, and the newer Sassy CSS (SCSS) syntax with curly braces and semicolons. The latter closely resembles standard CSS but still offers all the same additional features traditional Sass has to offer. It was introduced in version 3.0 of Sass in May 2010.
File extensions are .sass
for indented syntax and .scss
for block syntax. The .scss
syntax is widely adopted among developers due to the syntax similarity with standard CSS. You can write code with an SCSS-style declaration as follows:
selector { property: value; property: value; }
SCSS code is compiled similarly to regular Sass.
sass input_file.scss output_file.css
Overview of Less
Less (Leaner Style Sheets) is a CSS preprocessor similar to Sass, written in JavaScript, and extends the possibilities of CSS. It was developed by Alexis Sellier and introduced in 2009 after the release of Sass. It was created to solve the indentation syntax issue with Sass, which many developers found unintuitive.
Syntax
Less adopts a similar syntax to that of standard CSS.
selector { property: value; property: value; }
Configuration
Less uses the .less
file extension and compiles with JavaScript.
Install Less globally in your development environment:
npm install less -g
Compile a Less file into CSS:
lessc styles.less styles.css
Less also supports real-time compilation via Less.js. This means it could also be used directly in the browser by pointing a script tag to the Less CDN and linking your Less stylesheet directly to your HTML document.
<link rel="stylesheet/less" type="text/css" href="styles.less" /> <script src="https://cdn.jsdelivr.net/npm/Less" ></script>
Ultimately, a Less CDN is not recommended for use in production code as it could introduce dependency issues to the project. But it's still a viable option to get started with Less easily, especially for beginners who are still new to the command line.
Less features
Variables
The @
symbol is used to declare a variable in Less.
@base-color: #336699; @border-radius: 5px; .button { background-color: @base-color; border-radius: @border-radius; }
A variable name can also be used as the value for another variable.
@light: #fff; @dark: #222; .section { @bg-color: @light; .card { background-color: @bg-color; } }
Compiles to:
.section .card { background-color: #fff; }
Mixins
Enables the reuse of sets of properties or rules. The Less mixin syntax resembles CSS class and ID selectors, only distinguished by the parentheses required when calling it.
/* Declare mixins */ .rounded-corners { border-radius: 10px; } #card-border { border: 2px solid green; } /* Use mixins */ header { #card-border(); .rounded-corners(); }
Compiles to:
header { border: 2px solid green; border-radius: 10px; }
Imports
Uses the @import
rule to include files in a stylesheet. While Less allows the @import
statements to be placed anywhere, it's recommended to position them at the beginning of the stylesheet for clarity on imported content.
@import "filename";
If a file extension is not specified, it imports separate files as a Less file.
Nesting
Provides a way to nest selectors, enhancing readability and reducing code repetition.
#container { width: 100%; .item { color: #333; } }
Operations
Supports mathematical operations ( +
, -
, *
, /
) for numerical values, facilitating dynamic styling.
@base-padding: 10px; @additional-padding: 5px; #box { padding: @base-padding + @additional-padding; }
Compiles to:
#box { padding: 15px; }
Functions
Less offers a variety of built-in functions for list manipulation, string manipulation, math equations, and more.
@list: "Home", "About", "contact"; .nav-section { height: 30px * length(@list); }
Compiles to:
.nav-section { height: 90px; }
Properties as variables
Allows you to treat standard CSS properties as variables.
.card { color: #efefef; border: 2px solid $color; }
Compiles to:
.card { color: #efefef; border: 2px solid #efefef; }
Color operation functions
Provides functions like lighten()
and darken()
for color manipulation.
@base-color: #336699; @lighter-color: lighten(@base-color, 20%); @darker-color: darken(@base-color, 10%); #header { background-color: @lighter-color; border-bottom: 1px solid @darker-color; }
The complete Less Features list can be found in the official Less Features documentation.
Differences and similarities between Sass and Less
The syntax and features of Sass and Less are quite similar in terms of their fundamental purpose as CSS preprocessors. However, they diverge in certain aspects.
Differences
Sass
-
Adopts an indentation code style without the use of semicolons.
-
Compiles to CSS using the Dart Sass compiler.
-
Utilizes the
$
symbol for variable creation. -
Mixins are defined using the
@mixin
keyword. -
Has a broader feature set and allows more customization control.
-
Allows dynamic function creation.
Less
-
Uses curly braces and semicolons to define a code block.
-
Can be compiled in both the node.js environment and directly in the browser.
-
Uses the
@
symbol for variable creation. -
Uses the class or ID selector to define a mixin.
-
Maintains simplicity with a smaller set of features.
-
Uses a set of predefined functions
Similarities
-
Import: Sass and Less adopt the same
@import
syntax to import files. -
Variables: Both Sass and Less allow the definition and use of variables, promoting consistency and ease of maintenance.
-
Nesting: Both preprocessors support nested styling rules, facilitating a hierarchical structure that mirrors the HTML document's hierarchy.
-
Mixins: Sass and Less offer mixin functionality, enabling the reuse of style patterns across the stylesheet.
Learning curve and developer familiarity
Sass
Due to its extensive feature set, Sass has a slightly steeper learning curve.
Sass benefits from comprehensive and well-maintained documentation. The official Sass documentation provides in-depth explanations, examples, and references, making it a valuable resource for beginners and experienced developers.
The documentation often includes version-specific guides, ensuring users have relevant information based on the Sass version they are working with. This is crucial for developers to navigate changes and updates.
The Sass community actively contributes to documentation, expanding on topics and providing additional insights. This collaborative effort enhances the overall quality and coverage of Sass documentation.
The Sass preprocessor is actively maintained on GitHub as an open-source project with over 14.5k GitHub stars and over 25 contributors as of the time of writing this article.
Less
Less learning curve is generally considered smoother than Sass, making it easier for developers to transition from traditional CSS. The syntax is similar to CSS, contributing to a faster learning and development process for those already comfortable with standard stylesheets.
Less also provides direct in-browser compilation via the Less CDN, simplifying preprocessor usage for developers without configuration hassles.
Less offers documentation that covers its features and usage. While not as extensive as Sass's documentation, it provides sufficient guidance for users to understand and implement Less in their projects.
Less documentation includes learning resources, examples, and explanations. The maintenance and updates to Less documentation have been consistent, but the pace might not match the frequency seen in Sass documentation.
The Less preprocessor, like Sass, is still actively maintained on Github, with over 17k GitHub stars and over 240 contributors as of the time this article was written.
Performance and scalability comparison
Compilation speed
Sass
The Sass compiler was initially written in the Ruby programming language and was known as 'Ruby Sass.' It has since been deprecated, and the Sass team has introduced Dart Sass as the official compiler for Sass projects.
Dart Sass has become the recent implementation of Sass, providing better performance and feature compatibility.
Sass code:
/* test-file.sass */ $bg-color: #ccf $border-radius: 10px @mixin card-styles background-color: $bg-color border-radius: $border-radius /* Example usage */ .card @include card-styles
Compiling the Sass code:
sass test-file.sass test-sass-file.css
Sass compile time:
Less
Less compilation speed is generally faster than Sass due to its lightweight feature set. The Less compiler (lessc) is a javascript compiler that processes Less code into CSS.
The exact performance can depend on the Less compiler and the specific features employed in the stylesheets.
To test the compilation time of both preprocessors, we have a simple test application with the same code written in both Sass and Less.
Less code:
/* test-file.less */ @bg-color: #ccf; @border-radius: 10px; .card-styles() { background-color: @bg-color; border-radius: @border-radius; } /* Example usage */ .card { .card-styles(); }
Compiling the Less code:
lessc test-file.less test-less-file.css
Less compile time:
As we can see, the Sass code takes more time to compile than Less.
Sass is essentially known for its slower compile speed compared to Less. This is due to its extensive feature set. It efficiently processes Sass or SCSS files into CSS, and the speed is often influenced by factors such as file size and complexity.
Scalability
Sass
Sass is highly flexible and adaptable for larger projects. It supports many features and control directives, allowing developers to modularize and organize their code effectively.
Sass's support for partials and imports aids in code organization. Using variables and mixins further enhances scalability by promoting more reusable code snippets and maintainable styles.
Less
Less provides flexibility for larger projects but may not have the same extensive feature set as Sass. It supports variables and mixins, contributing to scalability, but developers might find Sass more feature-rich for complex scenarios.
Similar to Sass, Less encourages code organization. However, the extent of code organization might depend on the project's specific requirements.
Compatibility with existing tools and libraries
Sass and Less officially supports several tools and libraries. In this section, we will cover the compatibility of both preprocessors with build tools such as Vite, Bootstrap Library, and the React framework.
Build tools
Sass
Sass integrates with build tools such as Vite, a next-generation build tool for modern web development. Vite natively supports both Sass and SCSS, allowing developers to easily incorporate Sass stylesheets into their Vite projects. This integration ensures a smooth development process and workflow for developers using Sass in Vite projects.
Less
Less is compatible with Vite, and developers can use Less stylesheets within a Vite-powered project. Vite's ability to handle various stylesheet languages, including Less, makes it flexible for developers who might prefer Less over Sass.
Front-end libraries and frameworks - Bootstrap
Sass
Sass has a strong integration history with Bootstrap, which switched to Sass as its main preprocessor starting from the release of Bootstrap version 4. The Bootstrap library allows developers to customize and extend Bootstrap styles using Sass variables and features. This also contributed to developers' wide use of Sass as a preprocessor.
Less
Bootstrap has traditionally used Less as its preprocessor in versions 2 and 3. Developers who prefer Less can leverage the Bootstrap original Less with source code and files provided for customization.
Front-end libraries and frameworks - React
Sass
Sass can seamlessly integrate into React projects. Whether using Create React App or a custom setup, incorporating Sass in React applications is straightforward. Modularizing styles with Sass aligns well with React's component-based architecture.
Install Sass as a dependency for your React application:
npm install sass --save-dev
Verify the installation by checking the devDependencies property in your package.json
file:
"devDependencies": { "sass": "<version number>" }
Import a Sass file into a React component with the import keyword:
import "./filename.sass
When importing a Sass file into a React component, the .sass
file extension must be present, as React requires this to recognize the file, unlike when importing into another Sass file.
Less
Similar to Sass, Less can be used in React projects. It follows the same integration pattern as that of Sass. Less stylesheets can be incorporated into React applications without significant challenges, making it a viable choice for developers working with Less and React.
Install less as a dependency for your React application:
npm install less --save-dev
Ensure the devDependencies property in your package.json
file contains the following:
"devDependencies": { "less": "<version number>" }
Import a less file into a React component:
import "./filename.less"
After following these steps, you can use either Sass or Less in your React application, showcasing the compatibility of both preprocessors with React applications.
Conclusion
In summary, CSS preprocessors like Sass and Less offer notable advantages compared to standard CSS. They are similar tools that do a similar job.
After reviewing the factors outlined in this guide, it is safe to say that choosing between Sass and Less ultimately depends on the project requirements and developer preferences, as both are viable options for additional functionalities when styling web pages.
I hope this guide helps you confidently select the right CSS preprocessor for your next project. Feel free to experiment with Sass and Less on Frontend Mentor projects to determine which preprocessor suits your web development workflow.
References and further reading
-
An Empirical Study on the Use of CSS Preprocessors - Davood Mazinanian, Nikolaos Tsantalis
-
The Complete Guide to Sass (Syntactically Awesome Stylesheets) Programming Language - Livecoding.tv
-
Sass Documentation - Official Sass website
-
Less Documentation - Official Less website
-
CSS preprocessors - MDN web docs
Practice building projects like a pro
- Portfolio-ready projects
- Professional design files
- Curate your profile
- Unlimited solution refinement