Skip to content

Instantly share code, notes, and snippets.

@chriseppstein
Created November 12, 2010 21:35
Star You must be signed in to star a gist
Save chriseppstein/674726 to your computer and use it in GitHub Desktop.

Sass/Less Comparison

In this document I am using Sass's SCSS syntax. You can choose to use the indented syntax in sass, if you prefer it, it has no functional differences from the SCSS syntax.

For Less, I'm using the JavaScript version because this is what they suggest on the website. The ruby version may be different.

Variables

Sass             | Less
-----------------+-----------------
$color: red;     | @color: red;
div {            | div {
  color: $color; |   color: @color;
}                | }

Both languages support scoped variable definition within a selector context. However they differ in their behavior:

Sass                     | Less
-------------------------+-----------------
$color: black;           | @color: black;
.scoped {                | .scoped {
  $bg: blue;             |   @bg: blue;
  $color: white;         |   @color: white;
  color: $color;         |   color: @color;
  background-color: $bg; |   background-color: @bg;
}                        | }
.unscoped {              | .unscoped {
  color: $color;         |   color: @color;
  // Would be an error   |   // Would be an error
  // background: $bg;    |   // background: @bg;
}                        | }

And their different output:

Sass Output                 | Less Output
----------------------------+----------------------------
.scoped {                   | .scoped {
  color: white;             |   color: white;
  background-color: blue;   |   background-color: blue;
}                           | }
.unscoped { color: white; } | .unscoped { color: black; }

Nested Selectors

Sass and Less have the & selector that allows nested selector to refer to the parent scope.

Sass               | Less
-------------------+-----------------
p {                | p {
  a {              |   a {
    color: red;    |     color: red;
    &:hover {      |     &:hover {
      color: blue; |       color: blue;
    }              |     }
  }                |   }
}                  | }

Mixins

Sass                              | Less
----------------------------------+----------------------------------
@mixin bordered {                 | .bordered {
  border-top: dotted 1px black;   |   border-top: dotted 1px black;
  border-bottom: solid 2px black; |   border-bottom: solid 2px black;
}                                 | }
                                  | 
#menu a {                         | #menu a {
  @include bordered;              |   .bordered;
}                                 | }

Mixins with Arguments / Dynamic Mixins

Sass                              | Less
----------------------------------+----------------------------------
@mixin bordered($width: 2px) {    | .bordered(@width: 2px) {
  border: $width solid black;     |   border: @width solid black;
}                                 | }
                                  | 
#menu a {                         | #menu a {
  @include bordered(4px);         |   .bordered(4px);
}                                 | }

Selector Inheritance

Less does not provide selector inheritance.

Sass                        | Less  | CSS Output
----------------------------+-------+---------------------------
.bordered {                 |  N/A  | .bordered, #menu a {
  border: 1px solid back;   |       |   border: 1px solid back; }
}                           |       |
                            |       |
#menu a {                   |       |
  @extend .bordered;        |       |
}                           |       |

Colors

Both less and sass provide color math. It was a bad idea in Sass, I'm not sure why less chose to copy it. There's no point in comparing them.

Sass provides a full array of tools for manipulating colors. All color representations (named colors, hex, rgb, rgba, hsl, hsla) are understood as colors and colors can be manipulated.

Sass exposes a long list of color functions not found in CSS:

Accessors:

  • red($color)
  • green($color)
  • blue($color)
  • hue($color)
  • saturation($color)
  • lightness($color)
  • alpha($color)

Mutators:

  • lighten($color, $amount)
  • darken($color, $amount)
  • saturate($color, $amount)
  • desaturate($color, $amount)
  • adjust-hue($color, $amount)
  • opacify($color, $amount)
  • transparentize($color, $amount)
  • mix($color1, $color2[, $amount])
  • grayscale($color)
  • compliment($color)

Note: Less.js provides a number of similar color functions.

Numbers

Both Sass and Less support numbers and basic arithmetic. However they differ significantly with respect to how they handle units.

Sass supports unit-based arithmetic, just like you learned in school. Complex units are supported in any intermediate form and will only raise an error if you try to print out the value of a complex unit.

Additionally, Sass has conversion tables so that any comparable units can be combined.

Sass will let you define your own units and will happily print out unknown units into your css. Less will not. Sass does this as a form of future proofing against changes in the w3c specification or in case a browser introduces a non-standard unit.

Sass:

1cm * 1em => 1 cm * em
2in * 3in => 6 in * in
(1cm / 1em) * 4em => 4cm
2in + 3cm + 2pc => 3.514in
3in / 2in => 1.5

Less:

1cm * 1em => Error
2in * 3in => 6in
(1cm / 1em) * 4em => Error
2in + 3cm + 2pc => Error
3in / 2in => 1.5in

Conditionals & Control Structures

Less does not provide any conditionals or looping structures. Instead, it provides mixin guards and pattern-matching which can be used to similar effect.

Sass and Less provides provide boolean types true and false, the and, or, and not operators as well as <, >, <=, >=, == operators. There are minor syntax differences between the two (Sass syntax shown here).

Some sass examples:

@if lightness($color) > 30% {
  background-color: black;
}
@else {
  background-color: white;
}

Looping:

@for $i from 1px to 10px {
  .border-#{i} {
    border: $i solid blue;
  }
}

A similar example in Less, using mixins:

.mixin (@color) when (lightness(@color) > 30%) {
  background-color: black;
}
.mixin (@color) when (lightness(@color) =< 30%) {
  background-color: white;
}

Less supports looping via recursion, but not (yet) selector interpolation as shown in the Sass example, so it is of limited use.

Server Side Imports

Both sass and less will import other sass and less files.

Output formatting

Less has three output formats: normal, compressed & yui-compressed. Sass has four: nested, compact, compressed, expanded.

Sass output compression currently beats the google pagespeed css plugin output by a few percent.

Comments

Less and Sass both support C-style (/* */) and C++ Style comments (//).

Namespaces

Less provides a feature that Sass does not:

#bundle () {
  .red { background-color: red }
  .green { background-color: green }
}

.foo {
  #bundle > .red;
}

Generates:

.foo {
  background-color: red;
}

The sass team considered this feature and decided that adding it would create fragility and unexpected interconnectedness.

@parixitjani
Copy link

Fine compression. Clear the overall concepts.

@Jaace
Copy link

Jaace commented Aug 27, 2013

I've been using Sass (SCSS) alongside Bootstrap but since it seems that LESS has somewhat caught up since I last looked at it I'll probably hop back to it. My workflow consists of the Roots WP starter, grunt.js, composer, Bootstrap and I guess LESS now.

I like SCSS a lot but it seems to be the odd man out in my workflow now...

@CWSpear
Copy link

CWSpear commented Sep 13, 2013

According to lessjs.org, LESS 1.4.0 "[i]ncludes new features such as extends..."

However, I don't see an example on the site, and it was proving more than a simple Google search to find out more information than the one line on LESS' site.

@aebsr
Copy link

aebsr commented Sep 27, 2013

ditto to @CWSpear's point, if you have

.bordered {
  border: 1px solid back;
}

#menu a {
    .bordered;
}

it will successfully compile to:

.bordered {
  border: 1px solid back;
}
#menu a {
  border: 1px solid back;
}

Treating the selector as if it were a mixin.

@aebsr
Copy link

aebsr commented Sep 27, 2013

Your conditional example also doesn't account for LESS 1.4 where we can do this

@iterations: 10;

.loopingClass (@index) when (@index > 0) {

  .border-@{index}px {
    border: unit(@index, px) solid blue;
  }

  .loopingClass(@index - 1);
}

.loopingClass (0) { /*stop*/ }
.loopingClass (@iterations);

Far from as lean as the SASS example, but generates the same CSS and is whole possible. At least in the example you use.

@bassjobsen
Copy link

@CWSpear for less > 1.4

 .bordered {                
  border: 1px solid back;  
}                         

#menu a {                 
 &:extend(.bordered);
}

compiles to:

 .bordered, #menu a {
  border: 1px solid back;
  }

@arlodesign
Copy link

LESS supports another use of the & operator that SASS does not:

.parent {
    background: #fff;
    &-child {
        color: #222;
    }
}

…produces:

.parent {
    background: #fff;
}
.parent-child {
    color: #222;
}

Try that in SASS or SCSS, and you'll get an error.

@alkaithil
Copy link

@arlodesign I believe you can now that Sass 3.3 has been released. I'm not sure if the gist is updated to cover last Sass version, if not I hope it will be soon!

@benfrain
Copy link

benfrain commented Apr 2, 2014

One of the main 'features' of pre-processors that nobody ever seems interested in talking about is compile time. That is Sass's achilles heel in non-Ruby projects. It's horribly slow to spin up Ruby just to compile Sass.

@darlanalves
Copy link

@benfrain If you are fond of Node.JS and Javascript, the node-sass package is way faster than the ruby watcher, and is written in JS + C (libsass). There's one drawback: you still have to install the compass gem to import the framework in the include paths.

@tcelestino
Copy link

Namespace on LESS is amazing.

@Taiger
Copy link

Taiger commented Jun 19, 2014

Less 1.7x I can do things Sass cannot. Like passing rulesets to mixins:
http://lesscss.org/features/#detached-rulesets-feature

@thaliaarchi
Copy link

I noticed that in the list of Sass color functions, that complement() is spelled wrong as compliment(). I found this out the hard way.

@kazurasaka
Copy link

sass output

.unscoped { color: white; } ×

.unscoped { color: black; } type miss?

@another-guy
Copy link

Awesome comparison and intro to both SASS/LESS. So much easier to pick up one now. Appreciate for putting it together!

@huricool
Copy link

Thanks for the good comparison btw them. I prefer SASS though.

@ivanderos
Copy link

Thank you.

@Romanzo
Copy link

Romanzo commented Jan 8, 2016

@sunnywx
Copy link

sunnywx commented Jul 4, 2016

the variable scope test is wrong

@vishnuvardhanv
Copy link

{Nice Work}

@krishna4b0
Copy link

Great work !!

@NaveenDA
Copy link

Thanks Now My doubt clear.

@angusgrant
Copy link

angusgrant commented Feb 6, 2017

Hi what about in LESS you can import a file by "reference". @import (reference) somelessfile.less and it wont include any of the CSS in the output file just make that file programmatically available for example you could include the boostrap.less CSS and then use the .table css selector as a a variable to include in the parent Less file.

@import (reference) "base/bootstrap.less";


table.bm {
    .table;
    .table-bordered;
    .table-condensed;
    .table-hover;
    
    td:not([colspan="1"]) {
        background-color: @table-bg-accent;
    }
    
    td,th {
        text-align:center;
    }
}

outputs:

table.bm {
  width: 100%;
  max-width: 100%;
  margin-bottom: 20px;
  border: 1px solid #dddddd;
}
table.bm > thead > tr > th,
table.bm > tbody > tr > th,
table.bm > tfoot > tr > th,
table.bm > thead > tr > td,
table.bm > tbody > tr > td,
table.bm > tfoot > tr > td {
  padding: 8px;
  line-height: 1.42857143;
  vertical-align: top;
  border-top: 1px solid #dddddd;
}
table.bm > thead > tr > th {
  vertical-align: bottom;
  border-bottom: 2px solid #dddddd;
}
table.bm > caption + thead > tr:first-child > th,
table.bm > colgroup + thead > tr:first-child > th,
table.bm > thead:first-child > tr:first-child > th,
table.bm > caption + thead > tr:first-child > td,
table.bm > colgroup + thead > tr:first-child > td,
table.bm > thead:first-child > tr:first-child > td {
  border-top: 0;
}
....

Is this possible in SASS/SCSS is that what partials are all about i cant see them in the docs?

@CBSE10thResult2017
Copy link

@CBSE10thResult2017
Copy link

@GraniteConsultingReviews

Thanks for sharing about sass and less comparison I was very confused between them

@multics
Copy link

multics commented Jan 22, 2019

When I see Ruby, I give up Sass.

@mathieucaroff
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment