Wednesday, December 28, 2011

adopting sass with Sinatra

I have been working on an embedded web application with Sinatra. I took enough care to keep css files clean and compact. But it is getting tougher with ever growing style sheets to be vigilant at all times. I heard about sass and less but never felt I would need such tools to handle styles. Today I could learn basics of Saas.
And now I regret for not adopting to such good frameworks from the beginning.

Though less offers dynamic stylesheets, 32kb javascript is too much of a burden for my embedded application.
As such I run a rake script to minify and compress markup and javascripts. I thought sass would be a better choice. I could simply run script to convert scss files to css.

But it would not be so much so convenient during development to convert these scss files every now and then to css. But thanks to Rack and Sinatra it was really easy to integrate sass with existing app.  Here goes sinatra file.


require 'sinatra'
require 'sass'

get '/stylesheets/:name.css' do
  content_type 'text/css', :charset => 'utf-8'
  filename = "#{params[:name]}"
  render :scss, filename.to_sym, :layout => false, :views => './public/stylesheets'
end

get '/' do
  erb :index
end


 Normally we don't need to write a get routine for resources in public folder. But in this case sass looks at "views" folder for scss files. Also during development it would be better if we could test actual css. Thus converting these scss files to css makes more sense. Now I can keep styles in more modular way using nice features of saas. Following two underscore files makes them modular as saas wont generate css for them
when they are imported.

_s1.scss

#fullname {
  p:first-child {
    color : grey;
  }

  p:last-child {
    color : lightgrey;
  }
}

_s2.scss

#communication {
  p:first-child {
    color : red;
  }

  p:last-child {
    color : lightgrey;
  }
}

also theme.scss can be made with functions and using mixins

theme.scss
@function  contact_padding($n) {
  @return ($n * 3) + px;
}


@mixin contact($bw, $bc) {
  padding:contact_padding($bw);
  border: $bw+px solid $bc;
  font-size:20px;
  font-weight:bold;
}

Now all these are imported to common.scss as

common.scss
@import "s1", "s2", "theme";

.theme1 {
  @include contact(2,orange);
}

Now when common.css is linked in html, sinatra does all hard work of importing and converting  before rendering css files.


<!DOCTYPE HTML>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="stylesheets/common.css" />    
  </head>
  <body>
    <div class="theme1">
      <div id="fullname">
        <p>Sriharsha</p>
        <p>Vardhan</p>
      </div>
      <div id="communication">
        <p>Email: mail@mydomain.net</p>
        <p>Mobile: +91 0101 010 101</p>
      </div>
    </div>
  </body>
</html>
Hope this makes it easy to get started.

No comments: