Vincent Garreau
Co-Founder & Front-end developer livestorm.co
Workflows, outils et astuces pour un développement front-end avancé
Lundi 26/03 | Workflow CSS + ES2015/18 Workflow JS + Modules et composants web |
Mardi 27/03 | Frameworks JS + Introduction à Vue.js |
Mercredi 28/03 | Suite intro Vue.js + Consignes TP n°1 |
Vendredi 30/03 | Correction du TP n°1 Suite intro Vue.js + Consignes TP n°2 |
Lundi 16/04 | Correction du TP n°2 + Synthèse |
Les bases du CSS
Préprocesseurs CSS
Postprocesseurs CSS
Méthodologies CSS
Astuces CSS
Les méthodes à connaître
Package managers
Linters JavaScript
Modules et composants web
Systèmes de modules
Module bundlers
Présentation rapide des frameworks JavaScript actuels
Introduction à Vue.js
<style>.element { width: 200px; }</style>
<span style="width:200px"></span>
<link rel="stylesheet" href="style.css">
Terme en anglais : CSS specificity
Terme en français : Poids des sélecteurs
<span style="color: red"> // 1000
#element // 100
.element // 10
span // 1
#element > div > li:hover // 100 + 1 + 1 + 10
.element !important // S'applique en priorité
Style inline
(HTML) |
IDs |
Classes, attributs,
pseudo classes (:) |
Elements,
pseudo elements (::) |
---|---|---|---|
1000 | 100 | 10 | 1 |
.button-push { padding: 10px; }
<button class="button-push">Push 1</button>
<button class="button-push">Push 2</button>
D'après les standards W3C
Un préprocesseur CSS contient une palette d'outils qui permet d'écrire un CSS plus maintenable
// CSS
.element {
width: 200px;
height: 80px;
font-size: 1.2em;
}
// Stylus ({}, : et ; sont chacun optionnel)
.element
width 200px
height 80px
font-size 1.2em
Léger et rapide à écrire
// CSS
.element > li { padding:10px; }
.element > li:hover { padding:20px; }
// Stylus
.element
> li
padding 10px
&:hover
padding 20px
Principe d'indentation (évitez plus de 3 niveaux)
// Sans préprocesseur
.element
width 20px
height 20px
margin-right 10px
// Avec préprocesseur
$element-size = 20px
.element
width $element-size
height $element-size
margin-right $element-size / 2 // Opération
Mixins
Fonctions
Opérateurs
Conditions
Itérations
@extend
@block
....
Un postprocesseur CSS est un outil qui permet d'effectuer
des tâches spécifiques sur un fichier CSS
PostCSS est un outil JavaScript qui permet d'effectuer des transformations d'un fichier CSS grâce à des plugins
Plugins PostCSS populaires :
autoprefixer : préfixe les propriétés
cssnext : permet d'écrire dès aujourd'hui du CSS4
Ensemble de conseils et de lignes de conduite
pour un CSS organisé et maintenable
Avantage d'un préprocesseur CSS :
Pouvoir générer un fichier CSS
à partir de plusieurs fichiers
Remarque
Sans préprocesseur, il est possible d'importer plusieurs fichiers CSS avec la méthode @import, mais cela est lourd car sans préprocesseur aucun fichier n'est généré.
Sans préprocesseur, 1 import = 1 requête HTTP en plus.
7-1 Pattern
7 dossiers, 1 fichier
Détails sur sass-guidelin.es/#the-7-1-pattern
📁 base
📁 components
📁 layout
📁 pages
📁 themes
📁 abstracts
📁 vendors
main.scss
Permet d' éviter des cas problématiques comme écraser du style précédemment appliqué / mélanger des styles
Si plusieurs développeurs travaillent sur un même projet, appliquer une règle de nommage commune est plus facile à comprendre / lire et à maintenir
OOCSS
Object-Oriented CSS
SMACSS
Scalable and Modular Approach for CSS
BEM
Block Element Modifier
// block-name__element-name--modifier-name
<header class="app-header">
<nav class="app-header-nav">
<ul>
<li class="app-header-nav__item"></li>
<li class="app-header-nav__item app-header-nav__item--on"></li>
</ul>
</nav>
</header>
Trucs et astuces, propriétés utiles...
// CSS2
.nav
.nav-item
display inline-block
vertical-align middle
// CSS3
.nav
display flex
align-items center
// Largeur responsive à gauche, fixe à droite
.wrapper
display flex
width 100%
.left // Largeur variable
width calc(100% - 300px)
.right // Largeur toujours égale à 300px
width 300px
// Largeur de 100px, padding inclus
.myElement
width 100px
padding 20px
box-sizing border-box
// border-box = padding inclus
// content-box (par défaut) = padding exclus
Classes vraiment utiles :
dropdown
modal
tooltip
// custom-bootstrap.styl (chargé après BS.)
.modal-header
border-radius .25rem .25rem 0 0
background $white-alabaster
text-align center
border-bottom 0
.form-control
border 1px solid $grey-alto
// var-colors.styl
$blue-picton = #36AAEA
// button.styl
.custom-button
background-color $blue-picton
$CouleurDominante-NomDeLaCouleur
Outil : Name That Color / Plugin Sublime
css-tricks.com/icon-fonts-vs-svg
Insertion du code de l'icône SVG directement dans le HTML
Insertion de l'icône SVG dans le HTML en utilisant les symboles
// On sélectione l'icône en ciblant l'id du symbole dans la balise "use"
<div class="svg-wrap">
<svg>
<use xlink:href="#icon-cross"></use>
</svg>
</div>
// On insère le fichier définition SVG dans le HTML (en haut, juste après l'ouverture du body)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-cross" viewBox="0 0 32 32">
<title>cross</title>
<path fill="#222" class="path1" d="M15.392 13.984l12.32-12.32c0.384-0.384 0.384-0.992 0-1.376s-0.992-0.384-1.376 0l-12.32 12.32-12.352-12.32c-0.384-0.384-0.992-0.384-1.376 0s-0.384 0.992 0 1.376l12.32 12.32-12.32 12.352c-0.384 0.384-0.384 0.992 0 1.376s0.992 0.384 1.376 0l12.352-12.32 12.32 12.32c0.384 0.384 0.992 0.384 1.376 0s0.384-0.992 0-1.376l-12.32-12.352z"></path>
</symbol>
<symbol id="icon-arrow" viewBox="0 0 32 32">
<title>arrow</title>
<path fill="#666" class="path1" d="M0.29 8.875l0.18 0.21 13.6 15.65c0.46 0.53 1.15 0.86 1.92 0.86s1.46-0.34 1.92-0.86l13.82-15.88c0.17-0.25 0.27-0.55 0.27-0.87 0-0.87-0.74-1.58-1.66-1.58v0h-28.68c-0.92 0-1.66 0.71-1.66 1.58 0 0.33 0.11 0.64 0.29 0.89z"></path>
</symbol>
</defs>
</svg>
Le standard JavaScript
ECMAScript 2015 = 6e édition / ES6
ECMAScript 2016 = 7e édition / ES7
ECMAScript 2017 = 8e édition / ES8
ECMAScript 2018 = 9e édition / ES9
// Anciennement var (ES5)
for (var i = 0; i <= 10; i++) {
console.log(i)
}
console.log(i) // 11
// Avec let (ES6)
for (let i = 0; i <= 10; i++) {
console.log(i)
}
console.log(i) // undefined
var school = 'HETIC'
// Anciennement var (ES5)
if (school === 'HETIC') {
var director = 'M. Beaux'
}
console.log(director) // M. Beaux
// Avec let (ES6)
if (school === 'HETIC') {
let director = 'M. Beaux'
}
console.log(director) // undefined
let age = 21
const firstname = 'Marie'
const identity = {}
age = 22 // let donc OK
firstname = 'Elodie' // const donc FAIL
identity = { firstname: 'Marie' } // FAIL
identity.firstname = 'Marie' // OK
let obj = {
bar: function () {
return this
}
}
console.log(obj.bar()) // obj
let obj = {
bar: () => {
return this
}
}
console.log(obj.bar()) // window
year = '2021'
// ES5
var str = 'La P' + year + ' est au top'
// ES6 : Entre backticks (différents des quotes)
const str = `La P${year} est au top`
// La P2021 est au top
const setColor(value = '#FF0000') = () {
console.log(`Couleur : ${value}`)
}
setColor("#000000") // Couleur : #000000
setColor() // Couleur : #FF0000
str = 'Les cours de marketing en H2 sont intenses'
youtubers = ['DirtyBiology', 'E-Penser']
// ES5
str.indexOf('marketing') !== -1 // true
youtubers['E-Penser'] !== undefined // true
// ES6
str.includes('marketing') // true
youtubers.includes('E-Penser') // true
const getAvatar = (email) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `https://www.gravatar.com/${email}.json`,
dataType: 'jsonp',
success(data) { resolve(data) },
error(data) { reject(data) }
})
})
}
getAvatar('08e83ed895943c88b5d11db6665ee8b4')
.then((response) => {
console.log('resolve data', response)
})
.catch((response) => {
console.log('reject data', response)
})
const ajax = (email) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `https://www.gravatar.com/${email}.json`,
dataType: 'jsonp',
success(data) { resolve(data) },
error(data) { reject(data) }
})
})
}
const getAvatar = async function(email) {
const res = await ajax(email)
return res
}
getAvatar('08e83ed895943c88b5d11db6665ee8b4')
.then((response) => { console.log('resolve data', response) })
.catch((response) => { console.log('reject data', response) })
Gestion des librairies / plugins via un
gestionnaire de paquets
// package.json
{
"name": "my-portfolio-package",
"version": "1.0.0",
"dependencies": {
"jquery": "^2.2.3"
}
}
// Commande pour installer le package jquery par exemple :
yarn add jquery
Outil pour garder un code JS lisible, cohérent et harmonieux
Plugins
Outils pour automatiser certaines tâches :
compilation d'assets, etc.
// gulpfile.js
// Import du module gulp et gulp-stylus
var gulp = require('gulp')
var stylus = require('gulp-stylus')
// Création d'une tâche, nommée "stylus"
gulp.task('stylus', function() {
return gulp.src('./assets/css/main.styl')
.pipe(stylus())
.pipe(gulp.dest('./build/css'))
})
// 1. Aller à l'emplacement du projet dans le terminal
// 2. Lancer la tâche "stylus" en tapant la commande :
gulp stylus
C'est quoi ? Pourquoi ?
Consiste à utiliser une
approche modulaire de l'architecture d'un projet informatique
Concept appliqué au
Javascript
Plus large qu'un module :
Template HTML + Javascript + Style CSS
Différents systèmes pour créer des modules Javascript
AMD
CommonJS
ES2015 Modules
// operators.js
define([], function () {
return {
sum: function (a, b) {
return a + b
},
divide: function (a, b) {
return a / b
}
}
})
// app.js
define(["./operators.js"], function (operators) {
var test = operators.sum(10, 5) // 15
})
Asynchronous Module Definition
// operators.js
exports.sum = function (a, b) {
return a + b
}
exports.divide = function (a, b) {
return a / b
}
// app.js
var operators = require('./operators.js')
var test = operators.sum(10, 5) // 15
// operators.js
const myObject = {}
myObject.sum = (a, b) => {
return a + b
}
myObject.divide = (a, b) => {
return a / b
}
export default myObject
// app.js
import operators from './operators.js'
const test = operators.sum(10, 5) // 15
Un outil qui analyse les modules pour générer des assets
Grafikart - Lien du tutoriel
module.exports = {
// Points d'entrée
entry: './assets/js/main.js',
// Configuration de l'export
output: {
path: './build/js',
filename: "main.js"
},
// Configuration des loaders
module: {
rules: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
]
},
// Configuration des plugins
plugins: []
}
Un outil tout en un pour créer une application maintenable
2010
2011
2011
2013
2009
2013
2014
Jeremy Ashkenas
Yehuda Katz
Meteor
Evan You
Facile à prendre en main
Développement rapide
Un écosystème flexible grâce aux différents plugins Vue
Mises à jour régulières
Communauté active
By Vincent Garreau
Workflows, outils et astuces pour un développement front-end avancé