Slide 1

Slide 1 text

FRONTEND (re)organize the chaos

Slide 2

Slide 2 text

FRONTEND (re)organize the chaos Matteo Papadopoulos @spleenteo @steffoz Stefano Verna

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Asset Pipeline a.k.a. Sprockets

Slide 5

Slide 5 text

“The new pipeline makes assets a first class citizen in the Rails stack.” Asset Pipeline

Slide 6

Slide 6 text

Asset Pipeline gem 'jquery-rails' ! //= require 'jquery'

Slide 7

Slide 7 text

Asset Pipeline 2011 Rails 3.1

Slide 8

Slide 8 text

Asset Pipeline 2012

Slide 9

Slide 9 text

Asset Pipeline Bower Frontend package manager

Slide 10

Slide 10 text

Asset Pipeline +17.000 packages

Slide 11

Slide 11 text

Asset Pipeline $ npm install -g bower $ bower init

Slide 12

Slide 12 text

Asset Pipeline { "name": "my-project", "dependencies": { "jquery-ui": "~1.11.1", "jquery": "~2.1.1" } } $ cat bower.json

Slide 13

Slide 13 text

Asset Pipeline $ tree bower_components -L 1 ./bower_components "## jquery $## jquery-ui

Slide 14

Slide 14 text

Asset Pipeline So we need two package managers?

Slide 15

Slide 15 text

Asset Pipeline Rails Assets Frictionless proxy between Bundler and Bower

Slide 16

Slide 16 text

Asset Pipeline source 'https://rubygems.org' source 'https://rails-assets.org' ! gem 'rails-assets-jquery-ui'

Slide 17

Slide 17 text

Asset Pipeline Bundler Rails Assets Bower do you have rails-assets-jquery-ui? do you have jquery-ui? sure thing, take it! here's the gem!

Slide 18

Slide 18 text

Asset Pipeline win-win that was easy.

Slide 19

Slide 19 text

Compass “A SASS Framework” Asset Pipeline

Slide 20

Slide 20 text

Compass vendor prefixes typography vertical rhythm grid reset helper functions image-related features Asset Pipeline

Slide 21

Slide 21 text

Compass Asset Pipeline monolithic approach

Slide 22

Slide 22 text

Compass soooo slow Asset Pipeline

Slide 23

Slide 23 text

Compass php syndrome Asset Pipeline

Slide 24

Slide 24 text

Compass Asset Pipeline box-shadow: 10px 10px 5px red;

Slide 25

Slide 25 text

Compass Asset Pipeline +box-shadow(red 10px 10px 5px) box-shadow: 10px 10px 5px red;

Slide 26

Slide 26 text

Compass vendor prefixes typography vertical rhythm grid reset helper functions image-related features Asset Pipeline

Slide 27

Slide 27 text

Compass vendor prefixes image-related features Asset Pipeline

Slide 28

Slide 28 text

Compass unix-like approach Asset Pipeline

Slide 29

Slide 29 text

Asset Pipeline vendor prefixes

Slide 30

Slide 30 text

Asset Pipeline 100% Sass mixin library

Slide 31

Slide 31 text

Asset Pipeline CSS post-processor Autoprefixer gem 'autoprefixer-rails'

Slide 32

Slide 32 text

Asset Pipeline a { display: flex; } > 1% last 2 versions Firefox ESR Opera 12.1 a { display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex }

Slide 33

Slide 33 text

Compass vendor prefixes image-related features Asset Pipeline

Slide 34

Slide 34 text

Asset Pipeline image-related features sprites webfont high DPI images support lossless image compression …

Slide 35

Slide 35 text

Asset Pipeline task management tools

Slide 36

Slide 36 text

Asset Pipeline GRUNT GULP BROCCOLI

Slide 37

Slide 37 text

Asset Pipeline +3400 tasks mostly frontend-related

Slide 38

Slide 38 text

Asset Pipeline $ npm install -g grunt-cli

Slide 39

Slide 39 text

Asset Pipeline $ cat package.json { "name": "my-project", "dependencies": { "grunt": "~1.11.1", "grunt-bemo": "~2.1.1", ... } } $ npm install

Slide 40

Slide 40 text

Asset Pipeline # Gruntfile.js ! module.exports = function(grunt) { grunt.loadNpmTasks('grunt-bemo'); ! grunt.initConfig({ bemo: { webfonts: { src: "app/assets/fonts/svg", fontDest: "app/assets/fonts", sassDest: "app/assets/stylesheets/_icon-glyphs.css.scss" }, sprites: { src: "app/assets/images/sprites", imageDest: "app/assets/images/sprites-{{density}}.png", sassDest: "app/assets/stylesheets/_sprites.css.scss" } } }); };

Slide 41

Slide 41 text

Asset Pipeline $ grunt bemo ! Running "bemo-sprites" task ... ! Running "bemo-webfonts" task ...

Slide 42

Slide 42 text

Asset Pipeline JS/Coffee code linter JS/Coffee code style checker Live reload SVG/PNG/JPG optimizer Inline assets Unused CSS removal ...

Slide 43

Slide 43 text

Asset Pipeline Recap Use Bower packages, not gems Rails Assets Replace Compass Bourbon/Autoprefixer Grunt/Gulp/Broccoli

Slide 44

Slide 44 text

Writing Sass

Slide 45

Slide 45 text

Writing Sass $ rails generate controller books create app/controllers/books_controller.rb invoke erb create app/views/books invoke helper create app/helpers/books_helper.rb invoke assets invoke coffee create app/assets/javascripts/books.js.coffee invoke scss create app/assets/stylesheets/books.css.scss Rails conventions

Slide 46

Slide 46 text

OOCSS Object-oriented CSS Writing Sass Organize the chaos v1 2012 - http://goo.gl/6ZRJm4

Slide 47

Slide 47 text

OOCSS A CSS “object” is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. That object can then be reused throughout a site. Writing Sass

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

Writing Sass

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Writing Sass media object

Slide 54

Slide 54 text

Writing Sass .media display: table width: 100% ! .media .img, .media .body display: table-cell vertical-align: top ! .media .img padding-right: 10px
!
!
...
!

Slide 55

Slide 55 text

Writing Sass No margins, no positioning, 100% width .media display: table width: 100% ! .media .img, .media .body display: table-cell vertical-align: top ! .media .img padding-right: 10px

Slide 56

Slide 56 text

Writing Sass Location indipendence Let the context choose your positioning Be fluid: always expand to take the full width of the container

Slide 57

Slide 57 text

Writing Sass Just class selectors? .media display: table width: 100% ! .media .img, .media .body display: table-cell vertical-align: top ! .media .img padding-right: 10px

Slide 58

Slide 58 text

Writing Sass ID selectors Limit reuse within the same page Tag selectors Force a semantic Carpet bombing

Slide 59

Slide 59 text

.media display: table width: 100% ! .media .img, .media .body display: table-cell vertical-align: top ! .media .img padding-right: 10px Writing Sass Wait, what about descendent selectors?

Slide 60

Slide 60 text

Writing Sass Descendent selectors Carpet bombing (again) Potential name clashing

Slide 61

Slide 61 text

Writing Sass Descendent selectors Do not use them.

Slide 62

Slide 62 text

Writing Sass .media display: table width: 100% ! .media .img, .media .body display: table-cell vertical-align: top ! .media__img padding-right: 10px

Slide 63

Slide 63 text

Writing Sass .media display: table width: 100% ! .media__img, .media__body display: table-cell vertical-align: top ! .media__img padding-right: 10px

Slide 64

Slide 64 text

BEM Writing Sass Block • Element • Modifier

Slide 65

Slide 65 text

Writing Sass .media display: table width: 100% ! .media__img, .media__body display: table-cell vertical-align: top ! .media__img padding-right: 10px Block (CSS object) Block element

Slide 66

Slide 66 text

Writing Sass Block (CSS object) .nav-bar .nav-bar__logo Block element

Slide 67

Slide 67 text

Writing Sass Block (CSS object) .nav-bar .nav-bar__logo Block element .nav-bar--primary Modifier

Slide 68

Slide 68 text

Writing Sass .media // .... ! .media--rev direction: rtl text-align: left ! .media__img padding-right: 0px padding-left: 10px
!
!
...
!

Slide 69

Slide 69 text

Writing Sass .nav-bar--primary__logo--dark

Slide 70

Slide 70 text

Writing Sass But it's verbose and ugly and...! CSS has limited character set. Deal with it.

Slide 71

Slide 71 text

Writing Sass Remember the pros! No more name clashing ! No more overrides ! Trivial to understand and maintain your codebase

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

Structure Writing Sass

Slide 74

Slide 74 text

Writing Sass . "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... Root file

Slide 75

Slide 75 text

Writing Sass . "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... // Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Blocks @import 'blocks/**/*'

Slide 76

Slide 76 text

Writing Sass // Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Blocks @import 'blocks/**/*' gem "sass-globbing"

Slide 77

Slide 77 text

Writing Sass . "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... // Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Blocks @import 'blocks/**/*'

Slide 78

Slide 78 text

. "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... // Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Formats @import 'formats/**/*' ! // Blocks @import 'blocks/**/*' Writing Sass Configuration functions mixins

Slide 79

Slide 79 text

// Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Formats @import 'formats/**/*' ! // Blocks @import 'blocks/**/*' Writing Sass . "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... Default styling, Basefile

Slide 80

Slide 80 text

Writing Sass html, body ! a ! ul, ol, blockquote ! li ! h1, h2, h3, h4, h5, h6, hgroup, ul, ol, dd, p, figure, pre, table, fieldset, hr, form ! input, textarea ! input[type="submit"], button

Slide 81

Slide 81 text

// Silent code @import 'functions/**/*' @import 'variables/**/*' @import 'bourbon' @import 'mixins/**/*' ! // Font faces @import 'font-faces' ! // Base @import 'normalize-scss' @import 'base' ! // Blocks @import 'blocks/**/*' Writing Sass . "## application.css.sass "## _base.css.sass "## _font-faces.css.sass "## blocks % "## _button.css.sass % "## _media.css.sass % $## ... "## functions % $## ... "## mixins % $## ... $## variables $## ... 99% of the code is here!

Slide 82

Slide 82 text

Writing Sass one block per file group blocks into subdirectories

Slide 83

Slide 83 text

Asset Pipeline Recap Rails per-controller modularity is not scalable OCCSS is a better solution BEM How to structure our Rails stylesheets directory

Slide 84

Slide 84 text

BEMO Writing Sass

Slide 85

Slide 85 text

Asset Pipeline Bemo http://github.com/stefanoverna/bemo Project starter/Scaffolder Common BEM blocks library Grunt tasks for retina-ready sprites and web fonts

Slide 86

Slide 86 text

THANKS! question time Matteo Papadopoulos @spleenteo @steffoz Stefano Verna