Permalink
Fetching contributors…
Cannot retrieve contributors at this time
183 lines (120 sloc) 5.48 KB

The CSS Renderer

The CSS renderer extends the Renderer class with methods for rendering CSS stylesheets. These include methods for defining rules and properties, helper methods for dealing with things like media queries and vendor prefixes, and mixins for typography, grids, and so on.

Example

Typically, this renderer is used to define classes that correspond to a master application-specific stylesheets.

{CSS} = require "nice"
class MyStyleSheet extends CSS

  main: ->

    @rule "h1", =>
      @fontSize "4.5rem"
      @lineHeight "5rem"
      @marginBottom "2rem"

    @rule "p", =>
      @fontSize "1.6rem"
      @lineHeight "2rem"
      @marginBottom "1rem"

    @rule "img", =>
      @padding "0.5rem"
      @border "1px solid silver"
      @float "left"
      @marginRight "0.5rem"

myStyleSheet = new MyStyleSheet
myStyleSheet.main() # render the stylesheet

Mixins

You can include mixins in your stylesheet with the mixin method. Mixins are basically functions that add methods or properties to your renderer.

You can define top level mixins, rule-level mixins, or property-level mixins. For example, the typography mixin defines a top-level (main) mixin called rhythm which, in turn, generates a function that you can use to set the font-size and line-height in a way that will preserve the specific "rhythm" (the ratio between the two).

Nice provides CSS renderer mixins for buttons, colors, themes, dialogs, forms, grid layout, themes, and typography. (Documentation coming soon.)

Example: Typography Mixin

Here is the example above, but simplified by using the typography mixin:

{CSS} = require "nice"
class MyStyleSheet extends CSS

  main: ({rhythm})->

    rhythm 1.1, (typeSize) =>

      @rule "h1", =>
        typeSize 5
        @marginBottom "2rem"

      @rule "p", =>
        typeSize 2
        @marginBottom "1rem"

    @rule "img", =>
      @padding "0.5rem"
      @border "1px solid silver"
      @float "left"
      @marginRight "0.5rem"

Media Queries

To make it easier to write responsive CSS, Nice's CSS renderer provides some helper functions. First, you define your breakpoints using the breakpoint method, like this:

@breakpoint 
  desktop: """
    screen and (min-width: 72rem)
    """
  tablet: """
    screen and (min-width: 48rem) 
    and (max-width: 72rem)
    """
  mobile: """
    screen and (min-width: 20rem)
    and (max-width: 48rem)
    """
  tiny: """
    screen and (max-width: 20rem)
    """  

which, in turn, defines additional helper functions based on the names of your breakpoints. These can be accessed by invoking the breakpoint method and passing a function instead of an object:

@breakpoint ({desktop, tablet, mobile, tiny}) =>

  desktop =>
    @rule "body", =>
      @width "72rem"

  tablet =>
    @rule "body", =>
      @width "48rem"

  mobile =>
    @rule "body", =>
      @width "20rem"

    @rule "nav", =>
      @display "none"

These helper functions will automatically wrap the contained CSS rules in the appropriate media query.

Methods

rule(selectors...,properties)

Render a rule for the given selectors using the properties render function.

Example

This CSS rendering code:

{CSS} = require "nice"
css = new CSS

css.rule "p, ul", ->
  css.marginBottom "2rem"

will generate this CSS:

p, ul {
  margin-bottom: 2rem;
}

property(name,value)

Renders a property declaration. This method is usually used simply to implement specific property methods, such as marginBottom or width.

prefixProperty(name,value)

Renders one property declaration for each browser prefix of -moz and -webkit as well as one free of prefixes.

For example, this declaration:

@prefixProperty "boxOrient", "vertical"

will generate the following properties:

-webkit-box-orient: "vertical";
-moz-box-orient: "vertical";
box-orient: "vertical";

As with property, this method is typically used to define specific property methods, such as boxOrient.

context(selector,rules)

Creates a selector context for the given rules render function. Any rules declared within the function will be relative to the context. Rule-level mixins are passed in to the rules function.

Simple selector combinator functions are provided to express the relationship between the rule selector and the context.

For example, the following rules will be defined relative to the div.article selector:

{contains} = CSS.combinators

@context "div.article", =>

  # div.article { ... }
  @rule =>
    # etc.

  # div.article p { ... }
  @rule contains("p"), =>
    # etc.

The available selectors are: contains, sibling, child, and variant, which correspond to space, +, >, and concatenation.

  # div.article p { ... }
  @rule contains("p"), =>

  # div.article + p { ... }
  @rule sibling("p"), =>

  # div.article > p { ... }
  @rule child("p"), =>

  # div.article.highlight { ... }
  @rule variant(".highlight")

(You don't have to use the combinators; they're are simple readability aids. You can also just write @rule " p", => ..., but it's easy to miss the space.)