Spree: LESS is dead. Long live SCSS/SASS!

I still remember one of the key feature of Spree when it first came out to the market is Compass/Blueprint + LESS. LESS is a dynamic CSS syntax language that offers powerful functions like mixin, netsing, variable, interpolation, inheritances, etc that make CSS easier to write and manage. Yet LESS seems unpopular amongst developers, it could be explained that because it was quite new at the time and considered hard for noob users. In fact, Spree’s made LESS optional in opt for a all-in-one screen.css file for quite a while. Since the move to Rails 3 last year, LESS was commented out and tweaks that were made on the screen.css are not populated back to LESS stylesheets, this discrepancies makes LESS less ideal for Spree theming.

When I was working on de-coupling spree_blue_theme assets from the spree core 0.70.x, I had a conversation with BDQ regarding of moving LESS stylesheets to spree_blue_theme. BDQ had not objection of moving it to spree_blue_theme and leave LESS stylesheets optional as is. However he suggested that rebase all changes from the main screen.css to LESS stylesheets then compile all of them to css and having screen.css act as the sprocket asset pipeline. To me that is a very good idea because it mitigate the incompatibility for theme migration as well as leverage the use of rails 3.1’s sprocket. Think again, that solution seems a bit more daunting than converting all LESS to SCSS/SASS. First is the poor performance of sprocket in development mode. Second is why settle for something worse? Hence, I suggested to him that we should give SCSS/SASS a try because it has close resemblance with LESS syntax (the SCSS is – not the SASS) and is supported out of the box on Rails 3.1 that would help resolve locating asset path problem. Hence this is the reason of this post, that is guiding you through my journey from LESS wonderland to SASS-y land.

You can check my commit for spree_blue_theme here.

Rebase

With the help of the al-mighty git log -p, I could track down all changes that has been made to the screen.css then merge these changes back to equivalent LESS stylesheets.

Relocation

I moved all LESS stylesheets from app/stylesheets to app/assets/stylesheets/store and renamed all filenames extension to .scss. I did not opt for the SASS syntax because of its lacking curl brackets that is native to CSS and LESS syntax.

Conversion

Assisting Tool

SASS provides you very powerful and nifty tool to validate stylesheets on-the-fly.

sass --watch app/assets/stylesheets/store:screen.css

The --watch would keep track of all changes you made to files that contribute to the final compiled screen.css. In case you make mistakes in your stylesheets, the output will tell you instantly what goes wrong and at what line of which file.

Importing

The screen.less is used as a meta-file to consolidate all LESS ‘partials’. Similarly, SASS does the same regarding the filename prefix _ and use same @import syntax, however you do not specify the under score in import line. For example:

@import '_form';

would become

@import 'form';

Variables

Variable is again another plus that LESS offers, so do SASS. To convert LESS variable to SASS, simple replace the @ sign with $ sign. For example:

@white: #FFF;

would become:

$white: #FFF;

as the same goes to the argument of mixin, for example:

.message_box (@bg_color: #ccddff, @color: #556699, @border_color: #99aacc)

would become

@mixin message_box ($bg_color: #ccddff, $color: #556699, $border_color: #99aacc)

Mixins

Mixins in SCSS/SASS are defined with prefix @mixin and invoked with @include rather than then dot notation of LESS. I think SCSS/SASS is more visible as CSS coders tend to mistake the dot with CSS class selector.

So something like:

.message_box (@bg_color: #ccddff, @color: #556699, @border_color: #99aacc) { ... }

.flash.errors {
  .message_box(#F4B4B4, #000, #000);
}

would now be

@mixin message_box ($bg_color: #ccddff, $color: #556699, $border_color: #99aacc) { .. }

.flash.errors {
  @include message_box(#F4B4B4, #000, #000);
}

Nesting Rules

Nesting in both are the same. So I leave the nesting intact.

Operator & Function

Same.

Assets Location

Assets pipeline is new to Rails 3.1. Rails provides asset_path helper to assist the job, however I could not rename filename to scss.erb to use it, it just won’t work. Thanks to sass-rails, I could use image-url helper to locate the asset easily:

background: #FFF url('../images/body-back.png') top left repeat-x;

to

background: #FFF image-url('body-back.png') top left repeat-x;

Enhancement

SASS provides @extends directive to inherits rules of a set that helps reduce code duplication. One example is the .errorExplanation of messages partial that has duplicated rules of .flash and .flash.errors can be refactored to:

.formError, .errorExplanation {
  @extend .flash;
  @extend .flash.errors;
  p { margin: 0px; }
  ul { margin-bottom: 0px; }
  h2 {
    font-weight: bold;
    font-size: 1.0em;
    margin: 0px;
  }
}

Conclusion

In conclusion, SASS suffice all the features of LESS with minor modification to the syntax. Additionally, thanks to the tight support of Rails 3.1 for SASS, there seems to be little configuration. Though virtually as same as SASS, LESS seems to die out due to lacking of a strong user base of RoR.

Advertisements

About Jones Lee

Nothing much about me..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: