Responsive Grids with Garden

 

Priyatam Mudivarti

Founder/Principal | Facjure, LLC

 

@priyatam

Clojure/West
Portland, OR, Mar 2015

Why Grids

Information Architecture

Typography

Graphic Design

Print Design

Web Design

The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice.

 

— JOSEF MULLER-BROCKMANN

But I'm not a web designer!

Do you know CSS?

Many choices

 

960px

Bootstrap

Foundation

Jeet

Susy

Skeleton

Skeljs

Flexbox
 

https://github.com/priyatam/thinking-grids

> 50 grid libraries

Real designers 

design from scratch

they're hackers too

designer

Make the headings serifs and scale-types using four breakpoints (480 px increments). Use our brand settings on a 3-column grid

λgrammer

Let me write a higher order function



(defn create-minimal-grid [clazz pad]
  [[:* {:box-sizing "border-box"}]
   [clazz {:background "white"
           :margin [[0 0 pad 0]]}
    [:&:after {:content ""
               :display "table"
               :clear "both"}]
    ["[class*='col-']" {:float "left"
                        :padding-right pad }]
    [:.col-1-3 {:width "33.33%"}]
    [:.col-2-3 {:width "66.66%"}]
    [:.col-1-2 {:width "50.00%"}]
    [:.col-1-4 {:width "25.00%"}]
    [:.col-1-8 {:width "12.50%"}]
    [:.out-padding {:padding [[pad 0 pad pad pad]]}
     ["[class*='col-']:last-of-type" 
         {:padding-right pad}]]]])

A grid in a single function

Can we make it better?

https://github.com/facjure/mesh
(def gutter (px 20))

(def typesetting
  (list
   (typo/typeset-body typo/defaults :golden)))

(def grids
  (list (typo/baseline (rgba 0 0 255 0.5) (px 2))
        (grid/create ".grid" gutter)
        (grid/wrap-widths 978)
        (grid/create-nested-units)
        (grid/nuke-gutters-and-padding)
        (grid/respond-small (:mobile breakpoints) gutter)
        (grid/respond-medium (:tablet breakpoints))))

(def styles
  (css (merge grids typesetting)))

How about responsive
typography?


calc(minFont +   (maxFont - minFont) 
*   ((100vw - minWidth) 
/ (maxWidth - minWidth))

 

based on viewport math



(defn calc [min-font max-font min-width max-width]
  (println "Viewport size:" (viewport-w))
  (let [(viewport-w .. js/document -documentElement -clientWidth) 
        font-diff (+ min-font (- max-font min-font))
        vp-diff (- (px (viewport-w)) min-width)
        wid-diff (- max-width min-width)
        res (* font-diff (/ vp-diff wid-diff))]
    (println "Calculated Fontsize: " (:magnitude res))
    (swap! state assoc :font-size res)
    res))

a single function + media queries

http://madebymike.com.au/writing/precise-control-responsive-typography/

Demos

Bootstrap

container
row
column

is limiting

Susy

most popular layout engine

not based on calc

~3000 SLOC

depends on context 

extension is hard

feels like "framework" 

Why stop there

(copy print-design)

Baseline

Grid?

DIN Paper system

16 columns  =  desktops
 

8 columns     =   tablets
 

4 columns     =   mobile
 

render any screen  from 240 up to 2560 px

*http://goldengridsystem.com

Demos

That's half
the truth

unsymmetrical grids need complex math

 

!browser issues

js framework integrations

 

perfection takes time

Foundations

columns

gutters

baseline grid

simple, fluid, nested, hierarchical

typographic rythms
modular scale
 

layout math

media queries

CONCEPTS

TYPES

CORE

CSS/SASS

are great, but limited

css doesn’t “talk to dom”

math impl is hard

 

not modular
not content driven

not dynamic


mixins are not composable


constrained by limitations—not by choice

 

Most Grid libraries are limited

Can you create columns with just one wrapping element?

Are you stuck with a set number of columns? 

Do you have to add several classes to your markup for the grid to function?

Are the gutters between columns created by padding or an actual space between them (margin) ?

Can you make vertical grids with it?

Can you pass other values to these gutters? For instance, 2rem *

 

* https://github.com/corysimmons/lost

Garden

written by Joel Holdbrooks

(author of a dozen clj/cljs libraries)

CSS as data

Vectors
= Selectors

 

Map
= Declarations

 

Rules
= Vector of Vectors

[:.grid {:*zoom 1}
  [:&:before :&:after {:display "table"
                       :content " "
                       :line-height 0}]
  [:&:after {:clear "both"}]]

Text

DRY Mixins & Functions 


;; DRY "Mixins" return declarations
(def reset
  {:margin 0
   :padding 0})


;; Real Functions return values (Rules)
(defn clearfix [clazz]
  [clazz {:*zoom 1}
   [:&:before :&:after 
       {:display "table"
        :content " "
        :line-height 0}]
   [:&:after {:clear "both"}]])

Text

Media Queries



(defn respond-medium [width]
  (at-media {:screen true :min-width width}
            [:.wider
             [:.grid {:max-width width
                      :margin "0 auto"}]]))

 

Abstraction is at the center of most work in
Computer Science &
User Interface Design.

 

Abstractions

Not in
CSS, 
Less,

Sass, Stylus

namespaces

 

pass css as functions at runtime

compose HTML and CSS in the same syntax

simple & powerful units & arithmetic


rEPL-driven design

programming stylesheets
in FP

 

separate  selectors and declarations

 

Ring-style middleware

Mesh,
a grid library—

early prototypes

http://github.com/facjure/mesh


Decouple

selectors * declarations

;; a bad example
(defn make-serifs [selector families]
  (fn [declarations]
    (let [styles (selector declarations)]
      (conj styles (font (:garamond families) 3 600 0.5 2)))))

;; slightly better
(defn scale-type [selector params]
  (fn [declarations]
    (let [styles (selector declarations)]
      (conj styles
            (at-media {:min-width (get-in params [:breakpoints :mobile])}
                      [:& {:font-size (* 1.5 (:min-font params))}])
            (at-media {:min-width (get-in params [:breakpoints :tablet])}
                      [:& {:font-size (* 1.75 (:min-font params))}])
            (at-media {:min-width (get-in params [:breakpoints :laptop])}
                      [:& {:font-size (* 2.25 (:min-font params))}])))))

Compose Declarations
and Selectors, with HoF

(defn headings [declarations]
  [:h1 :h2])

(-> headings
    (scale-type settings)
    (make-serifs brand-fonts)
    (make-sans-brand-fonts)
    (grid/create {:columns 3})

Create your own DSLs

Integrate with Om

store styles in app-state

 

store content in app-state

 

components mount their own styles and content as data on IWillMount, as values

 

unmount (if necessary)

 

Issues with Garden

learning clojurescript

 

low-level, no libraries 

 

integration with sass or postcss (@import "susy")

 

compile errors, spell checks

 

tools and gui

need a engineer who is a designer

Demo

let's create a storyboard-style magazine layout

Initial Content

(swap! app-state assoc-in [:content :logo] "/img/logo.png")

(css (merge
        (images/photos)
        grid-styles
        typography-base))

(reset! app-state new-content) 

 

iterate: grid gutters, ratios, typesetting, edit content

There is no

perfect Grid 

a great Grid toolkit can provide tools to help designers create their own layout engine

 

Thanks, Joel Holdbrooks and David Nolen for creating Garden and Om.

 

 

don't overthink it: https://css-tricks.com/dont-overthink-it-grids/
bootstrap grid overview: http://www.helloerik.com/the-subtle-magic-    
   behind-why-the-bootstrap-3-grid-works
last "poster": joseph-mueller-brockmann
baselingrid example: http://goldengridsystem.com
movie poster: http://themanyfacesof.com/sigourney-weaver/

illustrations and logos: matt martini

Credits

References


slides
http://slides.com/priyatam/responsive-grids-with-cljs

garden
https://github.com/noprompt/garden
grid toolkit with garden (early stage)
http://github.com/facjure/mesh
live coding
https://github.com/bhauman/lein-figwheel
lein templates
https://github.com/priyatam/mala
https://github.com/swannodette/mies-om

Responsive-Grids-with-Garden

By Priyatam Mudivarti

Responsive-Grids-with-Garden

Clojurescript community has been slow to embrace Garden, a simple library for rendering CSS in Clojure/ClojureScript. Conceptually similar to Hiccup, Garden allows you to design pages and layouts like a functional programmer: plain-old data structures, functions, and abstractions.

  • 2,694