web frontend development: tools and good practices to (re)organize the chaos

Post on 24-Apr-2015

196 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

After my first attempt to "organize the chaos" (2012) in the structure of a front-end project, Stefano Verna (@steffoz) and I, have tried to bring together a number of tools and conventions to deal with front-end development in a way that could be understandable and maintainable, over the time, by a whole team. This presentation has been performed, for the first time, during the Ruby-Day-2014 in Venice, Italy. Here the video of the speech (italian): https://www.youtube.com/watch?v=fUJOJY_yVXg&index=6&list=PL5ImBN21eKvbQ6kH6WCAqj1QqgusGsiO0

TRANSCRIPT

FRONTEND (re)organize the chaos

FRONTEND (re)organize the chaos

Matteo Papadopoulos@spleenteo

@steffozStefano Verna

www.cantierecreativo.net

Asset Pipelinea.k.a. Sprockets

“The new pipeline makes assets a first class citizen in the

Rails stack.”

Asset Pipeline

Asset Pipeline

gem 'jquery-rails'!

//= require 'jquery'

Asset Pipeline

2011Rails 3.1

Asset Pipeline

2012

Asset Pipeline

BowerFrontend package manager

Asset Pipeline

+17.000packages

Asset Pipeline

$ npm install -g bower$ bower init

Asset Pipeline

{ "name": "my-project", "dependencies": { "jquery-ui": "~1.11.1", "jquery": "~2.1.1" }}

$ cat bower.json

Asset Pipeline

$ tree bower_components -L 1

./bower_components"## jquery$## jquery-ui

Asset Pipeline

So we need two package managers?

Asset Pipeline

Rails AssetsFrictionless proxy between Bundler and Bower

Asset Pipeline

source 'https://rubygems.org'source 'https://rails-assets.org'!

gem 'rails-assets-jquery-ui'

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!

Asset Pipeline

win-winthat was easy.

Compass“A SASS Framework”

Asset Pipeline

Compass

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

Asset Pipeline

Compass

Asset Pipeline

monolithic approach

Compass soooo slow

Asset Pipeline

Compass php syndrome

Asset Pipeline

Compass

Asset Pipeline

box-shadow: 10px 10px 5px red;

Compass

Asset Pipeline

+box-shadow(red 10px 10px 5px)

box-shadow: 10px 10px 5px red;

Compass

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

Asset Pipeline

Compassvendor prefixes image-related features

Asset Pipeline

Compass unix-like approach

Asset Pipeline

Asset Pipeline

vendor prefixes

Asset Pipeline

100% Sass mixin library

Asset Pipeline

CSS post-processorAutoprefixer

gem 'autoprefixer-rails'

Asset Pipeline

a { display: flex;}

> 1%last 2 versionsFirefox ESROpera 12.1

a { display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex}

Compassvendor prefixes image-related features

Asset Pipeline

Asset Pipeline

image-related features

sprites webfont high DPI images support lossless image compression …

Asset Pipeline

task management tools

Asset Pipeline

GRUNT GULP BROCCOLI

Asset Pipeline

+3400tasks

mostly frontend-related

Asset Pipeline

$ npm install -g grunt-cli

Asset Pipeline

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

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" } } });};

Asset Pipeline

$ grunt bemo!

Running "bemo-sprites" task...!

Running "bemo-webfonts" task...

Asset Pipeline

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

Asset Pipeline

RecapUse Bower packages, not gems Rails Assets Replace Compass Bourbon/Autoprefixer Grunt/Gulp/Broccoli

Writing Sass

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

OOCSSObject-oriented CSS

Writing Sass

Organize the chaos v1 2012 - http://goo.gl/6ZRJm4

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

Writing Sass

Writing Sass

media object

Writing Sass

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

<div class="media">! <div class="img"> <img src="..." /> </div>! <div class="body"> ... </div>!</div>

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

Writing Sass

Location indipendenceLet the context choose your positioning

Be fluid: always expand to take the full width of the container

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

Writing Sass

ID selectorsLimit reuse within the same page

Tag selectorsForce a semantic Carpet bombing

.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?

Writing Sass

Descendent selectorsCarpet bombing (again) Potential name clashing

Writing Sass

Descendent selectorsDo not use them.

Writing Sass

.media display: table width: 100%!

.media .img, .media .body display: table-cell vertical-align: top!

.media__img padding-right: 10px

Writing Sass

.media display: table width: 100%!

.media__img, .media__body display: table-cell vertical-align: top!

.media__img padding-right: 10px

BEM

Writing Sass

Block • Element • Modifier

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

Writing Sass

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

Writing Sass

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

.nav-bar--primary Modifier

Writing Sass

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

<div class="media media--rev">! <div class="media__img"> <img src="..." /> </div>! <div class="media__body"> ... </div>!</div>

Writing Sass

.nav-bar--primary__logo--dark

Writing Sass

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

Writing Sass

Remember the pros!No more name clashing !

No more overrides !

Trivial to understand and maintain your codebase

Structure

Writing Sass

Writing Sass

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

Root file

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/**/*'

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"

."## application.css.sass"## _base.css.sass"## _font-faces.css.sass"## blocks%   "## _button.css.sass%   "## _media.css.sass%   $## ..."## formats%   "## _align.css.sass%   "## _font-size.css.sass%   $## ..."## functions%   $## ..."## mixins%   $## ...$## variables

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/**/*'

."## 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

// 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

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

// 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!

Writing Sass

one block per file

group blocks into subdirectories

Asset Pipeline

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

BEMO

Writing Sass

Asset Pipeline

Bemohttp://github.com/stefanoverna/bemo

Project starter/Scaffolder Common BEM blocks library Grunt tasks for retina-ready sprites and web fonts

THANKS! question time

Matteo Papadopoulos@spleenteo

@steffozStefano Verna

top related