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.

Monday, December 26, 2011

HTML5 arrows

I am trying to create bar graphs with html5. As part of that I needed forward and backward arrows.

I tried to get arrows marked out of html and css3. Here is the result http://jsfiddle.net/harsha/2aq7R/1/embedded/result


Just started with arrow head. This wont show up anything as border is transparent is all sides.

      .arrow_head {
        width0pxborder-width20pxborder-stylesolid;  
        border-colortransparent transparent transparent transparent;
      }

Now to get top arrow effect let us show up bottom border.
      .top_arrow {
        border-bottom-color#E9E9E9;
      }


Similarly to get down arrow let us open up top border
      .down_arrow {
        border-top-color#E9E9E9;
      }



to get right arrow let us open up left border
      .right_arrow {
        border-left-color#E9E9E9;
      }

to get left arrow let us open up right border
      .left_arrow {
        border-right-color#E9E9E9;
      }


Now arrow body is pure border with fixed height and width. so to get right arrow


      <div style="float:right">
        <div style="width:20px; height:20px; background:#E9E9E9; float:left; margin-top:10px">div>
        <div class="arrow_head right_arrow" style="float:left">div>
      div>



Similarly all sides can be offset as shown below


HTML>
<html>
  <body>
    <div style="background:gray; width:300px; padding: 10px; height:40px">

      <div style="float:left">
        <div class="arrow_head left_arrow">div>
        <div style="width:20px; height:20px; background:#E9E9E9; margin-left:40px; margin-top:-30px">div>
      div>

      <div style="float:right">
        <div style="width:20px; height:20px; background:#E9E9E9; float:left; margin-top:10px">div>
        <div class="arrow_head right_arrow" style="float:left">div>
      div>

    div>

    <br />
    <div style="background:gray; width:300px; padding: 10px; height:40px">

      <div style="float:left; margin-top:-20px">
        <div class="arrow_head top_arrow">div>
        <div style="width:20px; height:20px; background:#E9E9E9;  margin-left:10px">div>
      div>

      <div style="float:right">
        <div style="width:20px; height:20px; background:#E9E9E9; margin-left:10px">div>
        <div class="arrow_head down_arrow">div>
      div>

    div>


  body>
html>





And here is the css


      .arrow_head {
        width0pxborder-width20pxborder-stylesolid;  
        border-colortransparent transparent transparent transparent;
      }
      .top_arrow {
        border-bottom-color#E9E9E9;
      }
      .down_arrow {
        border-top-color#E9E9E9;
      }
      .right_arrow {
        border-left-color#E9E9E9;
      }
      .left_arrow {
        border-right-color#E9E9E9;
      }