Il y a 3 ans sur twitter, un certain Christian Heilmann, évangéliste web chez Mozilla, nous avait donné la clé pour comprendre HTML5:
« HTML5, c’est passer des pages statiques aux applications web et des bidouilles aux solutions »
Dans cet article, nous allons redécouvrir comment développer une application web HTML5 à travers une série d’exemples et de conseils.
Bien démarrer avec HTML5
Commençons par une page HTML5 avec le minimum vital :
- un doctype HTML5 sur la première ligne : à ne pas oublier sous peine de faire basculer votre navigateur dans un mode de compatibilité dégradé
- une balise meta UTF-8 à insérer en premier dans la partie « head » de votre document pour éviter les problèmes d’encoding
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Hello</title> <link rel="stylesheet" href="normalize.css"> </head> <div class="container"> Hello </div> </body> </html>
Afin d’uniformiser les rendus entre navigateurs, vous pouvez inclure la librairie normalize.css http://necolas.github.io/normalize.css/ qui ajoute les styles de base ce qui vous évitera bien des surprises.
Si votre application web ne contient que des pages statiques, vous pouvez utiliser le template de page proposé par HTML5 Boilerplate : http://html5boilerplate.com/. Il inclut normalize.css et rajoute une série de bonnes pratiques proposées par la communauté : une feuille de style pour l’impression, des fallbacks pour les anciennes versions d’Internet Explorer, des fichiers de configuration serveur, un layout mobile de base et ses icones associées, des règles CSS simples…
Utilisez la console JavaScript
Le développement d’applications web HTML5 se déporte de plus en plus dans le navigateur lui-même grâce aux nouvelles fonctionnalités offertes par les consoles JavaScript. Pour augmenter sa productivité, il est essentiel de bien la maîtriser :
- avec Google Chrome, la console s’ouvre avec le raccourci clavier Ctrl + Shift + J sous Windows ou ⌥⌘J sous mac
- avec Firefox Ctrl + Shift + K sous Windows ou ⌥⌘K sous mac
On peut par exemple vérifier que notre première page utilise le bon doctype HTML5. Tapez « document.compatMode », vous devriez voir s’afficher « CSS1Compat ».
Les bons liens pour maîtriser les consoles de Firefox et Google Chrome :
- Avec la console Google Chrome : https://developers.google.com/chrome-developer-tools/
- Avec la console Firefox : https://developer.mozilla.org/en-US/docs/Tools
- Devtools secrets : http://devtoolsecrets.com/
Testez dans plusieurs navigateurs
Avec la multiplication des terminaux mobiles, des versions de systèmes d’exploitation et bien sûr des navigateurs, il est fortement conseillé de s’habituer à tester dans au moins deux navigateurs : on pourra par exemple installer Firefox et Google Chrome. Les tests sous Firefox vous éviteront de livrer une application qui ne fonctionnerait qu’avec WebKit, le moteur de rendu de Google Chrome. Si votre application fonctionne correctement dans ces deux navigateurs, vous avez de forte chances pour qu’elle fonctionne aussi dans les autres navigateurs modernes.
Pour tester votre application dans les « Zombie Browsers » tels que Internet Explorer 6 / 7 / 8, téléchargez les machines virtuelles mises à disposition par Microsoft sur leur site http://modern.ie
Construire une page de login pour votre application
La création d’une page de login pour l’utilisateur est l’occasion d’introduire la structure de votre application. Pour créer votre page de login, vous allez avoir besoin d’un premier fichier login.html ainsi que de votre première feuille de style main.css. Profitez-en pour créer une arborescence de répertoires standard, telle que celle proposée dans HTML5 Boilerplate.
Créez maintenant votre page login.html à la racine de votre arborescence :
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Login</title> <link rel="stylesheet" href="vendors/normalize/normalize.css"> <link rel="stylesheet" href="styles/main.css"> </head> <body> <div class="container"> <div class="login"> <form action="index.html" name="login-form"> <input type="text" placeholder="Name" required name="login"> <input type="password" placeholder="Password" required name="password"> <button id="login-btn">Login</button> </form> </div> </div> </body> </html>
Créez une feuille de style main.css vide dans le répertoire /app/styles.
L’utilitaire grunt http://gruntjs.com, que vous pouvez installer avec yeoman http://yeoman.io/, vous permet d’accélérer vos développements en lançant un serveur web et mettant à jour en direct votre page dans votre navigateur après chaque changement :
$ grunt server
Une page de login avec du style : comprendre CSS
Le Box Model
Pour ajouter vos premiers styles, il est nécessaire de maîtriser le concept de « box model ». Pour vous simplifier la vie, il est courant d’utiliser une technique qui uniformise le rendu du « box model » entre les navigateurs. Pour cela, ajoutez la règle CSS suivante :
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
Vous remarquerez que la règle CSS est dupliquée pour prendre en compte les différents navigateurs, ici Firefox et Chrome / Safari via les préfixes « -moz- » pour Mozilla et « -webkit- » pour Chrome et Safari (qui partagent pour l’instant leur moteur de rendu CSS). Les explications de Paul Irish : http://www.paulirish.com/2012/box-sizing-border-box-ftw/
Positionner ses éléments dans la page
Pour centrer la div contenant le formulaire de login, ajoutez les règles CSS suivantes :
html { background-color: lightgrey; min-height: 100%; } body, .container { width: 100%; height: 100%; } .login { position: absolute; top: 50%; left: 50%; width: 14em; margin-left: -7em; height: 6em; margin-top: -3em; padding: 1em; background-color: white; box-shadow: 0.2em 0.2em 0.2em grey; border-radius: 0.2em; }
La technique consiste à passer l’élément avec la classe « login » en position absolue, la placer à 50% du haut de la page et 50% d’un des côtés de la page. On ajuste ensuite le positionnement en appliquant une marge négative de la moitié de la largeur et de la moitié de la hauteur de la boîte.
La synthèse des principes de mise en page CSS est disponible sur le site http://learnlayout.com/, et pour ceux qui souhaiteraient aller plus loin : http://learn.shayhowe.com/advanced-html-css/.
Le principe de l’amélioration progressive
Dans notre exemple, nous avons choisi d’ajouter :
- une légère ombre avec la propriété box-shadow
- des coins arrondis avec la propriété border-radius
Pour les anciens navigateurs qui ne supportent pas cette propriété, l’ombre n’apparaîtra pas : cela n’empêche pas l’utilisateur de s’authentifier. Cette technique d’amélioration progressive est une des bonnes pratique à utiliser dans la suite de votre projet.
Manipuler les styles avec la console
Plutôt que de modifier les styles dans vos fichiers sources, puis de recharger la page dans le navigateur, vous gagnerez du temps en utilisant directement la console de Chrome. Utilisez les nombreux raccourcis clavier pour augmenter votre productivité : la liste est disponible via la touche F1.
Si vous souhaitez ajuster la taille de votre formulaire, cliquez sur celui-ci avec le bouton droit pour « inspecter l’élément ». Double cliquez sur les propriétés CSS pour les modifier en direct. Utilisez la touche majuscule et les flèches du clavier pour changer les valeurs par « crans ».
Vous pouvez aussi modifier votre feuille de style dans l’onglet « source », en tapant ⌘O ou Control O sous Windows, puis en tapant les premières lettres de main.css. Faites vos modifications, puis sauvegardez les localement.
L’historique des modifications est conservé par le navigateur (bouton droit sur votre fichier, puis « Local Modifications… »), et à tout moment vous pouvez revenir en arrière avec l’option « revert ».
Ajouter des effets visuels
Ajoutons maintenant un effet de dégradé :
html { background-color: lightgrey; min-height: 100%; background: radial-gradient(ellipse at center, #ddd 1%, #aaa 100%); }
Rendez-vous sur la présentation de Léa Verou http://lea.verou.me/css3-gradients pour expérimenter en live toutes les options des dégradés CSS.
Si la soumission du formulaire de login est un peu longue, mieux vaut prévoir un effet visuel pour faire comprendre à l’utilisateur que son action a bien été prise en compte. C’est l’occasion d’utiliser des effets de transitions CSS en réutilisant le principe des boutons du projet ladda : http://lab.hakim.se/ladda/
<link rel="stylesheet" href="vendors/ladda/ladda.min.css"> <script src="vendors/ladda/spin.min.js"></script> <script src="vendors/ladda/ladda.min.js"></script> <button id="login-btn" class="ladda-button" data-style="expand-right" data-size="s" data-color="blue"><span class="ladda-label">Login</span></button>
Modifions notre feuille de style pour terminer la boite de login :
.login input,.login button { width: 100%; margin-bottom: 0.5em; border-radius: 2px; border: 1px solid lightgray; }
Les bonnes pratiques dans vos feuilles de style
L’approche classique pour créer un premier design est d’utiliser la librairie Bootstrap : http://twitter.github.io/bootstrap/. En utilisant Bootstrap, vous démarrez avec des noms de classe standards qui suivent les recommandations SMACSS http://smacss.com/. C’est aussi une manière d’apprendre le « bon » vocabulaire du design pour chacun des types d’éléments. Si votre application le requiert, rien ne vous empêchera par la suite d’abandonner Bootstrap pour développer votre propre style.
Quelques conseils :
- plusieurs bonnes pratiques pour le design des feuilles de styles sont disponibles dans le styleguide de Google : http://google-styleguide.googlecode.com/svn/trunk/htmlcssguide.xml
- créez un fichier « overrides.css » pour y placer les règles CSS qui surchargent les feuilles de styles des librairies tierce : cela vous permettra de mettre à jour facilement les versions, sans écraser vos éventuelles modifications
- créez un fichier « ugly.css » pour y mettre les styles temporaires : on évite ainsi de « polluer » nos « vraies » feuilles de styles
- créez une classe .debug à appliquer sur vos éléments qui posent problème. Ajoutez par exemple la règle « border: 1px solid lime »
- pour les écrans « retina », doublez la taille de vos images, quitte à utiliser une compression plus forte, et utilisez un ratio de 50% : par exemple pour afficher une image à l’écran de 100 pixels de large, utilisez une image source de 200 pixels et fixez la largeur à 100 pixels
Pensez « mobile » dès le début : comprendre le Viewport et les Media Queries
Commencez, dès les premières pages, à construire votre application pour qu’elle soit utilisable sur les terminaux mobiles. Il sera beaucoup plus facile ensuite d’optimiser vos pages pour des situations plus confortables, comme un ordinateur de bureau qui possède plus d’espace visible disponible, de mémoire et de puissance processeur.
Pour faciliter la « chorégraphie » de votre contenu entre le mode mobile et le mode desktop, pensez votre contenu sous la forme de bloc comme indiqué ci-dessous :
Profitez-en pour utiliser, si besoin, les nouvelles balises HTML5 : header, footer…
Découvrir le Viewport
Si vous testez votre application dans un navigateur mobile, il y a de forte chances pour que vous soyez déçu : votre page est tassée, illisible, voire coupée. Les navigateurs proposent la notion de « viewport » aux développeurs afin d’optimiser l’affichage sur mobile :
Il est possible de contrôler le niveau de zoom du viewport afin d’obtenir le résultat souhaité via une simple balise meta :
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Pour tester la configuration par défaut de vos terminaux mobiles, rendez-vous sur http://mobitest.me/.
Responsive Design avec les Media Queries
Pour afficher un contenu adapté aux anciens navigateurs et aux téléphones mobiles, on choisira de présenter à l’utilisateur une mise en page simple par défaut.
Grâce aux « Media Queries CSS » il vous est possible de détecter les utilisateurs qui disposent de plus d’espace disponible. Vous pourrez alors leur proposer une mise en page plus avancée. Par exemple, si on souhaite afficher plus d’images de produits sur un écran d’une largeur minimum de 40em, on choisit de réduire la taille des images à 50% :
@media screen and (min-width: 40em) { .product-img { width: 50%; float: left; } }
Les Media Queries ne sont pas forcément simples à développer ou à tester. On peut s’aider de l’utilitaire en ligne http://gridpak.com/ qui propose de configurer visuellement le résultat attendu et qui prépare les feuilles de styles associées.
Une bonne base pour démarrer un site web mobile se trouve à l’adresse suivante : http://html5boilerplate.com. Pour compléter notre boite à outil mobile, il nous manque quelques exemples qu’on ira piocher sur le site http://bradfrost.github.io/this-is-responsive/patterns.html. Enfin, pour gérer des transitions fluides entre chaque page, on peut s’inspirer des exemples disponibles à cette adresse : http://tympanus.net/Development/PageTransitions/ :
.pt-page-moveToLeft { -webkit-animation: moveToLeft .6s ease both; -moz-animation: moveToLeft .6s ease both; animation: moveToLeft .6s ease both; } @-webkit-keyframes moveToLeft { to { -webkit-transform: translateX(-100%); } } @-moz-keyframes moveToLeft { to { -moz-transform: translateX(-100%); } } @keyframes moveToLeft { to { transform: translateX(-100%); } }
Créer un formulaire de contact
Voici un exemple de formulaire de contact pour lequel les nouveaux champs des formulaires HTML5 sont bien pratiques :
Prenons un exemple avec le téléphone : il est possible d’ajouter des règles de validations spécifiques :
Nous utilisons dans ce cas une expression régulière reprise du site http://html5pattern.com :
<div class="control-group" id="phone"> <label class="control-label" for="input-when">Phone number</label> <div class="controls"> <input id="input-when" class="span4" type="text" value="" required pattern="^(?:0|\(?\+33\)?\s?|0033\s?)[1-79](?:[\.\-\s]?\d\d){4}$"> </div> </div>
Sur http://www.wufoo.com/html5/, vous trouverez des exemples pour chacune des possibilités des formulaires HTML5.
La mise en page du formulaire a été réalisée grâce aux classes spécifiques de la librairie Bootstrap. Pour les dates et les heures, on a ici utilisé bootstrap-datepicker et bootstrap-timepicker disponibles sur http://github.com.
Optimisez les performances
Optimisez vos images
Au delà des temps de chargement des requêtes AJAX de votre application, ce sont souvent les temps de chargement des images qui plombent les performances d’une application web. Une technique consiste à charger des images de taille plus réduite pour les mobiles et des images haute qualité pour les grands écrans. Un exemple d’implémentation avec la librairie Response.js http://responsejs.com/ :
<-- Load lo-fi.png for devices 0–640px wide or no-js. Load hi-fi.png for devices 641px+ wide. --> <img src="lo-fi.png" data-min-device-width-641="hi-fi.png" alt="example" />
Pour éviter de multiples appels au serveur, il est aussi possible d’insérer directement dans vos feuilles de styles les icônes de votre interface en convertissant vos images en base64, par exemple avec le site http://dataurl.net/#dataurlmaker :
<img width="11" height="14" src="data:image/gif;base64,R0lGOD lhCwAOAMQfAP////7+/vj4+Hh4eHd3d/v7+/Dw8HV1dfLy8ubm5vX19e3t7fr 6+nl5edra2nZ2dnx8fMHBwYODg/b29np6eujo6JGRkeHh4eTk5LCwsN3d3dfX 13Jycp2dnevr6////yH5BAEAAB8ALAAAAAALAA4AAAVq4NFw1DNAX/o9imAsB tKpxKRd1+YEWUoIiUoiEWEAApIDMLGoRCyWiKThenkwDgeGMiggDLEXQkDoTh CKNLpQDgjeAsY7MHgECgx8YR8oHwNHfwADBACGh4EDA4iGAYAEBAcQIg0Dk gcEIQA7" alt="File Icon">
Optimisez vos fontes
Il est de plus en plus courant de voir l’utilisation de la nouvelle règle CSS font-face pour charger des icônes vectorielles : on pense par exemple à FontAwesome http://fortawesome.github.io/Font-Awesome/. Si vous n’utilisez pas l’ensemble des icônes de FontAwesome, vous pouvez vous construire une fonte spécifique avec un sous-ensemble d’icônes grâce à http://www.icnfnt.com.
Même technique pour les polices Google : ne choisissez par exemple que le sous-ensemble « latin » de Open Sans :
<link href="http://fonts.googleapis.com/css?family=Open+Sans&subset=latin" rel="stylesheet" />
La page de Google expliquant les optimisations possibles de leurs polices : http://www.igvita.com/2012/09/12/web-fonts-performance-making-pretty-fast/.
Utilisez Appcache pour vos ressources statiques
Il est possible de mettre en cache une grande partie des ressources statiques grâce à l’Appcache HTML5. Le comportement de cette API peut sembler déroutant dans un premier temps, mais avec les explications disponibles sur http://appcachefacts.info/ et en utilisant les nouvelles fonctionnalités de la console Firefox http://flailingmonkey.com/application-cache-not-a-douchebag, vous devriez enfin comprendre son fonctionnement.
Le plus simple reste d’utiliser confess https://github.com/jamesgpearce/confess qui vous générera le manifeste à votre place. Un exemple de résultat pour le fichier manifest :
CACHE MANIFEST # This manifest was created by confess.js, http://github.com/jamesgpearce/confess # # Time: Fri Dec 23 2011 13:12:32 GMT-0800 (PST) # Retrieved URL: http://functionsource.com/ # User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/... CACHE: /images/icons/logo.png /javascripts/lib/legacy.js /stylesheets/light.css http://mysite.com/images/header.png ... http://www.google-analytics.com/ga.js NETWORK: *
Piochez dans les API HTML5
Voici quelques autres exemples d’API HTML5 qui complètent la panoplie du développeur web :
SessionStorage
L’API SessionStorage permet de stocker des valeurs en session. Dans notre formulaire de login, nous aurions pu stocker le nom de l’utilisateur pour l’afficher dans la page suivante :
<input type="text" placeholder="Name" required oninput="sessionStorage.setItem('username', this.value);" name="login">
Il est alors possible d’accéder à la valeur « username » depuis une autre page avec :
sessionStorage.getItem('username');
LocalStorage
L’objectif de LocalStorage est de remplacer le système vieillissant des cookies. A la différence de SessionStorage, l’API LocalStorage écrit, de façon permanente et synchrone, ses données sur le disque :
Au lieu de stocker de simples String, vous pouvez stocker des objets JavaScript en les sérialisant/désérialisant avec JSON :
var myObject = ['myValue1', 'myValue2']; localStorage.myItem = JSON.stringify(myObject); var myResult = JSON.parse(localStorage.myItem);
LocalStorage propose un système de quota d’espace disponible qui diffère entre chaque navigateur. Via des APIs spécifiques à chaque navigateur, on peut récupérer la taille de l’espace disponible restant :
window.webkitStorageInfo.queryUsageAndQuota(webkitStorageInfo.TEMPORARY, //the type can be either TEMPORARY or PERSISTENT function(used, remaining) { console.log("Used quota: " + used + ", remaining quota: " + remaining); }, function(e) { console.log('Error', e); } );
La documentation disponible sur le site des développeurs Google Chrome est particulièrement bien faite sur ce sujet : https://developers.google.com/chrome/whitepapers/storage
Geolocalisation
L’API de géolocalisation est très facile à utiliser et peut être mise à profit pour afficher, par exemple, la carte des magasins les plus proches de l’utilisateur. Pour cela, on utilise le service Google Maps et on passe en paramètre la latitude et la longitude :
if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(successFunction, errorFunction); } else { alert('No Geolocation.'); } function successFunction(position) { var map = new google.maps.Map(document.getElementById('google_canvas'), { zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP }); var geolocate = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); var infowindow = new google.maps.InfoWindow({ map: map, position: geolocate, content: '' }); map.setCenter(geolocate); }
Microdata
L’utilisation des microdatas dans la page permet aux moteurs de recherche de mieux référencer les sites. Si nous reprenons notre exemple avec les magasins :
<header itemscope itemtype="http://schema.org/Organization"> <h1 itemprop="name">Magasin</h1> <div itemscope itemtype="http://schema.org/PostalAddress"> <div class="address"> <span itemprop="streetAddress">1 rue du Paradis</span> <span itemprop="postalCode">75001</span> <span itemprop="addressLocality">PARIS</span> <span itemprop="addressCountry">ILE DE FRANCE</span> <span itemprop="addressCountry">France</span> </div> </div> <span itemprop="telephone">Tel.<a href="tel:0101010101">0101010101</a></span> </header>
Dernières étapes avant de publier
Pour chaque fonctionnalité HTML5 que vous utilisez, n’oubliez pas de vérifier si son utilisation est recommandée. Deux sites peuvent vous aider : http://html5please.com/ et http://caniuse.com/. Enfin, avant de déployer votre application web, vérifiez votre checklist : http://webdevchecklist.com/.
Pour la prochaine version de votre application web, n’hésitez pas à consulter la page suivante http://platform.html5.org/ qui rassemble toutes les APIs et les dernières nouveautés HTML5.