Skip to content

Lythom/formation-api-html5-css3

Repository files navigation

API HTML 5 et CSS 3


Samuel BOUCHET

Freelance - JavaScript developer and architect

@Lythom


Le plan

  • le web version html 5
  • structure des pages html 5
  • webforms2
  • multimedia et graphisme
  • communications
  • webworkers
  • fichiers et ressources locales
  • device api
  • css3
  • responsive design

Note:

  • Beaucoup de choses
  • Objectif: bien tout comprendre mais pas forcément mémoriser. Ce support permettra de retrouver les infos.

LE WEB VERSION HTML 5


Définition et limites de HTML 5

  • Successeur de HTML 4
  • Spécification d'un ensemble de fonctionnalité et de comportements attendus
  • Chaque fonctionnalité => support navigateur différent
  • Concerne surtout l'API JavaScript
  • Concerne aussi l'accessibilité et l'interactivité

Support des navigateurs

https://caniuse.com/


Compatibilité : Modernizr

Détecte le support d'une fonctionnalité par le navigateur

https://modernizr.com/

Note:

  • Modernizer
    • Au moment d'afficher la page chez l'utilisateur, répond à la question : Le navigateur supporte t'il la fonctionnalité X ?
    • Pivot de l'amélioration progressive (progressive enhancement)
    • Plus fin que la détection de user-agent navigateur

Compatibilité : Polyfills

Ajoute en JavaScript une fonctionnalité native qu'un navigateur n'implémente pas

🔎 <nom_fonctionalité> polyfill <navigateur_cible>

Compatibilité : BabelJS

Permet de faire fonctionner une version récente de javascript (ES6) sur un navigateur qui ne le supporte.

https://babeljs.io/


Impact sur les architectures Web

  • + de fonctionnalités
  • Donc des applications web + riches
  • Donc des architectures + complèxes

Quelques mots clés :

  • Bibliothèque (Library) : A utiliser en l'état
  • Framework : Impose une manière de faire
  • Boilerplate : Squelette d'application pré construit
  • Generators : initialise une appli sur mesure

Note: Architecture logiciel n'est pas l'objet de la formation, on va rester sur les fonctionnalités individuelles et garder l'architecture la plus simple possible.


HTML 5 pour les mobiles

https://caniuse.com/

Les smartphones se sont développés au moment de HTML 5 : Très bon support globalement

Popularité des applications webview (ex: cordova)

Popularité des Progressive Web Applications (PWA)

Note:

  • le principe d'une application webview est d'encapsuler une page web dans une application mobile.
  • PWA uniquement sous Android pour le moment (bientôt Microsoft) et qui permet d'installer une application web offline.

STRUCTURE DES PAGES HTML 5

clic droit -> afficher la source

  • Doctype <!doctype html>
  • Balises sémantiques <section></section>
  • Microformats
<li itemtype="http://microformats.org/profile/hcard" itemscope>
    <div itemprop="fn">Tony Stark</div>
</li>

note:

  • pas de comparatif avec avant car peu d'intérêt de voir ce qu'on ne pouvait pas faire.
  • Doctype pour indiquer au navigateur qu'on est en html5
  • Balises sémantiques et microformats pour permettre une meilleur accessibilités (outils de retranscription vocaux ou brail, robots, référencement)

WEBFORMS2


Nouveaux champs de saisie

<input name="myinput" type="choisir_ci-dessous" />
  • Hidden state (type=hidden)
  • Text (type=text) state and Search state (type=search)
  • Telephone state (type=tel)
  • URL state (type=url)
  • E-mail state (type=email)
  • Password state (type=password)
  • Date state (type=date)
  • Month state (type=month)
  • Week state (type=week)
  • Time state (type=time)
  • Local Date and Time state (type=datetime-local)
  • Number state (type=number)
  • Range state (type=range)
  • Color state (type=color)
  • Checkbox state (type=checkbox)
  • Radio Button state (type=radio)
  • File Upload state (type=file)
  • Submit Button state (type=submit)
  • Image Button state (type=image)
  • Reset Button state (type=reset)
  • Button state (type=button)

Note:


Sliders

https://caniuse.com/#search=sliders (94.5%)

<input type="range" min="0" max="100" step="10" name="range" />
___

datalist

https://caniuse.com/#search=datalist (72.29%)
🔎 `"datalist polyfill"` ou bibliothèque spécifique
  • Liste de suggestions pour assister la saisie
  • Autocompletion sans JavaScript
  • Inidicateur visuels
<input type="range" list="rangelist" min="0" max="100" name="range" />
<datalist id="rangelist">
    <option value="20" label="low">
    <option value="50">
    <option value="80" label="high">
</datalist>

Note: Polyfill à tester ! Fonctionnalité encore mal couverte : mettre en place le cas d'utilisation et tester sur toutes les cibles. Alternativement choisir une solution en JavaScript qui fournira un service équivalent.


placeholder

https://caniuse.com/#search=placeholder (97.7%)

<input type="text" list="valuelist" name="val" placeholder="Saisir une valeur" />
<datalist id="valuelist">
    <option value="abc" label="low">
    <option value="bcd">
    <option value="cde" label="high">
</datalist>
___

Expressions régulières

Exemple 1:

const dateRegexp = /[0-9]{2}-[0-9]{2}-[0-9]{4}/gi
document.getElementById('regexpDate').innerHTML = 'test de dates:' + '<br/>'
document.getElementById('regexpDate').innerHTML += '20/10/1987'.match(dateRegexp) + '<br/>'
document.getElementById('regexpDate').innerHTML += '20-10-1987'.match(dateRegexp) + '<br/>'
Tester
</div>
___

Expressions régulières

Exemple 2:

const bulletLine = /\* (.*)/g
const text = 
`* une ligne
* une autre
* ça va changer !`;
document.getElementById('regexpText').innerHTML = text.replace(bulletLine, '- $1<br/>')
Tester

Expressions régulières

Impossible de penser à tous les cas du premier coup :

🔎 regexp date_fr


Validation automatique

Avec un pattern

<form action="#" name="validate1" onsubmit="alert(document.validate1.val.value);return false;">
<input type="text" list="valuelist2" name="val" placeholder="Saisir une valeur"
       pattern="[A-Za-z]{3}" title="3 lettres minuscule ou majuscules"/>
<datalist id="valuelist2">
    <option value="dfg" label="low">
    <option value="fgh">
    <option value="ghj" label="high">
</datalist>
<input type="submit" />
</form>

Note: Pas de visuel pour indiquer le champ en erreur sur tous les navigateur. Utiliser les sélecteurs de style :valid et :invalid


Validation automatique

Avec un required

<form action="#" name="validate2" onsubmit="alert(document.validate2.val.value);return false;">
<input type="text" list="valuelist3" name="val" placeholder="Saisir une valeur"
       required pattern="[A-Za-z]{3}" title="3 lettres minuscule ou majuscules"  />
<datalist id="valuelist3">
    <option value="jkl" label="low">
    <option value="klm">
    <option value="mpo" label="high">
</datalist>
<input type="submit" />
</form>
Valider par le code (voir slide suivante)

Note: Pas de changement visuel a priori, indication visuelle "required" (souvent asterisque + message) à faire en html.


Validation dans le code

Par exemple en forçant une valeur de la datalist

<form  onsubmit="return formIsValid();">
function formIsValid() {
  const value = document.validate2.val.value
  const list = document.getElementById('valuelist3').options
  if (value === 'secret') return true
  for(var i = 0; i < list.length; i++) {
      if (list.item(i).value === value) return true
  }
  return false;
}

Note: Chercher dans la doc de l'api pour connaitre la structure des données, ici : https://www.w3schools.com/jsref/coll_datalist_options.asp


MULTIMEDIA ET GRAPHISME


Vidéo

https://developer.mozilla.org/fr/docs/Web/HTML/Element/Video

<video src="https://zippy.gfycat.com/WavyMeanDesertpupfish.webm" 
       height="150" loop controls
       poster="https://cdn.pixabay.com/photo/2017/11/11/23/31/curtain-2940999__340.png">
  Votre navigateur ne permet pas de lire les vidéos.
  Mais vous pouvez toujours <a href="https://zippy.gfycat.com/WavyMeanDesertpupfish.webm">la télécharger</a> !
</video>


Audio

https://developer.mozilla.org/fr/docs/Web/HTML/Element/audio

<audio src="http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg" 
       autoplay>
  Votre navigateur ne supporte pas l'élément <code>audio</code>.
</audio>

Canvas

<canvas id='canvas1' width='480' height='320'> Canvas not supported</canvas>
const c = document.getElementById('canvas1');
const ctx = c.getContext('2d');
let x = 100, y = 160, i = 0;
ctx.fillStyle = 'lightgrey'; ctx.fillRect(0, 0, 480, 320);
// axis
ctx.beginPath();ctx.strokeStyle='red';
ctx.moveTo(0,y);ctx.lineTo(480,y);ctx.stroke();
ctx.moveTo(x,0);ctx.lineTo(x,320);ctx.stroke();
// draw function
ctx.beginPath();ctx.moveTo(x,y + Math.sin(0) * 100);
setInterval(function() {
    i++;
    ctx.lineTo(x + i, y + Math.sin(i/50) * 100);
    ctx.strokeStyle='black';ctx.stroke();
}, 1000/60)
Canvas not supported

Dessiner !


SVG

<svg width="480" height="320">
  <rect width="480" height="320" style="fill:lightgrey;" />
  <rect x="100" y="0" width="1" height="320" style="fill:red;" />
  <rect x="0" y="160" width="480" height="1" style="fill:red;" />
  <path id="svgpath" d="M 100 160 L 101 162 L 102 164 L 103 166 L 104 168 L 105 170 L 106 172 L 107 174 L 108 176 L 109 178 L 110 180 L 111 182 L 112 184 L 113 186 L 114 188 L 115 190 L 116 191 L 117 193 L 118 195 L 119 197 L 120 199 L 121 201 L 122 203 L 123 204 L 124 206 L 125 208 L 126 210 L 127 211 L 128 213 L 129 215 L 130 216 L 131 218 L 132 220 L 133 221 L 134 223 L 135 224 L 136 226 L 137 227 L 138 229 L 139 230 L 140 232 L 141 233 L 142 234 L 143 236 L 144 237 L 145 238 L 146 240 L 147 241 L 148 242 L 149 243 L 150 244 L 151 245 L 152 246 L 153 247 L 154 248 L 155 249 L 156 250 L 157 251 L 158 252 L 159 252 L 160 253 L 161 254 L 162 255 L 163 255 L 164 256 L 165 256 L 166 257 L 167 257 L 168 258 L 169 258 L 170 259 L 171 259 L 172 259 L 173 259 L 174 260 L 175 260 L 176 260 L 177 260 L 178 260 L 179 260 L 180 260 L 181 260 L 182 260 L 183 260 L 184 259 L 185 259 L 186 259 L 187 259 L 188 258 L 189 258 L 190 257 L 191 257 L 192 256 L 193 256 L 194 255 L 195 255 L 196 254 L 197 253 L 198 253 L 199 252 L 200 251 L 201 250 L 202 249 L 203 248 L 204 247 L 205 246 L 206 245 L 207 244 L 208 243 L 209 242 L 210 241 L 211 240 L 212 238 L 213 237 L 214 236 L 215 235 L 216 233 L 217 232 L 218 230 L 219 229 L 220 228 L 221 226 L 222 225 L 223 223 L 224 221 L 225 220 L 226 218 L 227 217 L 228 215 L 229 213 L 230 212 L 231 210 L 232 208 L 233 206 L 234 205 L 235 203 L 236 201 L 237 199 L 238 197 L 239 195 L 240 193 L 241 192 L 242 190 L 243 188 L 244 186 L 245 184 L 246 182 L 247 180 L 248 178 L 249 176 L 250 174 L 251 172 L 252 170 L 253 168 L 254 166 L 255 164 L 256 162 L 257 160 L 258 158 L 259 156 L 260 154 L 261 152 L 262 150 L 263 148 L 264 146 L 265 144 L 266 142 L 267 140 L 268 138 L 269 136 L 270 134 L 271 133 L 272 131 L 273 129 L 274 127 L 275 125 L 276 123 L 277 121 L 278 119 L 279 118 L 280 116 L 281 114 L 282 112 L 283 110 L 284 109 L 285 107 L 286 105 L 287 104 L 288 102 L 289 100 L 290 99 L 291 97 L 292 96 L 293 94 L 294 93 L 295 91 L 296 90 L 297 88 L 298 87 L 299 86 L 300 84 L 301 83 L 302 82 L 303 81 L 304 79 L 305 78 L 306 77 L 307 76 L 308 75 L 309 74 L 310 73 L 311 72 L 312 71 L 313 70 L 314 69 L 315 68 L 316 68 L 317 67 L 318 66 L 319 65 L 320 65 L 321 64 L 322 64 L 323 63 L 324 63 L 325 62 L 326 62 L 327 61 L 328 61 L 329 61 L 330 61 L 331 60 L 332 60 L 333 60 L 334 60 L 335 60 L 336 60 L 337 60 L 338 60 L 339 60 L 340 60 L 341 61 L 342 61 L 343 61 L 344 61 L 345 62 L 346 62 L 347 63 L 348 63 L 349 64 L 350 64 L 351 65 L 352 65 L 353 66 L 354 67 L 355 67 L 356 68 L 357 69 L 358 70 L 359 71 L 360 72 L 361 73 L 362 74 L 363 75 L 364 76 L 365 77 L 366 78 L 367 79 L 368 80 L 369 81 L 370 83 L 371 84 " stroke="black" stroke-width="3" fill="none" />
</svg>
const path = document.getElementById('svgpath');
let x = 100, y = 160, i = 0;
path.setAttribute('d', /* … */);
setInterval(function() {
    i++;
    path.setAttribute('d', /* … */);
}, 1000/60)

Dessiner !


WebGL

<canvas id='canvas' width='480' height='320'> Canvas not supported</canvas>
const c = document.getElementById('canvas2');
const gl = c.getContext('webgl');
// instructions opengl a partir d'ici
// c'est trop long pour une slide
Canvas not supported

Dessiner !

Note: Canvas avancé pour utiliser la puissance de la carte graphique.


COMMUNICATIONS


Réseau

Architecture client / serveur

HTTP = protocole de transfert

format du message HTTP = headers + payload

headers = request [ + response ] + métadonnées


JSON

Format d'échange privilégié sur le web aujourd'hui

compatible avec l'objet JavaScript

Autres formats similaires : xml, yaml, formats binaires

{ 
  "menu": "Fichier", 
  "commandes": [ 
      {
          "titre": "Nouveau", 
          "action":"CreateDoc"
      }, 
      {
          "titre": "Ouvrir", 
          "action": "OpenDoc"
      }
   ] 
} 

Note:


XHR2

Ne pas utiliser XHR2 !

https://developer.mozilla.org/fr/docs/Web/API/Fetch_API
+ polyfills si besoin (https://github.com/github/fetch)

fetch('/users.json')
  .then(function(response) {
    return response.json()
  }).then(function(json) {
    console.log('parsed json', json)
  }).catch(function(ex) {
    console.log('parsing failed', ex)
  })

Note: Les Polyfills s'appuiront sur xhr2 de façon transparent pour vous.


fetch typical use

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
}
function parseJSON(response) {
  return response.json()
}
fetch('/users')
  .then(checkStatus)
  .then(parseJSON)
  .then(function(data) {
    console.log('request succeeded with JSON response', data)
  }).catch(function(error) {
    console.log('request failed', error)
  })

CORS (Cross-Origin Resource Sharing )

Système de sécurité implémenté par les navigateurs

Empêche par défaut les requêtes cross-sites
(En anglais cross-domain)

Se configure au niveau du serveur web, les informations sont transmises à travers les headers http

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
Access-Control-Max-Age: 1728000

https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS

Note: Laissez les développeurs expérimentés vous expliquer.


Messaging

https://html.spec.whatwg.org/multipage/web-messaging.html#crossDocumentMessages

Note: Je n'en ai jamais eu l'usage, permet de transmettre des messages entre plus pages de domaines différents. Plus souvent fetch + politique CORS sont utilisés pour communiquer.


WebSocket

Ouverture d'un socket réseau direct entre un serveur et un client. socket = adresse IP + port

Nécessite un serveur websocket dédié, application différente du serveur http

Utiliser des bibliothèques plutôt que l'API native, https://socket.io/

WebRTC est une autre API qui met l'accent sur les performances du streaming, plus complexe

Note: la plupart du temps le même serveur fait à la fois HTTP et Websocket, parfois même au sein du même programme serveur, mais il s'agit bien de 2 mécaniques complètement différentes pour communiquer entre client et serveur.


WEBWORKERS


Modèle mono-thread

  • JavaScript est mono-threadé
  • L'asynchrone est simplement décalé dans la file d'exécution
  • Le système d'événements permet à l'environnement (navigateur, système d'exploitation) de notifier d'une changement
  • Système d'événement est la force des performances de JavaScript

Workers

Agents qui exécutent du code Asynchrone


Shared


FICHIERS ET RESSOURCES LOCALES


LocalStorage et SessionStorage

localStorage.setItem("username", "John");
alert( "username = " + localStorage.getItem("username"));

~ 10Mo de capacité


ApplicationCache Service Workers

https://caniuse.com/#search=Service%20Workers (73.67%) https://developer.mozilla.org/fr/docs/Web/API/Service_Worker_API/Using_Service_Workers

  • Stocke des fichiers en cache
  • Permet de rendre l'entièreté de votre site disponible une fois déconnecté du réseau

Note: Les Services Workers ne sont pas trivial à utiliser mais pas non plus excessivement complèxes. Avancer étape par étape.

Capacité dépends des navigateur et du disque dur de l'utilisateur, en théorie beaucoup (> 100 Mo partagés)


IndexedDB

https://caniuse.com/#search=indexedDB (93.98%)

Stocker des données dans une base de données objets sur le navigateur du client

https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB

Capacité dépends des navigateur et du disque dur de l'utilisateur, en théorie beaucoup (> 100 Mo partagés)


File API

https://caniuse.com/#search=file%20API (94.62%)

Manipuler des fichiers sélectionnés par l'utilisateur côté client

https://developer.mozilla.org/fr/docs/Web/API/File/Using_files_from_web_applications

Plusieurs cas d'utilisation (téléchargement, affichage des images, modification avec envoi)


DEVICE API


Géolocalisation

https://caniuse.com/#search=Geolocation (95.01%)

Connaitre la position de l'utilisateur

if ("geolocation" in navigator) {
  /* géolocalisation possible */
  navigator.geolocation.getCurrentPosition(function(position) {
    do_something(position.coords.latitude, position.coords.longitude);
  })
} else {
  alert("Le service de géolocalisation n'est pas disponible sur votre ordinateur.");
}

Orientation

https://caniuse.com/#search=Orientation (91.8%)

Connaitre l'orientation du téléphone

        window.addEventListener('deviceorientation', handleOrientation);
        function handleOrientation(event) {
          // true pour un référentiel terrestre
          // false pour un référentiel arbitraire
          const absolute = event.absolute;
          // inclinaison autour de l"axe Z
          const alpha    = event.alpha;
          // inclinaison autour de l"axe X
          const beta     = event.beta;
          // inclinaison autour de l"axe Y
          const gamma    = event.gamma;
        }
        

Batterie

https://caniuse.com/#search=battery (69.15%)

Connaitre l'état de charge du périphérique. Support en baisse pour confidentialité.

const battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;

function updateBatteryStatus() {
  console.log("Batterie chargée à : " + battery.level * 100 + " %");
  if (battery.charging) { console.log("Chargement de la batterie"); }
}
battery.addEventListener("chargingchange", updateBatteryStatus);
battery.addEventListener("levelchange", updateBatteryStatus);
updateBatteryStatus();
___

Caméra et micro

https://caniuse.com/#search=getUserMedia (84.56%)

Obtenir un flux de données du micro ou de la webcam.

Nombreux changement d'API, utilisation d'un Shim ou d'un polyfill recommandé.

🔎 Shim getUserMedia

CSS3


Fonts

Problématique très complèxe

Sans webfont

🔎 css font stack
  • Peu de choix, pas de fantaisie

Fonts

Problématique très complèxe

avec webfont

Note: Si possible confier le sujet à un web developer expérimenté. Sinon suivre une méthode éprouvée.


Fonts

Approche naïve

@font-face {
    font-family: 'League Gothic';
    src: url('league-gothic.eot');
    src: url('league-gothic.eot?#iefix') format('embedded-opentype'),
         url('league-gothic.woff') format('woff'),
         url('league-gothic.ttf') format('truetype');
}

Je suis en League Gothic !

<span style="font-family: 'League Gothic'">Je suis en League Gothic !</span>

Sélecteurs CSS 3

https://caniuse.com/#search=CSS3%20selectors (98.16%)

sélecteurs CSS utilisés également dans les biblitohèque de requêtage du DOM

🔎 css selecteur <motif>

https://developer.mozilla.org/fr/docs/Web/CSS/S%C3%A9lecteurs_CSS


Sélecteurs CSS 3

  • [foo^="bar"] (attribute start with)
  • [foo$="bar"] (attribute end with)
  • [foo*="bar"] (attribute contains)
  • :root (racine du document)
  • :nth-child()
  • :nth-last-child()
  • :nth-of-type()
  • :nth-last-of-type()
  • :last-child
  • :first-of-type
  • :last-of-type
  • :only-child
  • :only-of-type
  • :empty
  • :target
  • :enabled
  • :disabled
  • :checked
  • :not()
  • ~

Sélecteurs CSS 3

* Préférez les sélecteurs de class (`.nomDeClasse`) * Évitez les sélecteurs d'identifiant (`#toujoursUniqueSaufParfois`) * Évitez les sélecteurs de type (`span, div, a, button`) * Évitez les sélecteurs universels ou d'attributs seuls * OUI (dans un context fermé) * `.monElement > *`, `input.avecStyleSpecial[type=range]` * NON (dans un context trop large) * `div > *`, `[type=range]`
Note: Sélecteurs de styles à utiliser pour les styles globaux uniquement (reset, choix de design à grande échelle)

Bordures

 .shadowBox {
       width: 200px;
       color: #444444;
       background-color: #ddd; /* Fallback for older browsers */
       background-image: linear-gradient(#E5E5E5, #CFCFCF);
       box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.7) /* inset */; 
       margin: 2rem;
       padding: 1rem;
    }
<style> .shadowBox { display: inline-block; width: 200px; color: #444444; background-color: #ddd; background-image: linear-gradient(#E5E5E5, #CFCFCF); box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.7); margin: 2rem !important; padding: 1rem !important; } .shadowBox2 { display: inline-block; width: 200px; color: #444444; background-color: #ddd; background-image: linear-gradient(#E5E5E5, #CFCFCF); box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.7) inset; margin: 2rem !important; padding: 1rem !important; } </style>
Boite avec ombrage
Boite avec ombrage 2

Couleurs et opacité

espace de couleur sRGB sur le web (sRGB color space)

.shadowBoxLeft {
    background-color: rgba(255, 0, 0, 0.5);
}
.shadowBoxRight {
    background-image: linear-gradient(#0000FF, rgba(0, 0, 255, 0));
    /* #0000FFFF = rgba(0, 0, 255, 1) 
                 = rgb(0, 0, 255) 
                 = hsla(240, 100%, 50%, 1) 
                 = hsl(240, 100%, 50%) */
}
<style> .shadowBox3 { display: inline-block; width: 200px; color: #444444; background-color: rgba(255, 0, 0, 0.5); box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.7); margin: 2rem !important; padding: 1rem !important; } .shadowBox4 { display: inline-block; width: 200px; color: #444444; background-color: rgba(0, 0, 255, 0.3); background-image: linear-gradient(rgba(0, 0, 255, 1), rgba(0, 0, 255, 0)); box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.7) inset; margin-left: -5rem !important; padding: 1rem !important; } </style>
Boite avec ombrage
Boite avec ombrage 2

Transitions et transformations

.spinButton {
    transition: transform 0.5s ease-in;
}
.spinButton:active {
    transform: rotate(270deg);
}
.spinButton.easeout {
    transition: transform 0.5s ease-out;
}
<style> .spinButton { transition: transform 0.5s ease-in; height: 96px; width: 96px; } .spinButton:active { transform: rotate(270deg); } .spinButton.easeout { transition: transform 0.5s ease-out; } </style>

Click me ! Ease-in Click me ! Ease-out

<button class="spinButton">Click me ! Ease-in</button>
<button class="spinButton easeout">Click me ! Ease-out</button>

Note: mots clés: css transition et css transform; performance de transform (scale, opacitity, rotate) meilleures que de modifier width et height en JavaScript.


Animations

@keyframes alwaysSpinButtonAnimation {
    from {transform: rotate(0deg);}
    50% {transform: rotate(90deg);}
    to {transform: rotate(360deg);}
}

.alwaysSpinButton {
    animation-name: alwaysSpinButtonAnimation;
    animation-duration: 1s;
    animation-iteration-count: 10;
    animation-timing-function: linear;
}
<style> @keyframes alwaysSpinButtonAnimation { from {transform: rotate(0deg);} 50% {transform: rotate(90deg);} to {transform: rotate(360deg);} } .alwaysSpinButton { height: 96px; width: 96px; animation-name: alwaysSpinButtonAnimation; animation-duration: 1s; animation-iteration-count: 10; animation-timing-function: linear; } </style>

Click me !

<button class="alwaysSpinButton">Click me !</button>

Note: mots clés: css animation keyframes;


RESPONSIVE DESIGN


Responsive Web Design (RWD)

Contenu qui s'adapte à l'espace d'affichage disponible

  • Grille fluide (float, display: inline-block, flexbox, CSS grid)
  • Media queries (@media screen and (min-width: 1024px) {)
    • Avec breakpoints
    • Sur mesure
  • Element queries (nécessite JavaScript)
  • images et video adaptives
  • SVG et vectoriel

https://developer.mozilla.org/fr/Apps/app_layout/responsive_design_building_blocks


Progressive Enhancement

  • Utiliser les fonctionnalités les répandues en premier
  • Utiliser modernizr pour ajouter des fonctionnalités si possible
  • Avoir un fallback CSS pour les propriétés mal supportées

Retrouver les slides sur https://github.com/Lythom/formation-api-html5-css3

About

No description, website, or topics provided.

Resources

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENCE.md

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published