Quantcast
Channel: Alsacreations.com - Apprendre
Viewing all 405 articles
Browse latest View live

Tutoriel : CSS Grid Layout en production ?

$
0
0

Flexbox et Grid Layout comptent parmi les spécifications qui ont le plus contribué à l'évolution des styles CSS durant ces dernières années. Véritables bénédictions pour l'intégrateur, ces deux approches ont littéralement révolutionné les modes de mise en page classiques et renvoyé les anciennes techniques bancales aux oubliettes.

Les premières ébauches de spécifications Flexbox datent de 2009, tandis que le premier brouillon officiel de Grid Layout est apparu en 2012. Bien que tous deux supportés simultanément dès la sortie d'Internet Explorer 10 en octobre 2012, l'adoption de Grid Layout en est encore à ses balbutiements en raison... d'Internet Explorer.

Quelles sont les raisons de ces réticences, et surtout, comment utiliser Grid Layout en production dès aujourd'hui ?

Une compatibilité acceptable...

À la mi-2018, les chiffres étaient déjà fort éloquents : 90% de support en France, et 88% dans le monde entier. La grande majorité des navigateurs de bureau et mobiles reconnaissent cette spécification depuis plusieurs versions comme le montre l'indispensable référence Can I Use.

Seuls absents à ce jour : Opera Mini (0.14% d'usage en France) et... Internet Explorer version 9 et inférieure (0.1% d'usage en France).

Sachez tout de même que des sites tels que Slate, Financial Times, Stripe, Slack, Medium et Yandex emploient Grid Layout en production : http://www.gridexamples.com/

Mais un support partiel d'Internet Explorer

Microsoft Edge 16, sorti en septembre 2017, reconnaît la dernière version de la spécification Grid dans son intégralité.
Par contre, les anciennes moutures d’Internet Explorer sont un peu plus à la traîne : IE10, IE11 et les premières éditions de Edge supportent officiellement Grid Layout mais se réfèrent à une antique version de la spécification qui est bien moins complète, et de nombreuses fonctionnalités y sont donc manquantes.

Une question de version

L'implémentation de Grid par les différentes version d’Internet Explorer est simple et compliquée à la fois :

  • IE9 et inférieur : pas de support
  • IE10, IE11, Edge 12-15 : ancienne spécification (support partiel)
  • Edge 16+ : nouvelle spécification

Dans la suite de cet article, le terme "Internet Explorer" fait référence aux versions "IE10, IE11, Edge 12-15".

Le support partiel d'Internet Explorer s'explique par le fait que la spécification Grid Layout a évolué plus rapidement que lui, et se manifeste principalement par :

  • Des fonctionnalités manquantes (qui n'existent tout simplement pas dans IE),
  • Des fonctionnalités divergentes (qui s'écrivent différemment ou opèrent autrement sur IE que les autres),
  • Des bugs (eh ouais !).

Fonctionnalités manquantes

Parmi les lacunes principales de ces versions, on dénombre le manque de support des certaines fonctionnalités majeures détaillées ci-après.

Pas de placement automatique

Première particularité notable dans l'intégration des grilles dans Internet Explorer : il n'y a pas de notion de Placement Automatique des éléments sur IE : Il faut placer chaque élément individuellement et explicitement dans chaque cellule.

Il en découle, fort logiquement qu'aucune des propriétés standards suivantes n'est reconnue par IE :

  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid (propriété raccourcie globale)
Pas de gouttières

Ne craignez rien pour votre maison, les seules gouttières dont vous serez privés sur Internet Explorer sont celles permettant d'espacer les rangées et les colonnes de la grille.

Les propriétés grid-row-gap, grid-column-gap et grid-gap (et leur équivalent plus récent gap tout court) prévues pour gérer aisément les gouttières dans Grid Layout sont totalement absentes du vocabulaire d'IE et il ne s'y passera rien du tout s'il les croise au détour d'une ligne de code.

La seule manière de s'en sortir est de prévoir une colonne (ou rangée) supplémentaire qui fera office de gouttière :

.container {
  display: -ms-grid; /* version IE */
  display: grid;
  grid-gap:  1rem;
  -ms-grid-columns:  1fr 1rem 1fr; /* version IE */
  grid-template-columns:  1fr 1fr;
} 
Pas de zones nommées

Grid Layout propose une méthode alternative de construction : les zones et lignes nommées.

Les propriétés grid-template-areas et grid-area permettent de créer des zones nommées et de s'y placer... mais elles non plus ne sont pas supportées par Internet Explorer.

Ce genre de syntaxe sera donc inopérant sur IE :

.container {
  display: grid;
  grid-template-areas: "a b" 
                       "c d";
} 
.child {
  grid-area: a;
}
Divers autres manquements

Pour finir, n'oublions pas qu'Internet Explorer ignore totalement :

  • Les valeurs auto-fit et auto-fill très pratiques pour construire des grilles automatiques,
  • Le mot-clé dense qui permet de remplir les cases laissées libres dans la grille.

Des fonctionnalités divergentes

Depuis leur version de brouillon (adoptée à l'époque par IE10 précipitamment), certaines propriétés ou valeurs ont muté... sans que Internet Explorer ne suive le wagon.

Des propriétés différentes... et préfixées

C'est un jeu auquel nous aurions aimé nous passer : il faut deviner quelles propriétés sont préfixées pour Internet Explorer et, surtout, pressentir quel est leur petit nom sur ce navigateur car il risque d'être différent du reste du monde.

Voici la liste des propriétés de grille reconnues sur IE mais sous un nom différent des standards :

propriété standard équivalent IE
display: grid display: -ms-grid
grid-template-columns -ms-grid-columns
grid-template-rows -ms-grid-rows
grid-row-start -ms-grid-row
grid-column-start -ms-grid-column
grid-row-end -ms-grid-row-span (plus ou moins équivalent)
grid-column-end -ms-grid-column-span (plus ou moins équivalent)
align-self -ms-grid-row-align
justify-self -ms-grid-column-align

Exemple de code CSS standard :

.container {
  display: grid;
  grid-template-rows:  20rem 100px 1fr;
  grid-template-columns:  100px 1fr 10rem;
} 
.child {
  grid-column: 1 / 3;
}

Équivalent sur Internet Explorer :

.container {
  display: -ms-grid;
  -ms-grid-rows:  20rem 100px 1fr;
  -ms-grid-columns:  100px 1fr 10rem;
} 
.child {
  -ms-grid-column: 1;
  -ms-grid-column-span: 2;
}

Fort heureusement, l'outil autoprefixer évoqué en détail plus loin gère très bien ces propriétés sans que vous ayez à vous en soucier.

repeat()

Dans les premières spécifications, la valeur-fonction repeat() est née sous une mouture totalement différente de ce que l'on connaît actuellement. Internet Explorer est là pour nous rappeler ce temps jadis.

valeur standard équivalent IE
repeat(10, 1fr 2rem) (1fr 2em)[10]

Il est donc parfaitement possible d'appliquer cette valeur pour répéter des motifs de pistes, mais en faisant bien attention de respecter la syntaxe particulière d'IE.

Des bugs

Ah ben forcément on ne pouvait pas y couper : Internet Explorer, tout comme les autres navigateurs, est parfois un peu buggué quand il s'agit de CSS, et plus particulièrement lorsqu'une spécification est récente. Il faut parfois attendre les mises à jour des navigateurs pour voir certains bugs se résorber ou disparaître.

Pour vous aider à patienter, Rachel Andrew, papesse de Grid Layout, a concocté un espace collaboratif sur Github nommé "Gridbugs" et qui compile un ensemble de bugs (et solutions) fréquents concernant Grid Layout : https://github.com/rachelandrew/gridbugs

N'hésitez pas une seconde à placer ce lien dans vos favoris.

Alors on fait quoi concrètement ?

Dans la pratique, nous disposons de trois solutions pour gérer les lacunes actuelles des navigateurs :

  • notre cerveau,
  • l'outil PostCSS Autoprefixer,
  • la règle CSS @supports().

Je ne vais pas entrer dans le détail de la première option, mais plutôt m'intéresser aux deux suivantes.

Autoprefixer

Autoprefixer est un (superbe) outil permettant d’ajouter tous les préfixes CSS à vos propriétés de manière automatisée et, surtout, uniquement pour les navigateurs le nécessitant encore.

Par défaut, Grid Layout n’est pas activé sur Autoprefixer. Il faut l’activer dans les options en passant grid: false à grid: true.

Autre point important : la dernière version d'Autoprefixer a fait d'énormes progrès en matière de gestion des préfixes et fonctionnalités pour Internet Explorer (depuis la version version 8.6.4 précisément), il est dorénavant beaucoup plus fiable et vivement conseillé dans vos projets (pas que pour Grid Layout d'ailleurs).

Pour comprendre comment fonctionne le nouveau Autoprefixer dans les détails, je vous invite à consulter cette ressource anglophone très complète : https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/

Ce qu'apporte Autoprefixer ?

Comme son nom l'indique, Autoprefixer ajoute automatiquement les préfixes (-webkit-, -moz-, -ms-, etc.) lorsque cela est nécessaire sur une propriété ou sur une valeur.

Mais il va bien au-delà puisqu'il est capable de convertir totalement des propriétés pour les rendre compatibles.

Les propriétés suivantes, par exemple, n'ont pas d'équivalent dans Internet Explorer, mais elles sont reconnues grâce à Autoprefixer, qui les transforme en "syntaxe IE-friendly" :

  • grid-template-areas
  • grid-template
  • grid-row-end
  • grid-column-end
  • grid-row
  • grid-column
  • grid-area
  • grid-row-gap
  • grid-column-gap
  • grid-gap

Exemple de code standard :

.container {
  display: grid;
  grid-gap:  1em;
  grid-template:  "a b"  minmax(100px, 1fr) 
                  "c d"  20em / 1fr 1fr;
} 
.child {
  grid-area: a;
}

Converti grâce à Autoprefixer en :

.container {
  display: -ms-grid;
  display: grid;
  grid-gap:  1em;
  -ms-grid-rows:  minmax(100px, 1fr) 1em 20em;
  -ms-grid-columns:  1fr 1em 1fr;
  grid-template:  "a b"  minmax(100px, 1fr) 
                  "c d"  20em / 1fr 1fr;
}
.child {
  -ms-grid-row:  1;
  -ms-grid-column:  1;
  grid-area: a;
}

Et hop, emballé c'est pesé ! Il devient bien plus simple de gérer le cas Internet Explorer grâce à ce genre d'outil.

Notez que grâce à Autoprefixer, rien de nous empêche désormais d'employer la méthode de placement via zones nommées (areas).

@supports ()

La règle @supports, également nommée “règle conditionnelle”, permet de détecter la reconnaissance de certaines propriétés CSS au sein du navigateur.

Introduite au sein des spécifications dans le module des CSS conditionnelles, au même titre que les Media Queries, la règle @supports se rapproche de ce que peut nous offrir un outil tel que Modernizr, à savoir détecter le support ou non d’une fonctionnalité CSS chez votre visiteur afin de prévoir une alternative au besoin.

  • @supports est reconnue depuis à partir de Microsoft Edge, il est donc totalement ignoré par IE11 et inférieurs.
  • le test (display: grid) n'est reconnu qu'à partir de Edge 16
@supports (display: grid) {
  /* will return true for any browser supporting the spec, Edge included */
}

Cette syntaxe de @supports nous permet de ne conserver que les navigateurs vraiment totalement compatibles avec les versions stables de Grid Layout, en excluant IE10, IE11 et Edge 15 qui ne reconnaissent que la version préfixée.

Quelles sont mes options ?

Pour finir, voyons quelles sont les options à ma disposition en regard de mes contraintes de compatibilité navigateurs.

Je suis libre ! (Edge minimum)

  1. on applique Grid Layout pour les navigateurs modernes uniquement (Edge+) via @supports
  2. pas besoin d'Autoprefixer

Je dois absolument tenir compte d'IE10 et IE11

  1. on applique Grid Layout pour tous les navigateurs
  2. on active Autoprefixer pour pallier les lacunes d'IE
  3. on emploie des propriétés et des fonctionnalités capables d'être prises en compte par Autoprefixer et on fait attention où l'on met les doigts pour ne pas se faire pincer très fort.

Je dois absolument tenir compte d'IE9 (OMG!)

  1. il va falloir prévoir une alternative en positionnements ancestraux (float / inline-block). Courage !
  2. on applique Grid Layout pour les navigateurs modernes uniquement (Edge) via la règle @support
  3. pas besoin d'Autoprefixer mais on doit faire le double du boulot (deux versions de positionnements à maintenir)

Conclusion

Rien de tel qu'un petit exemple concret pour illustrer l'ensemble de cet article et conclure en beauté.

L'objectif à atteindre est de concevoir un gabarit de 3 éléments de largeur identique (1/3 de l'espace disponible) et séparés par une gouttière de 1em.

.container {
  display: flex;  /* 1 */
  justify-content: space-between;  /* 2 */
}

.container >  * {
  flex-basis: calc(100%  /  3  - (1em  *  2  /  3));  /* 3 + 4 */
}

@supports (display: grid) { /* 5 */
  .container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 1em;
  }
}

/* 
Explications :
1- l'alternative est ici Flexbox (prévoir Autoprefixer pour les navigateurs nécessiteux)
2- on prévoit une "gouttière" de 1em
3- on calcule la taille des 3 enfants par rapport à la gouttière
4- on préfère flex-basis à width pour éviter de devoir écraser width dans Grid Layout 
5- seuls les navigateurs modernes (Edge) se reconnaîtront ici
*/

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com


Actualité : Les vidéos de la KiwiParty 2018 sont en ligne

$
0
0

Depuis quelques jours, les vidéos des conférences de la KiwiParty sont disponibles en ligne, rassemblées dans la Playlist Alsacréations.

L'ensemble des 12 conférences de la journées y sont réunies et visionnables. Nous remercions encore chaleureusement Blackblitzpour avoir assuré ce streaming et ces enregistrements de qualité.

N'hésitez pas à consulter le compte-rendu complet de l'événement pour vous replonger dans cette journée de partage et d'informations.

Publié par Alsacreations.com

Astuce : Inspecter un DOM qui bouge

$
0
0

Avez-vous déjà tenté d'inspecter un document HTML, pour dénicher des bugs ou examiner sa conception, alors même que sa structure change... à cause de JavaScript ?

Prenons un cas concret : le champ de recherche avec autocomplétion de Wikipédia qui affiche une liste déroulante de liens. Celle-ci apparaît lorsque du texte est entré, mais disparaît du document lorsqu'on perd le focus (par exemple lorsqu'on cherche à l'inspecter avec la souris). Il ne s'agit pas juste d'un élément masqué mais bien retiré du DOM (Document Object Model). Embêtant pour aller analyser en direct son contenu, ses styles, etc.

Tentative d'inspection DOM

Chrome permet de mettre en pause l'exécution de la page lorsqu'un élément du DOM se voit modifié :

  • Si l'un de ses descendants est modifié/ajouté/supprimé
  • Si ses attributs changent
  • Si le noeud est supprimé

Pour répondre à notre problématique initiale, il faut donc cibler un élément parent qui reste sur la page quoiqu'il arrive et choisir Break on puis subtree modifications.

Un breakpoint est ajouté, de telle sorte que lorsque "sous-arbre" DOM sera modifié, on pourra mettre en pause le fil d'exécution et examiner cela.

Break on subtree modifications

Maintenant, toute action va provoquer un bloquage (Paused in debugger) et la vue de la page sera grisée. Durant ce temps, toute inspection du DOM est possible, en prenant son temps (l'élément est figé et ne disparaît plus).

Il est bien entendu possible de reprendre le fil, progressivement ou totalement, avec les boutons correspondants affichés à l'écran. Toute autre modification du DOM provoquera un nouvel arrêt, donc tout va dépendre de la façon dont le script procède.

Inspection en pause

Pour visualiser les breakpoints actifs, il faut se rendre dans le l'onglet DOM Breakpoints pour pouvoir les désactiver, ré-activer ou s'en débarasser définitivement.

Inspect breakpoint

Firefox ne dispose pas directement de la même fonctionnalité mais beaucoup de travail a été effectué du côté de JavaScript avec MutationObserver. Il y a également l'astuce moins pratique de mettre en pause le debugger après un temps mesuré, avec cette instruction entrée dans la console :

setTimeout(() => { debugger; }, 2000)

Vous avez 2 secondes pour déclencher les modifications sur le document avant que celui-ci ne se fige. L'inspection d'éléments est alors possible dans l'onglet approprié, mais la visée à souris ne fonctionnera pas. Pour reprendre le fil et sortir de la pause, cliquez sur le bouton Lecture ou appuyez sur F8.

Debugger Firefox

Publié par Alsacreations.com

Actualité : Rendez-vous à Paris Web 2018 !

$
0
0

Paris Web est le gros événement Web à ne pas manquer début Octobre : pour sa 13e édition, ce cycle de conférences et ateliers rassemblera une cinquantaine d'orateurs et d'oratrices en pointe dans leurs sujets. Le thème de cette année est : Cultivons le Web de demain.

Certains thèmes sont fondamentaux à Paris Web depuis sa création. Cette édition 2018 ne fait pas exception :

  • le Front-End sera présent en très grande force (React, Vue, CSS, JS, SVG, etc.), avec notamment un certain Raphaël qui vous fera travailler Grid Layout ;)
  • l'Accessibilité est toujours de la partie, que ce soit dans les sujets (WCAG 2.1, ateliers, etc.), ou sur place (LSF, vélotypie, accès aux PMR, boucle magnétique sur place, etc.)
  • la Qualité Web est plus que jamais présente, via la performance, de nombreux sujets de sécurité, les boulettes en prod, etc.
  • le Web Design, notamment via de nombreux sujet sur l'UX, ou des choses plus spécifiques comme l'Atomic Design, les outils de prototypage, etc.

À noter, cette année vous verrez entre autres trois intervenants travaillant au W3C sur les relations avec les développeurs/développeuses, l'internationalisation des sites et le style guide… du W3C, avec l'un des co-créateurs de… CSS : Bert Bos.

D'autres thèmes/sujets comme l'IA, l'éthique, la vie privée, les jeux vidéos, etc. sont également présents, afin de vous ouvrir à d'autres sujets.

Les conférences auront lieu à l'IBM Client Paris, les 4 et 5 Octobre.

Les ateliers quant à eux auront lieu à la Web School Factory le 6 Octobre.

Pour en savoir plus :

Alors, on vous donne rendez-vous à Paris Web 2018 ?

Publié par Alsacreations.com

Actualité : Gagnez une entrée à dotJS et dotCSS

$
0
0

Le duo de conférences dotCSS et dotJS aura bientôt lieu, à Paris, le 8 et 9 novembre 2018. Cet événement majeur dans le monde du Web réunira des oratrices et orateurs de tous les continents, dont certains noms vous sont probablement déjà connus : Sara Soueidan, Una Kravets, Sacha Greif, John Papa... DotJS sera par ailleurs animé par le flamboyant Christophe Porteneuve (Delicious Insights).

À cette occasion, l'organisateur dotConférences et Alsacréations vous proposent :

  • de gagner une entrée !
  • de bénéficier de 20% de réduction sur le tarif billetterie

dotJS 2018

Gagner une entrée

Nous n'allons pas faire compliqué car nous savons que les passionné·e·s de CSS et JS voient leur temps compté avec tous les bugs rencontrés au quotidien, c'est pourquoi le défi se résume à re-twitter le twit relatif à la présente actualité (inception!):

Un tirage au sort sera effectué pour déterminer qui bénéficiera de cette entrée offerte.

Bénéficier de 20% de réduction sur le tarif billetterie

Pour ceci, c'est encore plus simple, vous utilisez le code "ALSACREATIONS" lors de l'inscription (attention si vous oubliez le S vous aurez un malus de +20%!). Par la magie des liens, on vous facilite la vie, à la portée d'un clic :

Merci à dotJS/dotCSS pour cette nouvelle édition prometteuse, au plaisir de vous y retrouver !

Lieu de l'événement : Dock Pullman 87 Avenue des Magasins Généraux (Bâtiment 137) 93300 Aubervilliers

dotJS conférence

Publié par Alsacreations.com

Actualité : L'élément <main>

$
0
0

Depuis quelques années, HTML propose un meilleur découpage sémantique des pages et applications web pour éviter la "divite", l'abus d'éléments <div> pour regrouper chaque bloc de contenu.

Dès les premières versions de HTML5, les éléments sectionnant ont vu le jour : <section>, <nav>, <article>, <aside>, <header>, <footer> ont été assez bien compris et se sont révélés utiles.

Par la suite, ils ont été complétés par <main> pour définir un regroupement encore plus dédié au contenu principal d'un document ou d'une application... par opposition à des blocs communs <header> et <footer> qui ne changeront que peu d'une page à l'autre.

Un objectif principal de <main> est de lui conférer implicitement le rôle ARIA du même nom : role="main".

Spécificités

Il était défini, de manière relativement logique deux critères :

  1. Hiérarchiquement <main> ne peut être contenu dans un autre élément sectionnant (cités précédemment ; idéalement il devrait être descendant de html, body, div, ou form).

  2. Il ne pouvait y avoir plus d'un élément <main> : désormais, avec les retours d'expériences et cas pratiques, on autorise l'usage de plusieurs <main> à partir du moment où il n'y en a qu'un d'actif à la fois et que les autres sont "désactivés" par un attribut hidden.

<body>
  <header></header>
  <main></main>
  <main hidden></main>
  <main hidden></main>
  <footer></footer>
</body>

Quel est l'intérêt ? Pouvoir concevoir une page dont le contenu principal changerait, serait activé par étapes successives par exemple en JavaScript par mouvement des attributs hidden. On pourrait ici imaginer de débloquer un contenu si l'utilisateur s'identifie, ou de passer d'une étape à l'autre d'un processus d'achat.

En voici une démo minimaliste :

See the Pen Main + hidden by Alsacreations (@alsacreations) on CodePen.

hidden

Attention, ne confondez pas l'attribut hidden avec une façon de masquer graphiquement des contenus comme on peut le faire en CSS avec display: none ou visibility: hidden. La signification est plus forte ici. Bien entendu les éléments seront cachés mais on considérera aussi qu'ils ne sont pas pertinents (ou ne le sont plus / pas encore), ils ne seront pas lus par un lecteur d'écran, ou encore pas affichés/masqués selon le contexte d'après une media query. Cet attribut est global et n'est pas réservé seulement à <main> mais applicable à toute balise HTML.

Ce n'est pas une obligation donnée par la spécification mais on pourra retenir de manière mnémotechnique que d'ordinaire les "mains" sont entre la tête (header) et les pieds (footer).

Publié par Alsacreations.com

Actualité : dotJS 2018

$
0
0

C'est avec un nouveau succès que dotCSS et dotJS ont eu lieu cette année. Avant de résumer l'essentiel de la journée de dotJS ci-après, deux informations principales :

  • L'édition 2019 sera étendue : dotCSS aura lieu le mercredi 4 décembre, suivi de deux jours pour dotJS les jeudi 5 et vendredi 6 décembre.
  • Dorénavant les événements dotConferences s'attacheront à un bilan carbone neutre. Après avoir examiné les principaux points d'émission (dus aux trois quarts aux transports), réduit ce qui pouvait l'être et compensant les émissions incompressibles. Un calculateur a été publié par l'organisation : https://github.com/dotconferences/dotjs2018-carbon-footprint n'hésitez pas à contribuer.

Débriefing des conférences, orateur par orateur. Toutes en anglais à l'origine donc pardonnez les quelques termes techniques intraduisibles s'étant glissés dans le texte.

Sacha Greif

Twitter : @sachagreif

Sacha réalise l'enquête State of JavaScript depuis plusieurs années. Les résultats frais de 2018 ont été dévoilés à dotJS et seront bientôt publiés en ligne sur https://www.stateofjs.com. La démarche fut lancée en 2016 face à un écosystème confus : des dizaines d'options existaient pour choisir sa stack JavaScript.

State of JS

On se concentre ici sur le chiffre "j'ai utilisé cette technologie et je l'utiliserai encore" ayant évolué entre 2016 et 2018 :

  • TypeScript : passe de 20% à 46% (raisons : permet d'éviter des erreurs, style de programmation élégant).
  • React : passe de 48% à 64% (raisons : style de programmation élégant, écosystème de paquets riche).
  • Vue.js : passe de 6% à 28% (raisons : courbe d'apprentissage plus aisée, style élégant, bonne documentation, léger).
  • GraphQL : passe de 5 à 20% (style élégant, popularité gagnant du mouvement, outils puissants pour le développement).
  • AngularJS : stagne à environ 20%.

En examinant de plus près les chiffres et les résultats du sondage, on remarque que tout le monde a entendu parler de Vue.js (inconnu pour 1% des sondés) et souhaiterait le découvrir. Même chose pour GraphQL, presque tout le monde en a entendu parler et la plupart veulent l'essayer (62%) si ce n'est pas déjà fait.

L'opinion est beaucoup plus mitigée pour Angular, c'est le seul qui ne progresse pas. 20% ne voulaient plus l'utiliser en 2016, désormais 33% en 2018. Le nombre de personnes souhaitant le découvrir est en chute. Raisons évoquées : complexe et surgonflé (bloated en V.O.), style de programmation maladroit (clumsy en V.O.), courbe d'apprentissage difficile.

Au niveau de la satisfaction, React et Vue.js sont très nettement au-dessus de la moyenne tandis que Polymer, Ember, et donc Angular perdent des points.

La plupart des développeurs et développeuses sont d'accord pour dire que JavaScript bouge dans la bonne direction, 39% en 2016 contre 51% en 2018. Ce qui est un très bon signe. Il y a cependant un gros potentiel d'amélioration, car encore de nos jours il faut passer un certain temps au lancement d'un projet pour mettre en place le framework bien qu'il existe des assemblages et modèles complets.

Tobias Ahlin

Twitter : @tobiasahlin

Tobias fait partie de l'équipe de Minecraft (Mojang ~150 personnes) qui a décidé de faire tourner son interface en... JavaScript. Pourquoi ? Pour miser sur le cross-platform (PC, iOS, Android, Xbox, Switch, c'est vrai qu'il y de quoi faire). Il va exposer la logique du jeu à travers des API pour pouvoir créer des mots, des cartes personnalisées, intervenir sur le gameplay etc. La problématique d'avoir le même code sur les 4 plateformes précitées est complexe. Encore plus quand on pense aux différents contrôleurs qui peuvent exister (clavier, tactile, manettes de jeu, et parfois plusieurs à la fois).

Un prototype a été construit et sera bientôt dévoilé. Les interactions sont conçues en JavaScript Vanilla et l'UI dans un framework maison. Ils étaient sceptiques quant à la performance sur mobile mais la situation a changé. Il y a peu, l'iPhone 4s représentait le meilleur cas de figure, maintenant il s'agit du plus mauvais contexte d'exécution. Il est également difficile d'espérer exécuter le code dans Chromium sur tous les systèmes.

Les utilisateurs ont des attentes différentes pour un jeu par rapport à une application "native". Ce qui aboutit à une ressemblance de beaucoup d'interfaces d'applications du quotidien mais une originalité pour les jeux : chacun a sa propre interface graphique immersive et n'est pas lié aux contraintes du système d'exploitation.

Avec l'utilisation du framework hummingbird l'interface du jeu peut être inspectée, modifiée en direct plutôt que d'avoir à recompiler. C'est une grosse révolution pour le développement et les expérimentations. Dans hummingbird, les VM (machines virtuelles) sont adaptées à chaque plateforme (V8, JavaScriptCore, etc) et on utilise CSS Flexbox pour le layout (la composition). Tout ce qui est conçu dans l'outil fonctionnera dans un navigateur web classique (mais pas forcmément l'nverse).

Hummingbird

Faire appel à la communauté JavaScript présente plusieurs avantages : plus de personnes le connaissent donc embaucher est plus facile, c'est une communauté open-source pleine de vie, il y a beaucoup de documentation, de très bons outils à jour et il s'intègre bien avec les outils de design du moment (ex : FramerX).

Il y a 90 millions de joueurs actifs, donc potentiellement beaucoup de monde et de jeunes auprès de qui sera introduit JavaScript.

Voir aussi : https://bit.ly/minecraftdotjs

Lauren Tan

Twitter : @sugarpirate_ (Netflix)

Lauren recommande l'utilisation de TypeScript ou Flow pour "sécuriser" le code, pour détecter dans quel cas une fonction peut échouer. JavaScript étant un langage permissif, il est difficile d'anticiper tous les cas et de savoir qu'une fonction va réellement être appelée avec les bons arguments du bon type. Dans certains cas une simple fonction d'une ligne pourra renvoyer une erreur selon que l'on lui passe une chaîne de texte, un nombre, un tableau, un objet. Le but est d'être averti à l'avance par le compilateur et de canaliser les exceptions. On mise alors sur des concepts de langage fonctionnel tels que la théorie des preuves et des types (un programme est une preuve).

John Papa

Twitter : @john_papa (Microsoft)

John insiste : choisir un framework est une question de feeling. Il n'y a pas de solution idéale, cela dépend de nos propres expériences, on ne doit pas choisir l'outil par rapport à ce que les autres peuvent nous en dire mais parce qu'il nous rend meilleur. Les meilleures options aujourd'hui étant Vue, React, Angular, que doit-on regarder ? Les fonctionnalités, la possibilité de l'étendre à grande échelle, le support, la longévité, la performance, la popularité et la documentation.

Vue React Angular

Si l'on prend des exemples concrets, ces 3 outils disposent de composants, de gestion d'état, de lazy loading, qui sont mis en oeuvre de façons différentes. L'état est dans Redux pour React, dans Vuex pour Vue.js et Angular se satisfait de NgRx-Data. Finalement on peut construire des webapps qui fonctionnent et se ressemblent très fortement. On n'a pas besoin d'avoir un gagnant unique dans notre industrie, c'est bien de pouvoir avoir le choix parmi 3 frameworks awesome (ou amazing selon Jean-Claude Van Damme).

Lightning talks

  • Jeremias Menichelli (@jeremenichelli) de Typeform : Lazy loading des fonts sans bloquer l'affichage lorsque le réseau est lent (avec FontFaceObserver)
  • Tim Pietrusky (@TimPietrusky) présente WebUSB http://wicg.github.io/webusb pour les artistes numériques, fonctionne dans Chrome pour le moment et permet de contrôler des périphériques Arduino par exemple qui vont ensuite contrôler des protocoles d'éclairage pour les salles de spectacle.
  • Roy Derks (@gethackteam) discute de la pertinence des modèles de type boilerplate pour construire une application JavaScript
  • Sam Wray présente OffscreenCanvas pour faire de la 2D/3D avec des workers et ne pas bloquer l'interface principale (postMessage servant de canal pour envoyer les informations).
  • Adam Weeks (@AdamWeeks) qui conseille de ne pas débuguer à la console.log mais de bien prendre en main les outils de développement, onglet Sources et de systématiser les breakpoints, voire les breakpoints conditionnels (clic bouton droit sur la ligne concernée).

Kurt Mackey

Kurt a témoigné de son expérience sur son projet pour construire un CDN en ayant tenté plusieurs approches et langages (nginx, lua, Go, otto, etc), pour finir sur une solution basée sur Node et V8. Il est difficile de retranscrire sa présentation liée à une expérience particulière... bientôt la vidéo.

Tara Z. Manicsic

Twitter : @tzmanics

Tara nous encourage à utiliser HTTP/2, plusieurs années déjà après sa création pour profiter d'avantages majeurs de performance : entre autres le multiplexage (envoyer plusieurs fichiers/ressources dans le même tunnel de connexion), la compression des en-têtes, la priorisation de flux. HTTP/2 n'était pas très simple à configurer à sa naissance mais désormais des extensions facilitent les choses y compris du côté d'Apache avec mod_http2. Attention cependant il nécessite également l'usage HTTPS.

On peut tester et visualiser le fonctionnement avec des outils tels que https://www.dareboost.com/en/website-speed-test-http2-vs-http1, h2i et nghttp2.

Lightning talks session 2

  • Maël Nison (@arcanis) cherche à améliorer le principe du dossier node_modules réputé pour être fouilli, lent, répétant plusieurs fois des dépendances communes.
  • Kashyap Kondamudi de Bangalore rappelle que l'on sort de l'enfer des callbacks avec les Promises JavaScript.
  • Tejas Kumar (@tejaskumar_) nous dit que JavaScript ne sera pas remplacé par WebAssembly (enfin pas tout de suite).
  • Olivier Loverde (@loverdeolivier) présente CQRS (Command Query Responsibility Segratation) pour séparer la logique des écritures de celle des lectures (asymétrique).
  • Joost Lubach d'Amsterdam présente une démo animée impressionnante qu'il utilise avec ses élèves pour expliquer le principe asynchrone, inspiré de The Promise of a Burger Party.

Felix Rieseberg

Twitter : @felixrieseberg (Tech lead à Slack)

Felix a beaucoup travaillé avec Electron, outil permettant de développer des applications desktop cross-platform en HTML, CSS, JavaScript grâce à un moteur Chromium embarqué. C'est le cas d'applications désormais bien connues : Slack, Visual Studio Code, Figma, Github desktop... Mais faire du JavaScript dans ce cas n'est pas toujours facile. Il est parfois qualifié de lent. Pourquoi ? Selon Felix il s'agit de code mal écrit, mal pensé, qui consomme par exemple de la mémoire inutilement.

Slack

Par exemple certains modules JS de base tels que require devraient être appelés uniquement lorsqu'on en a besoin (dans un "if" et pas systématiquement en amont du fichier. Require fait appel à is-reachable qui lui-même charge port-numbers représentant 94000 lignes de JSON. Wow. Avant même d'exécuter toute autre fonction.

Le code produisant des pixels peut souvent être optimisé. Exemple pratique avec une page d'accueil provocant des paints multiples et non nécessaires, occupant 50% du processeur, certainement déclenchés par un script quelconque, et vus par l'inspecteur de performances du navigateur. Désormais on a tous les outils évolués pour détecter cela.

Tout code n'est pas égal à ses semblables même s'ils accomplissent les mêmes actions. Comparaison de querySelectorAll et getElementsByClassName : https://jsperf.com/dotjs-perf-example où l'on trouve que querySelectorAll est 100 fois plus lent avec le test proposé.

Penser natif ? Avec Wasm et Rust sur des bouts de code précis pour des opérations très fréquentes qui demandent un peu de puissance.

Enfin, respecter le cycle de vie de l'application, et profiter de visibilitychange pour suspendre les opérations qui consomment de la puissance (setInterval, animations, vidéos, requêtes réseau non urgentes).

Notez que l'interface utilisateur du jeu Battlefield 1 est en JavaScript / React, que Nvidia GeForce Experience utilise nodeJS tout comme Adobe Creative Suite pour bon nombre de ses composants d'interface.

Myles Borins

Twitter : @mylesborins (Google)

Myles propose également de nous sortir de l'enfer des callbacks avec le couple async/await, ayant également pour avantage de ne pas bloquer le thread principal et donc la réactivité de l'interface. Les Promises (promesses) ont déjà mis du temps à être intégrées au langage (depuis 2014) tandis qu'async/await est plus récent (2016) et permet de réécrire autrement les choses. Difficulté : await doit toujours être utilisé dans une fonction async. Myles milite donc pour adapter le langage et permettre son utilisation au plus haut niveau.

Devon Lindsey

Twitter : @devonbl (Apple, entre autres)

Appréciant les robots, JavaScript et toutes sortes d'expérimentations, elle a conçu le Robot Rock pour faire "danser" des robots connectés en Bluetooth synchronisés à un rythme de musique, le tout en JavaScript grâce à Cylonjs et aux Node Clusters. La grande difficulté restant la latence imprévisible du Bluetooth, et l'imprécision des mouvements mécaniques avec les moteurs des roues. Il faut le voir pour le croire.

Anders Hejlsberg

Twitter : @ahejlsberg

Co-fondateur de TypeScript, ayant travaillé avec moult langages depuis des temps que seuls les amateurs de Turbo Pascal peuvent connaître, Anders a déterminé que le cross-platform est devenu un enjeu majeur avec les périphériques mobiles, et systèmes d'exploitation divers qui ont mis fin à la domination de Windows sur desktop en tant que plateforme majeure. En quelques années, le moteur JavaScript V8 de Google a vu ses performances multipliées par 5. Avec HTML5 il est désormais possible d'écrire de belles applications dans le navigateur, et JavaScript domine en première place aux classements de popularité des langages.

Au début les outils étaient très basiques, il n'y avait pas de classes ou de modules JS, l'éditeur était notepad.exe. Désormais nous avons un écosystème très riche, qu'il était nécessaire de compléter par un système de typage pour le langage afin de le rendre plus robuste.

Typescript dans Visual Studio Code

TypeScript a débuté vers 2012 avec pour fondations l'open-source, le respect d'ECMAScript, de l'innovation, une barrière basse à l'entrée et la communauté. C'est une solution désormais très populaire parmi les mordu·e·s de JavaScript, qui dispose d'une API interne (alors même qu'il s'agit d'un compilateur) pour pouvoir accéder à ses rouages et construire des extensions notamment dans les éditeurs de code source. En plus cela fonctionne avec Angular, Vue, React, Babel, il n'y a plus de raison de ne pas s'y intéresser ;)

Publié par Alsacreations.com

Actualité : Les frameworks JavaScript en 2018

$
0
0

Suite à la publication des résultats de la grande enquête The State of JavaScript 2018, déjà dévoilés en exclusivité pour dotJS, nous avons proposé un sondage sur Twitter pour avoir un panel plus représentatif de la communauté francophone, sur une question en particulier.

Trois frameworks majeurs se partagent actuellement le top 3. En plus d'autres plus "petits" tels qu'Ember ou Preact qui ont néanmoins de beaux projets et communautés à leur actif :

  • React
  • Angular
  • Vue.js

Vue React Angular

Dans l'enquête State of JS de cette année, il y a bien des informations intéressantes à en tirer. Nous vous laissons les découvrir en détails en consultant le site officiel, et nous concentrons sur le "choix" d'un framework, sujet épineux à notre époque.

À travers la question de la popularité, les réponses possibles étaient proposés de la façon suivante : "je n'en ai jamais entendu parler", "j'en ai entendu parler mais je ne suis pas intéressé", "j'en ai entendu parler et j'aimerais l'apprendre", "je l'ai utilisé mais je ne voudrais plus", et "je l'ai utilisé et je le ferai encore".

State of JS 2018

On peut constater plusieurs faits marquants :

  1. Quasiment tout le monde a entendu parler d'Angular, React, Vue.js
  2. React est de loin le plus utilisé (64,8%)
  3. L'intérêt pour Vue.js est indéniable (46,6% de curieux + 28,8% souhaitant à nouveau l'utiliser)
  4. Angular cumule le plus grand nombre d'insatisfaits (33,8%) ce qui est énorme, sans compter les non intéressés (31,8%)

Ces résultats sont confirmés par notre plus modeste sondage Twitter.

Quelles raisons à cela ? Dans les grandes lignes, de façon non exhaustive :

Angular, dévoilé par Google en 2010-2012, affiche un résultat mitigé, victime d'une politique d'évolution floue, de versions (notamment la 2.0) ayant brisé la rétro-compatibilité et d'une certaine complexité pour se laisser dompter. Il est aussi réputé pour un style de programmation un peu maladroit qui peut favoriser l'écriture de bugs.

React, publié par Facebook en 2013, a rapidement séduit par ses performances, son DOM virtuel, ses composants réutilisables et sa gestion fine des états. Il est très orienté pour les développeurs JavaScript avancés avec sa syntaxe propre de templating (JSX) et la possibilité d'utiliser des fonctionnalités poussées (rendu côté serveur, modules et classes ECMAScript 6, TypeScript, etc). Il y a beaucoup de packages existants, ses outils de conception sont à la mode et il reste léger. Une difficulté pour les débutants reste la gestion des données et leur transit à travers toute la hiérarchie des composants, chose pour laquelle il faut souvent ajoindre Redux et donc un nouveau niveau de complexité.

Vue.js, le plus récent inauguré en 2014, a vu sa communauté croître grâce à une prise en main plus aisée. Ne serait-ce qu'en évoquant sa syntaxe de templating en quasi-HTML plus "naturelle" que JSX, et une très bonne documentation. Bien que le nombre de modules proposés ne soit pas encore aussi pléthorique que l'univers de React, celui-ci suit une courbe tout aussi croissante et suffit à la plupart des usages, même poussés. Imaginé par un développeur de Google ayant travaillé avec Angular et ayant quitté la firme pour tenter de proposer une alternative alliant le meilleur de React et d'Angular avec des outils user-friendly, il sait convaincre.

Dans tous les cas, nous constatons qu'ils ont une grande maturité dans le développement web, une bonne documentation et qu'ils sont utilisés ou soutenus par de grands noms ce qui n'est pas négligeable pour leur pérennité : Yahoo, Google, Facebook, Netflix, Sony, Airbnb, WhatsApp, Instagram, Adobe... vous y retrouverez l'ensemble des entreprises à qui ces frameworks permettent de trouver un cadre de développement pour leurs équipes, ainsi que des développeurs et développeuses souvent déjà initié(e)s à leur usage. Il y a encore cependant des phases de scepticisme quant à l'univers de Node notamment sur la gestion des dépendances, leur sécurité, et le fameux dossier node_modules.

Lorsque l'on est intégrateur web, récent ou depuis plusieurs années, développeur ou même designer, s'intéresser ou se plonger dans de tels outils peut être anxiogène. Bien sûr il faut toujours relativiser leur intérêt par rapport aux projets concrets que l'on peut mener à bien avec eux. Le choix peut sembler délicat, mais on peut tempérer si vous n'avez pas encore fait le premier pas :

  • React et Vue.js sont un bon choix, quoiqu'il arrive
  • Leur architecture et philosophie sont proches, en découvrir l'un vous permettra de prendre la main plus rapidement avec l'autre
  • Les méthodes d'écriture de code JavaScript "modernes" seront nécessaires pour les apprivoiser

D'ailleurs, tout ceci tombe à pic ;) Alsacréations est aussi un organisme de formations qui vous propose de vous initier en 2019 à Vue.js ou à React, voilà de quoi ouvrir de belles perspectives.

Formation à React   Formation à Vue.js

Publié par Alsacreations.com


Article : CSS font-display et le chargement des polices web

$
0
0

Définie comme un "descripteur de la règle @font-face", la propriété CSS font-display a pour fonction de contrôler l'affichage d'une police de caractère téléchargeable durant la période où le fichier n'est pas encore récupéré par le navigateur.

Ce questionnement n'est pas anodin car l'expérience utilisateur peut être complètement chamboulée si aucun contenu textuel ne s'affiche durant plusieurs secondes sur la page consultée, sous prétexte de souffrir d'une mauvaise connexion internet par exemple.

font-display ?

Les premiers travaux visant à améliorer le chargement des polices par le navigateur, initiés par John Daggett (Mozilla) et Tab Atkins Jr. (Google), débutent dans les années 2014 sous le nom de "Font Loading Module" puis "Font Loading API".

La première référence marquante à une propriété nommée font-display apparaît dans un article de Google daté de 2016.

À ce jour, la propriété CSS font-display est présente dans les spécifications "CSS Fonts Module Level 4" (au statut de "W3C Working Draft", en brouillon donc, depuis septembre 2018).

Profitons-en pour signaler d'ores-et-déjà que font-display, malgré sa jeunesse, est déjà compatible sur une grande partie des navigateurs modernes, et donc parfaitement utilisable en production.

Carte d'identité de font-display

  • Propriété : font-display
  • Propriété liée à : @font-face
  • Valeur par défaut : auto
  • Média concerné : visuel

Exemple de code

@font-face {
  font-family: kiwi;
  src: url("/fonts/kiwi.woff2");
  font-display: auto;
}

Tableau de compatibilité

Navigateurs Versions Détails
Firefox

Firefox
Firefox Mobile

Supporté
Non supporté
Chrome Chrome
Chrome Android
Supporté
Opera Opera
Opera Mobile
Supporté
Non supporté
Safari Safari
Safari Mobile (iOS)
Supporté
Internet Explorer Internet Explorer Non supporté
Microsoft Edge Edge Non supporté
Android Browser Android Browser Non supporté

Source : CanIUse.com.

Les étapes d'affichage d'une police

Lorsqu'une police téléchargeable est proposée à un navigateur (via le chemin src de la règle @font-face), son rendu à l'écran traverse trois étapes successives :

  1. Étape de Blocage des fontes.
    Durant cette période le contenu du texte est rendu de manière "invisible". L'espace est occupé mais les caractères ne sont pas perceptibles, à l'exception des soulignements des liens. Dès lors que le fichier est chargé, le texte apparaît normalement dans la police finale attendue.
  2. Étape d'Échange.
    Au cours de cette seconde étape une police alternative visible (fallback) est affichée. Dès lors que le fichier est chargé, le texte apparaît normalement dans la police finale attendue.
  3. Étape d'Échec du chargement.
    Le fichier est à présent considéré comme étant en échec et la tentative de chargement est avortée. Une police alternative visible est affichée.

Le schéma ci-dessous décrit les trois différentes étapes de chargement d'une police.

La police demandée au navigateur est "Open Sans", via la règle suivante :

h1, h2 {
  font-family: 'open sans', sans-serif;
}

À chaque étape, le navigateur se pose la question de savoir si le fichier est enfin chargé. Si tel n'est pas le cas, il passe à l'étape suivante sinon il l'affiche fièrement.

étapes de chargement d'un fichier de police

Vous l'aurez compris : selon les écueils pour passer d'une étape à l'autre, l'affichage final de la police peut prendre un certain temps. Un temps loin d'être négligeable pour nos visiteuses et visiteurs.

FOIT et FOUT

Les deux acronymes "FOIT" et "FOUT" sont fréquemment associés à ces périodes de chargement.

FOIT

On parle de "FOIT" ("Flash Of Invisible Text") lorsque le texte est rendu de manière invisible. C'est typiquement le cas durant la phase de Blocage.

FOUT

On appelle "FOUT" ("Flash Of Unstyled Text") le moment où le contenu est rendu à l'aide d'une police alternative. Cela correspond à l'étape dite d'Échange.

La mauvaise nouvelle, mais qui n'est pas forcément une surprise, est que chaque navigateur adopte un comportement différent lors de ces trois étapes de chargement. Le comble étant que les spécifications sont assez explicites sur la question : "Les agents utilisateurs décident de leur stratégie de chargement de fontes tant que le fichier n’est pas chargé". Bref : "débrouillez-vous".

Durée de la phase de blocage selon les navigateurs :

  • Internet Explorer et Edge = 0s
  • Chrome, Firefox, Safari = 3s
  • Safari (anciens avant 8.0) = infini

Traduction :

  • Internet Explorer et Edge = FOUT
  • Chrome, FF, Safari = FOIT+FOUT
  • Safari (old) = FOIT

On se pose un instant et on en déduit que sur les (un peu) anciens navigateurs Safari, lorsqu'une police "exotique" est demandée mais que le navigateur ne la trouve pas. Le contenu demeure invisible durant tout le temps où ce fichier est chargé. Imaginez le nombre de visiteurs (clients ?) potentiellement perdus parce qu'ils sont privés de contenu durant plusieurs secondes… et parce que votre client voulait une police "cool".

Le problème des fontes d'icones

Une fois que l'on a bien saisi les stratégies de chargement des navigateurs, on est en droit de se dire que Internet Explorer - en choisissant un FOUT systématique - préserve la restitution immédiate du contenu pour les visiteurs et qu'il a plutôt raison de le faire.

On peut même se demander quel est vraiment l'intérêt de l'étape "FOIT" qui ne semble que nuisance pour l'obtention de l'information et du contenu.

Eh bien en fait ça dépend et c'est un peu plus compliqué que cela.

Prenons par exemple le cas des fichiers de polices composés d'icones et de pictogrammes, ce qu'on appelle communément "fontes d'icones" ou "icon font" en anglais. La plus célèbre étant FontAwesome.

Une fonte d'icônes est un fichier de police comme les autres. Cela signifie que lorsque ce fichier est en cours de chargement, les navigateurs peuvent choisir de le masquer (FOIT) ou de le remplacer par une police alternative (FOUT). Or, la police de remplacement d'un symbole tel que "icône de Twitter" n'existe pas, les caractères étant généralement choisis dans une zone Unicode complètement incompréhensible.

Le comportement de FOUT est par conséquent nuisible à la lecture et la compréhension du contenu et il serait préférable de ne rien afficher du tout tant que l'icône n'est pas chargée… mais uniquement lorsqu'il s'agit d'une fonte d'icônes !

Valeurs et effets de font-display

Les différentes valeurs de font-display sont :

font-display: auto;

La stratégie d'affichage de la fonte est définie par le navigateur, qui choisit l'un des autres modes suivants d'après ses paramètres internes : fallback, block, swap, optional.

font-display: block;

La période de blocage est courte (3s selon les recommandations) et est suivie d'une période d'échange infinie. Correspond au "FOIT" dans la mesure où le rendu est invisible tant que la police n'est pas chargée.

Cette valeur est parfaite pour les fontes d'icônes car elle masque le texte tant que le fichier d'icônes n'est pas disponible et évite ainsi d'afficher des caractères incongrus.

font-display: swap;

La période de blocage est extrêmement courte (100ms recommandé) et est suivie par une période d'échange infinie. Correspond au "FOUT".

Utilise une police de remplacement déjà disponible sur le navigateur (ex : serif, sans-serif ) pour afficher du texte immédiatement tant que la police n'est pas chargée, puis la remplace quand le bon fichier a été téléchargé.

Cette valeur est idéale pour du texte de contenu où l'accès à l'information est primordial car la police alternative s'affiche dès que possible.

font-display: fallback;

La période de blocage est extrêmement courte (100ms) et est suivie par une courte période d'échange (3s).

Une police alternative est affichée, remplacée dès que la police est chargée. Cependant, si l'attente est trop longue, la police alternative sera finalement conservée pour cette page.

font-display: optional;

La période de blocage est extrêmement courte (100ms) et il n'y a pas de période d'échange (0s).

Cette dernière valeur est quelque peu particulière. Le principe général est de n'afficher la fonte que si elle est immédiatement disponible (déjà dans le cache par exemple) et dans le cas contraire une police de remplacement est appliquée pour la page en cours.
Le navigateur peut décider de charger le fichier de manière asynchrone pour afficher la police au cours d'une page ultérieure, voire de ne jamais télécharger la fonte s'il détecte que la bande passante est limitée.

Cette valeur est particulièrement adaptée pour les textes de contenus principaux où une police exotique n'apporterait qu'un bonus esthétique par exemple.

Exemple concret

/* police de labeur */
@font-face {
  font-family: opensans;
  src: url("/fonts/open-sans.woff2");
  font-display: optional;
}
/* police d'icônes */
@font-face {
  font-family: iconfont;
  src: url("/fonts/myiconfont.woff2");
  font-display: block;
}
/* police de titrage */
@font-face {
  font-family: merriweather;
  src: url("/fonts/merriweather.woff2");
  font-display: swap;
}

/* application des polices */
body {
  font-family: opensans, helvetica, arial, serif;
}
h1, h2 {
  font-family: merriweather, georgia, sans-serif;
}
.icon {
  font-family: iconfont;
}

Publié par Alsacreations.com

Actualité : Apéro spécial "Accessibilité" chez Alsacréations

$
0
0

L’équipe du WdStr, l'association de webdesigners et front-dev de Strasbourg vous invite à venir célébrer le Printemps (si si, on espère comme vous qu'il revient bientôt...) autour d'une présentation sur l'accessibilité web.

Pierre Fournier, intégrateur au Crédit Mutuel, nous montrera au travers de quelques démonstrations, ce qu'est l'accessibilité et à quelles situations elle s'applique :

L'accessibilité on en a tou·te·s entendu parler, on a tou·te·s une vague idée de ce que c'est.
Mais qu'en-est il vraiment ? Comment la mettre en place, la contrôler et surtout à qui cela s'adresse-t-il ? Les personnes mal voyantes et les aveugles ? Oui c'est vrai, mais pas que...

Alors que vous souhaitiez découvrir un autre aspect de la conception web ou une bonne piqûre de rappel, rejoignez-nous chez Alsacréations le Jeudi 21 Mars à partir de 19h !

N’oubliez pas de vous inscrire, les places sont limitées !

Publié par Alsacreations.com

Actualité : Il n'y aura pas de KiwiParty en 2019

$
0
0

Si vous comptez parmi les fidèles "Alsanautes", vous aurez peut-être remarqué que nous n'avons pas encore communiqué à propos de la KiwiParty 2019 et vous en soupçonnez sans doute la raison.

En effet, je suis messager d'une mauvaise nouvelle : l'équipe d'organisation (Alsacréations et WdStr) a décidé suite à un vote interne de ne pas s'engager dans l'organisation d'une KiwiParty au cours de cette année 2019.

Les raisons sont assez simples et on peut en citer deux parmi d'autres :

  • Il devient de plus en plus difficile de trouver des sponsors ou aides pour cet événement,
  • La préparation d'une telle journée nécessite une organisation lourde et sans faille, et là aussi cette année... c'est compliqué

Il serait aujourd'hui bien trop risqué de tenter de mener à bien ce projet cette année sans y laisser plus d'investissement que de raison (en temps, énergie, argent et santé mentale).

Nous espérons cependant de tout cœur pouvoir annoncer une KiwiParty en 2020. Avec vous peut-être ?

D'ailleurs si l’envie vous venait de nous soutenir financièrement, moralement ou un autre adverbe positif en "ment", n’hésitez pas à nous le faire savoir en nous envoyant un mail à contact@kiwiparty.fr !

Publié par Alsacreations.com

Actualité : Rendez-vous pour la prochaine KiwiParty 2020 ?

$
0
0

Si vous comptez parmi les fidèles "Alsanautes", vous aurez peut-être remarqué que nous n'avons pas encore communiqué à propos de la KiwiParty 2019 et vous en soupçonnez sans doute la raison.

En effet, je suis messager d'une mauvaise nouvelle : l'équipe d'organisation (Alsacréations et WdStr) a décidé suite à un vote interne de ne pas s'engager dans l'organisation d'une KiwiParty au cours de cette année 2019.

Les raisons sont assez simples et on peut en citer deux parmi d'autres :

  • Il devient de plus en plus difficile de trouver des sponsors ou aides pour cet événement,
  • La préparation d'une telle journée nécessite une organisation lourde et sans faille, et là aussi cette année... c'est compliqué

Il serait aujourd'hui bien trop risqué de tenter de mener à bien ce projet cette année sans y laisser plus d'investissement que de raison (en temps, énergie, argent et santé mentale).

Nous espérons cependant de tout cœur pouvoir annoncer une KiwiParty en 2020. Avec vous peut-être ?

D'ailleurs si l’envie vous venait de nous soutenir financièrement, moralement ou un autre adverbe positif en "ment", n’hésitez pas à nous le faire savoir en nous envoyant un mail à contact@kiwiparty.fr !

Publié par Alsacreations.com

Article : Apprendre à développer en équipe

$
0
0

Cet article est issu de mon retour d'expérience sur ces 3 dernières années. Années pendant lesquelles j'ai réfléchi à améliorer le cadre de travail côté front de l'équipe d'une quinzaine de développeurs chez Logic-Immo. Il a pour but de donner des pistes aux équipes de moyenne ou grosse envergure qui souhaitent garder un cadre de travail agréable et performant.

Le travail en équipe est souvent douloureux. Qui n’a jamais fait l’expérience d’arriver dans une boîte et d’y voir une dette technique importante ? Parfois même, il n’y a aucune nomenclature commune, tout et son contraire se côtoient. Bootstrap sur quelques blocs, du css vanilla sur d’autres, certains développeurs/euses codent sur une seule ligne, d’autres écrivent avec des point-virgules, certains non, etc.

En mettant en place des règles pour favoriser un code propre et lisible, donc maintenable, il est bien plus plaisant de travailler sur vos projets au boulot. Comme chaque développeur/euse a sa manière de travailler, il convient de trouver une façon accessible au plus novice (il est fort probable que le directeur technique fasse appel à des contrats pros, stagiaires ou débutants pour dégager du budget pour une ressource plus sénior). Ainsi si la lecture du code est adaptée pour les débutants, elle est accessible pour tout le monde.

Le côté optimisation reste indispensable pour les navigateurs, mais nous verrons en fin qu’avec un certain nombre de tâches automatisées, c’est quelque chose qui se fait implicitement. Pour chaque point, je vais vous parler de l’idée générale, avec parfois plusieurs pistes. À vous de l’adapter à vos projets et de choisir les solutions les plus adéquates, en fonction du niveau de vos développeurs/euses ou des technologies utilisées.

Architecture des fichiers

La manière d'organiser vos fichiers, dans l'arborescence et dans la façon de les inclure est une base saine pour démarrer un projet bien ficelé.

Rangement logique des fichiers

Il suffit d’ouvrir certains projets pour se rendre compte qu’il y a un nombre conséquent de dossiers comprenant les mêmes types de ressources.

Ces ressources sont parfois :

  • placées à des endroits peu logique => Il est difficile de retrouver exactement où faire sa modification ;
  • dupliquées et donc redondantes => risque d’avoir du code inutilisé qui alourdit le site.

Pour pallier cela il faut avoir une arborescence de fichiers logique. Mettez vos fichiers front dans un dossier public/ ou asset/ puis organisez-les avec un découpage cohérent : css/ fonts/ img/ js/ less/ (ou sass/) etc.

Ne multipliez pas les endroits contenant un même type de ressources. Par contre au sein d’un même dossier d’un type de ressources, vous pouvez créer des sous-dossiers pour créer une arborescence logique.

Il n’y a pas forcément d’arborescence type, mais voici un exemple avec un site de petites annonces (semblable donc à une majorité des sites e-commerce).

exemple d'arborescence pour les fichiers SCSS d'un site de petites annonces

Exemple d'arborescence pour les fichiers SCSS d'un site de petites annonces

Inclusions des fichiers (phtml/less/etc)

L’inclusion de fichiers les uns dans les autres est un grand classique des risques d’erreurs. Il permet d’éviter d’avoir un fichier comprenant des centaines voir milliers de lignes de codes. Mais mal utilisé, il devient contre-productif.

Imaginez un exemple concret : si le fichier PHP principal d’une page contient l’appel à un fichier PHP pour le header qui comprend lui-même l’appel à un fichier PHP pour la navigation. Si ce dernier contient un appel à un fichier PHP d’un élément du menu et ainsi de suite. Lorsque vous avez une modification à faire sur la barre de navigation, vous ne savez pas du premier coup d’oeil si vous devez modifier du code dans le fichier de l’élément du menu ou celui de la navigation, voire celui du header.

Pour éviter ce genre de désagrément, ma recommandation est de n’avoir qu’un niveau d’inclusion. C’est exactement ce que l’on a fait plus haut dans l’arborescence de fichiers où seuls les quatre fichiers de bases de pages (detail, home, list, seo) importent d’autres fichiers. Je recommande aussi de mettre en LESS ou Sass les imports dans l’ordre d’apparition des éléments dans la page, rien que pour la lisibilité.

@import "compass/css3",
        "compass/reset",
        "../../../vendor/fontawesome/scss/font-awesome",
        "../../common/fonts/_font-custom",
        "../../common/_color",
        "../../common/_buttons",
        "../../common/_fonts",
        "../../common/_reset",
        "common/_structure",
        "../common/_criteo",
        "../common/_ads-interstitiel.scss",
        "../common/_banner-apps",
        "../common/_header",
        "../common/_navigation",
        "../common/_modal",
        "../common/_volumetry",
        "home/_header",
        "home/_search-engine",
        "home/_friendly-links",
        "home/_ads-sticky";

Découper en modules

Une façon de s'y retrouver plus facilement est de découper votre code en modules et de les rendre indépendants les uns par rapport aux autres. Pour ce qui est des styles par exemple, je vous conseillerais d'utiliser un préprocesseur CSS comme vu au dessus. Cela vous permet de créer un fichier de style pour chacun des blocs de votre page.

Cette façon de faire permet de savoir où faire des modifications rien qu'en visualisant la page HTML.

Nomenclature

Maintenant que nos fichiers sont bien placés et appelés, il nous faut une convention de nommage de ceux-ci et du code.

Nommage des fichiers et variables

Il n’y a rien de plus irritant que d’avoir au sein d'un même projet des fichiers nommés de façon diamétralement opposée et d’avoir des noms de variables aussi bien en majuscule qu’en CamelCase. D’autant plus que certaines notations ont des significations particulières comme les majuscules qui correspondent souvent à des variables globales.

Il n’y a pas de règles précises, l’idée étant vraiment d’avoir une nomenclature suivie par les membres de l’équipe. De notre côté, nous avons opté pour que les fichiers soient nommés nom-du-fichier.(js/scss/css/less/html/etc), donc tout en minuscule avec des tirets séparant les mots, tandis que les variables soient nommées en lowerCamelCase, c’est à dire avec une majuscule séparant les mots suivant du premier.

noms de fichiers noms de variables
search-engine.less searchEngine
home.js blockHomePage
sticky-footer.js stickyFooter
index.html app

L’utilisation des classes et IDs

Sujet parfois épineux. Chez nous, nous avons fait le choix de bannir les ID des styles. Ainsi il n’y a aucun risque d’écraser le style d’un collègue et de créer un effet de bord. Les IDs restent toutefois autorisés pour le JS ou la QA (Quality Assurance).

Il en va de même pour !important qui est uniquement toléré lorsque l’on doit surcharger un plugin JS qui ajoute des styles inline ou avec ID. Mais dans les faits, il n’est quasi jamais utilisé.

Bien évidemment, on ne met pas de styles dans les balises, pour la lisibilité et parce que leur priorité est plus élevée que les ID. De la même manière, il est dangereux de cibler directement une balise. Il vaut mieux cibler uniquement des classes car vous pourriez décider à tout moment de remplacer votre balise ul par une balise ol par exemple. Si vous aviez mis le style sur la classe, alors vous n'avez aucun risque.

Pour rappel, voici une petite astuce pour connaitre la priorité des sélecteurs et qui nous a pousser à adopter la règle d'autoriser uniquement les classes, pseudo-classes et pseudo-éléments (https://www.w3.org/TR/selectors-3/#specificity) :

Pour connaître le sélecteur qui est appliqué entre ces 4 suivants :

#footer ul li a {}
footer.linksSeo ul li a {}
#footer .linksSeo a {}
footer#footer ul a {}

il suffit de compter les occurrences de chaque type de sélecteurs et les ranger dans un tableau comme ceci :

!important Styles dans la balise IDs Classes / Attributs / :pseudo-classes Balises :pseudo-éléments
0 0 1 0 3 0
0 0 0 1 4 0
0 0 1 1 1 0
0 0 1 0 3 0

Puis de comparer les valeurs obtenues. La plus élevée est 1110 donc le sélection #footer .linksSeo a est prioritaire sur les autres. C’est aussi simple que cela. À égalité, c’est leur placement dans la feuille de style qui les départages, les plus bas écrasant toujours ceux du dessus. Ainsi en n’utilisant que des classes, on peut facilement surcharger un style sans se demander si notre sélecteur doit comporter un ID ou un !important. Voici un lien pour tester la priorité des sélecteurs pour les flemmards (caractéristique propre aux bons développeurs/euses ;-)) : https://specificity.keegan.st/

Ordre des propriétés/valeurs

Dans un soucis de rapidité de lecture, nous avons décidé d’ordonner les couples de propriétés/valeur de styles.

Ce qui demande un petit peu de gymnastique au début devient très vite un réflexe dont vous aurez du mal à vous passer.

L’idée est que lorsqu’une propriété, par exemple le background, est toujours positionnée plus bas que la propriété width, alors il est plus facile de la repérer rapidement. Voici un exemple que nous utilisons où nous avons regroupé les propriétés par logique. Il en existe d'autres comme le rangement par ordre alphabétique.

.selector {
   display
   position
   top
   right
   bottom
   left
   z-index
   overflow
   clear
   width
   height
   line-height
   padding
   margin
   font-family
   font-size
   font-weight
   font-style
   text-decoration
   text-align
   justify-align
   align-content
   color
   background
   border
   text-shadow
   ...
   :hover
   :focus
   ...
   ::afer
   ::before 
}

Disposition des sélecteurs communs

Cela peut paraître bête, mais lorsque vous avez plusieurs sélecteurs auxquels vous attribuez des propriétés/valeurs, écrivez les les uns en-dessous des autres pour gagner en lisibilité.

/* peu conseillé par illisible selon le nombre de sélecteurs */
.firstSelector, .secondSelector, .thirdSelector {
   margin: 20px;
}

/* conseillé car plus lisible */
.firstSelector,
.secondSelector,
.thirdSelector {
    margin: 20px;
}

Trouver le bon cadre

La question du choix de la technologie à utiliser se pose à chaque début de projet. L'un des sujets qui revient encore aujourd'hui est l'utilisation de JQuery. Est-ce bien nécessaire ? L'important est de privilégier des techniques ou technologies qui donnent un cadre, sans forcément passer par un framework.

Lorsque l’on bosse à plusieurs, il vaut mieux prendre une techno maîtrisée par l’ensemble de l’équipe qui est amenée à bosser sur le projet. Il peut être parfois intéressant de pousser une techno qui a le vent en poupe, notamment pour attirer de nouveaux développeurs/euses. Mais chaque technologie a sa période de gloire. De plus, elle n’est pas forcément maîtrisée par tous les futurs candidats prêts à rejoindre le projet. Là je vous conseillerais au maximum de rester framework agnostic. Faire le maximum de vanilla permet d’alléger le projet mais également de garder un code compris par tous, malgré que cela puisse augmenter les temps de développement car il y a plus à faire. Bien évidemment, cela n'empêche pas (et il est même conseillé) de mettre des règles et une architecture basée sur des controllers, dispatchers, components pour gagner en lisibilité.

Enfin définissez des conventions de codage. Afin d'avoir des règles pour le point virgule à la fin des lignes, un nombre d'espaces qui définissent une tabulation, etc.

Bienveillance

Le cadre de travail est tout aussi important. Avec du respect et de la bienveillance, vos collègues et vous serez plus à même de donner le meilleur de vous-même

Être responsable

La première attitude à adopter dans une équipe est d'être responsable. Quand un/e développeur/euse coince sur un sujet, technique ou autre, il vaut mieux en faire part rapidement à l'équipe. Chose évidente lorsque l'on travail en agile où les daily sont des moments privilégiés pour alerter ses camarades.

L'idée est de ne jamais se retrouver au pied du mur à la fin d'un projet. Si chacun prend le temps d'aider les autres, le niveau global s'améliore et personne ne reste coincé et donc non productif. N'hésitez pas à demander à votre manager ou directeur technique un temps de votre charge de travail dédié à l'entraide, la veille technique et les réunions improvisées. Cela évite d'avoir des retards dus aux imprévus et de générer du stress inutilement.

La notion clé du travail en équipe est donc la transparence vis-à-vis de l'équipe.

L’importance de la recette technique

Il est capital de faire valider son code par ses collègues. De une parce que ceux-ci peuvent vous aider à vous évitez de faire passer une coquille. Qui n’a jamais laissé par mégarde un console.log dans son code ? Mais aussi parce qu’ils peuvent vous aider à vous améliorer sur une partie du code où ils auraient fait autrement.

Les pull request doivent être bienveillantes. Il n’y a aucune raison d’être agressif et encore moins de se sentir dévalorisé lors de retours. Il y en a constamment, même pour les meilleurs, car il n’y a pas qu’une manière de coder et certains algo demandent parfois à être débattus. Les pull request peuvent contenir :

  • des améliorations à effectuer (avec explications précises) ;
  • des questions sur la compréhension d'un bout de code ;
  • des encouragements ou félicitations lorsque quelque chose d'intelligent a été fait.

exemples de messages de pull request

Exemples de messages de pull request

Chez nous, une pull request doit être validée par au moins deux développeurs/euses pour que le code puissent continuer son parcours par la QA, recette client puis finir en production.

Une responsabilité partagée

Travailler en équipe demande de se pousser vers le haut. C’est le niveau global de l’équipe qui permet d’avoir un code propre et performant.

L’avantage de la recette technique est que tout le monde est garant du code qui passe en production. Si une coquille ou un bug y arrive c’est que vous n’avez pas bien vérifié le code d’un de vos collègues. Vous êtes donc autant responsable que lui. Il faut donc penser au niveau de l'équipe et non de façon individuelle.

Le versioning

À une époque, il fallait faire attention aux fichiers que vous modifiez pour ne pas écraser le travail de vos collègues. En général, chacun modifiait une page différente pour éviter de se marcher sur les pieds. Mais depuis un bout de temps il existe des solutions pour éviter cela. La gestion de versions permet non seulement de modifier le même fichier sans risque d’effet de bord mais également de garder des sauvegardes de votre code à un instant donné. Ainsi nul besoin de laisser du code commenté pour plus tard. On pourra le récupérer ultérieurement dans l’historique de nos modifications si besoin.

Il existe des systèmes de gestion de versions centralisée comme SVN et décentralisée comme GIT. De nos jours GIT est la solution la plus utilisée donc je vous la conseille pour être à l’aise lors de vos premiers pas dans une nouvelle équipe.

Google Trends GIT/SVN

Partages de connaissances

Dès la conception d'une fonctionnalité ou d'un bloc, vos meilleurs amis sont la feuille et le crayon. Il est toujours plus facile de prendre la bonne direction si on la visualise en amont. Je préconise donc de faire le maximum de schémas et de prendre des notes. Toutes ces informations sont un support pour expliquer à vos collègues votre démarche, un concept ou une problématique à résoudre avec eux. N'oubliez pas qu'une documentation est indispensable pour les nouveaux arrivants ou vous y retrouver quand vous reviendrez sur le projet quelques mois plus tard.

Dans le même état d'esprit, instaurez des Tech Lunch. Le concept est de faire des présentations sur des points techniques aux autres membres de votre équipe. Ils permettent de vous améliorer en faisant des recherches plus pointues sur les sujets qui vous plaisent mais ils permettent surtout d'améliorer le niveau de vos collègues, qui produiront un meilleur code. Nous les faisons à raison d'une fois par mois entre midi et deux.

Automatisation des tâches

Finalement tout ça nous permet d'être plus efficace et de nous relire plus facilement. Mais prendre ces libertés ne permet pas de rendre votre code le plus performant possible. Automatisez au maximum certaines tâches car moins les process sont complexes et moins il y a de risques d'erreurs

Minification

La minification du code est sûrement la plus évidente, elle permet de gagner pas mal d'octets pour gagner en performance sur le site en production. Pour ceci et pour toutes les tâches de cette section, il est intéressant d'utiliser un gestionnaire de tâche. Même chose que pour les technologies JS, il s'agit de voir en fonction des compétences de chacun lequel vous souhaitez utiliser. Si Grunt est ancien, il existe Gulp ou webpack de plus récents, mais vous pouvez choisir d'autres gestionnaires également.

Cette tâche automatisée est très importante puisqu'elle vous permet d'écrire votre code de la façon la plus lisible possible. Vous pouvez privilégier toutes les écritures lisibles même si elles sont plus longues puisque cette tâche optimisera en partie votre code.

Concaténation

La concaténation est le fait de mettre le code de vos fichiers les uns à la suite des autres dans un seul et même fichier. Généralement on regroupe les fichiers JavaScript entre eux et ceux de styles entre eux. L'idée est de n'avoir qu'une seule requête HTTP à faire plutôt qu'une pour chaque fichier.

Autres

exemple de l'intérêt de la compression d'une image

La compression des images est un point clé puisqu'il s'agit très souvent des ressources les plus lourdes. Il est possible de mettre en place des tâches ou de passer par un compresseur d'images en ligne. TinyPNG par exemple : TinyPNG

Conclusion

Vous avez maintenant de nombreuses pistes pour améliorer votre façon de travailler en équipe. Certains éléments de nommage ou façon de faire peuvent être débattus et adaptés à votre équipe, en tenant compte des compétences de vos collègues. Mais gardez en tête que le temps de les mettre en place est un investissement à moyen et long terme. Plus qu'un gain de temps évident par la suite pour développer les futures évolutions, c'est aussi la motivation de l'équipe qui s'en trouvera améliorée.

Publié par Alsacreations.com

Article : Données sémantiques, structurées et associées, le choix JSON-LD

$
0
0

Nous savons bien que dans la multitude d'informations que présentent nos pages Web, certaines sont de première importance et doivent être lisibles et mises en valeur pour les visiteurs en chair et en os mais également pour les machines (robots envoyés par les moteurs de recherche par exemple). Pour ce faire, il avait été conçu un balisage sémantique spécifique : Microformats dans un premier temps, puis Microdata couplés avec HTML5 et les spécifications de Schema.org (voir l'article « Microdata et Schema.org, la sémantique chirurgicale »). Ces nouvelles "empreintes" sémantiques ont été très vite adoptées (voire développées) par les grands acteurs du Web tels que : Google, Yahoo, Bing. Il est donc primordial de ne pas les sous-estimer et d'en faire un usage sans modération notamment pour favoriser le référencement. Or, cette technique présente le désavantage d'ajouter un balisage ou des attributs spécifiques à l'intérieur du contenu des pages, ce qui n'est pas forcément faisable aisément, notamment lorsqu'on utilise un CMS dont le contenu peut être saisi par pléthore d'utilisateurs n'ayant pas forcément le niveau d'expertise suffisant.

logo de JSON-LD

Une nouvelle alternative a vu le jour avec l'avènement du format JSON que nous vous présentions dans l'article « JSON, le stockage léger et pratique de données multitypes » : JSON-LD (JSON pour données associées). Il a la particularité et l'avantage de pouvoir être utilisé hors du contenu des pages (nous verrons cela plus loin) et conserve la légèreté et la simplicité de syntaxe qu'offre JSON. De plus, c'est ce format-là qui est recommandé par Google dans sa rubrique dédiée aux développeurs à des fins d'insertion de données structurées (comprendre le fonctionnement des données structurées dans Google Developpers).

JSON-LD : simplicité, adaptabilité

La dernière spécification de ce format, reconnue par le W3C, standardisée donc, précise en introduction la définition suivante :

JSON is a useful data serialization and messaging format. This specification defines JSON-LD, a JSON-based format to serialize Linked Data. The syntax is designed to easily integrate into deployed systems that already use JSON, and provides a smooth upgrade path from JSON to JSON-LD. It is primarily intended to be a way to use Linked Data in Web-based programming environments, to build interoperable Web services, and to store Linked Data in JSON-based storage engines.

Ce qui pourrait être traduit de la manière suivante :

JSON est un format de linéarisation de données et de messagerie fort utile. Cette spécification définie JSON-LD, un format basé sur celui de JSON pour linéariser des données associées. La syntaxe est conçue pour s'intégrer aisément aux systèmes déployés utilisant déjà JSON et fournit une mise à niveau adaptée pour passer de JSON à JSON-LD. Elle est principalement prévue pour l'utilisation des données associées dans des environnements de programmation Web, afin de créer des services Web interopérables et de stocker des données associées dans des bases de données spécifiques à JSON.

En résumé donc, JSON-LD est une adaptation de JSON qui permet de servir des données associées (utilisant un vocabulaire défini par avance) et structurées sur le Web, de la manière suivante :

‹script type="application/ld+json"›
{
    "@context": "http://schema.org",
    "@type": "Organization",
    "name": "Alsacreations",
    "contactPoint": {
        "@type": "ContactPoint",
        "url": "https://alsacreations.com",
        "email": "contact@alsacreations.com",
        "contactType": "technical support",
        "contactOption": "TollFree"
    }
}
‹/script›
Tester le code

Quelques commentaires au sujet de l'exemple ci-dessus qui propose ici l'identification sommaire d'une organisation :

  • L'objet définissant les données structurées est situé dans une balise HTML ‹script›, quoi de plus normal, puisque JSON-LD est un objet JavaScript ! Cependant, l'attribut type de cette balise diffère un peu de ce que l'on a l'habitude de voir  (application/ld+json) mais cela reste tout à fait compréhensible.
  • S'agissant de l'objet JSON (code entre les parenthèses racines), on a bien la syntaxe habituelle, c'est à dire une liste de paires clé/valeur (sous la forme "clé":"valeur") séparées par des virgules. Quelques spécificités tout de même :
    • Des clés commençant par @ qui vont indiquer l'association :
      • @context permet d'indiquer le "vocabulaire" utilisé. Nous n'utiliserons dans cet article que celui de Schema.org.
      • @type représente le type de propriété racine qui est défini. L'arborescence de ces types se trouve sur le site de Schema.org. Chaque élément de cette liste est un type de propriété qui pourra être défini par des sous-propriétés et ainsi de suite. Le type hiérarchiquement le plus élevé (racine donc) dans notre exemple est Organization.
    • Des clés dont la valeur est un objet (ou un tableau, nous le verrons plus tard). Dans notre exemple, contactPoint est un objet composé de quatre éléments, le premier indiquant la propriété racine, et les trois autres définissant le courriel, ce à quoi ce courriel va servir (aide technique, commerciale,…) et la gratuité du service. Il est possible de définir plusieurs contacts ainsi, simplement en ajoutant d'autres objets du même type (attention, la valeur de contactPoint sera dans ce cas défini comme un tableau composé d'objets et donc délimité par des crochets). Exemple :
      ‹script type="application/ld+json"›
      {
          "@context": "http://schema.org",
          "@type": "Organization",
          "name": "Alsacreations",
          "contactPoint": [
              {
              "@type": "ContactPoint",
              "url": "https://alsacreations.com",
              "email": "contact@alsacreations.com",
              "contactType": "technical support",
              "contactOption": "TollFree"
              },
              {
              "@type": "ContactPoint",
              "url": "https://alsacreations.fr",
              "email": "contact@alsacreations.fr",
              "telephone": "+33 954965050",
              "contactType": "customer support"
              }
          ]
      }
      ‹/script›
      Tester le code

      Sachez également que les valeurs possibles pour les différentes clés sont indiquées sur Schema.org mais elles peuvent être imposées par Google afin d'être reconnues. En effet, la valeur pour contactType devrait pouvoir être n'importe quel texte d'après la spécification Schema.org, mais pour pouvoir être comprise par les robots de Google, il faudra qu'elle corresponde à une des valeurs suivantes : customer support, technical support, billing support, bill payment, sales, reservations, credit card support, emergency, baggage tracking, roadside assistance, package tracking. De même pour contactOption, seules deux valeurs sont prises en compte pour le moment : TollFree, HearingImpairedSupported.

Cette dernière remarque à propos des contraintes imposées par Google nous fait naturellement nous poser la question suivante : comment être sûr que la syntaxe des données servies sera bien interprétée par les GoogleBots ? Fort heureusement, un outil mis à disposition par l'entreprise de la Silicon Valley vous permettra de vérifier cela, il se nomme Outil de test des données structurées. Voici ce à quoi ressemble la validation du code ci-dessus :

Outil de validation des données structuréesCette validation est soumise à des règles définies dans la documentation de référence des données structurées. Outre l'obligation d'utiliser certaines valeurs pour quelques types, on y définit des propriétés obligatoires et d'autres recommandées ou facultatives. Nous vous conseillons donc de partir de ces références pour créer vos propres données sémantiques associées.

Dernier point à traiter : où placer le script ? Google préconise de le placer dans la section ‹head›, mais rien ne vous empêche de l'insérer dans le ‹body› à l'endroit que vous souhaitez. Vous comprendrez aisément que, dans ces conditions, l'ajout des données sémantiques sera simplifié, puisqu'elles seront regroupées à un même endroit et pourront être générées automatiquement plus aisément (nous verrons un exemple ultérieurement).

Exemples d'affichage riches dans une recherche Google

Mettons à présent les mains dans le cambouis et passons à l'élaboration du balisage de différents types de ressources en respectant les lignes de conduites du célèbre moteur de recherche. Cela nous permettra notamment de favoriser l'affichage dit "riche" dans ses résultats de recherche ce qui représente une plus-value non-négligeable notamment pour la visibilité de vos articles.

Balisage d'un article

Les propriétés

Il faut tout d'abord savoir que le format recommandé par Google pour prétendre à un "affichage riche" d'un article est l'AMP, veuillez vous rendre à la section AMP du guide pour de plus amples informations à ce sujet. Mais il est également possible de partir sur une solution non-AMP (c'est ce que nous allons nous attacher à faire ici). Voici les éléments recommandés pour les propriétés Article, NewsArticle et BlogPosting (toutes les trois sont prises en charge) :

Propriétés recommandées Description
dateModified La date et l'horaire de dernière modification au format ISO 8601.
"dateModified": "2019-01-20T20:00"                                          
datePublished La date et l'horaire de publication au format ISO 8601.
"datePublished": "2019-01-20T10:00"        
headline Le titre de l'article (ne devrait pas dépasser 110 caractères)
image Plusieurs occurrences de ImageObject ou URL. Il faudra respecter les préconisations suivantes :
  • Les images devront avoir une largeur minimum de 696px.
  • Elles devront se trouver sur la page Web associée sous forme de balise ‹img›.
  • Chaque page devra comporter au moins une image. Le choix d'affichage sera fait en fonction du ratio et de la résolution (définition)
  • Trois formats d'image sont pris en charge : .jpg, .png, .gif.
  • Afin d'améliorer les résultats, fournir plusieurs images à haute résolution (minimum : 300 000px) dont les ratios sont les suivants : 16x9, 4x3 et 1x1. Exemple :
    {
        "@context": "https://schema.org",
        "@type": "NewsArticle",
        "image": [
            "https://exemple.fr/img/photo-1x1.jpg",
            "https://exemple.fr/img/photo-4x3.jpg",
            "https://exemple.fr/img/photo-16x9.jpg"
        ]
    }

Évidemment, vous pouvez ajouter d'autres propriétés à votre balisage, même si elles ne seront pas prises en compte forcément par Google. Concrètement, voici le code qui pourrait définir l'article que vous êtes en train de lire :

‹script type="application/ld+json"›
{
    "@context": "https://schema.org",
    "@type": "Article",
    "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://www.alsacreations.com/article/lire/1780-donnees-semantiques-structurees-associ%C3%A9es-le-choix-JSON-LD.html"
    },
    "headline": "Données sémantiques, structurées et associées, le choix JSON-LD",
    "image": "https://www.alsacreations.com/xmedia/doc/original/validation_json-ld.png",
    "datePublished": "2019-02-06T08:00:00+08:00",
    "dateModified": "2019-02-08T09:20:00+08:00",
    "author": {
       "@type": "Person",
       "name": "Jojaba"
    },
    "publisher": {
       "@type": "Organization",
       "name": "Alsacreations",
       "url": "https://www.alsacreations.com",
       "logo": {
          "@type": "ImageObject",
          "url": "https://cdn.alsacreations.net/android-chrome-192x192.png"
       }
    },
    "keywords":"sémantique, référencement, seo, google, microformats, microdata, json-ld"
}
‹/script›
Tester le code

Vous constaterez que seule une image a été intégrée à ce balisage (alors qu'il est préconisé d'en fournir 3 de différents ratios), cela n'empêchera pas Google de l'utiliser si votre article se retrouve dans les résultats de recherche.

La génération automatique de balisage dans un CMS - exemple de WordPress

Afin d'automatiser la génération de ce balisage, nous pouvons à présent utiliser les fonctions mises à disposition par un gestionnaire de contenu tel que WordPress.

Les données dont nous avons besoins pour un article sont :

  1. l'url de la page de l'article,
  2. le titre de l'article,
  3. une image pertinente au sujet de l'article,
  4. la date de publication au bon format,
  5. la date de modification au bon format,
  6. l'auteur,
  7. les mots clés.

Nous pouvons retrouver toutes ces informations en ajoutant le code suivant dans le gabarit dédié à l'affichage d'un article (typiquement, dans WordPress, content.php, n'oubliez pas que les fonctions utilisées ci-dessous doivent l'être dans la Boucle) :

<?php
$art_url = get_permalink(); // 1
$art_title = get_the_title(); // 2 (on pourrait vérifier si le titre comporte plus de 110 caractères et le tronquer)
$art_img = (has_post_thumbnail()) ? get_the_post_thumbnail_url(get_the_ID(),'full') : false; // 3
$art_pub_date = get_the_date('c'); // 4 ("c" est le paramètre qui affiche le résultat au format ISO 8601 à partir de php5)
$art_modif_date = get_the_modified_date('c'); // 5
$art_author = get_the_author(); // 6
$art_keywords = (get_the_tags()) ? implode(",", get_the_tags()) : false; // 7
?>
<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Article",
    "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "<?php echo $art_url; ?>"
    },
    "headline": "<?php echo $art_title; ?>",
    <?php if ($art_img): ?>
    "image": "<?php echo $art_img; ?>",
    <?php endif; ?>
    "datePublished": "<?php echo $art_pub_date; ?>",
    "dateModified": "<?php echo $art_modif_date; ?>",
    "author": {
        "@type": "Person",
        "name": "<?php echo $art_author; ?>"
    },
    <?php if ($art_keywords): ?>
    "keywords":"<?php echo $art_keywords ?>"
    <?php endif; ?>
}
</script>

Là encore, une seule image de référence définie (au lieu des trois aux trois ratios demandés). Cela ne posera pas de problème tant que l'image sera suffisamment grande et qu'elle ait une définition convenable. Cependant, il faudra s'assurer que cette image est bien affichée dans le contenu de l'article (ce n'est pas forcément le cas).

Il existe d'ores et déjà des plugins de WordPress permettant d'ajouter le balisage JSON-LD, ils n'ont pas été testés pour les besoins de cet article, mais peuvent représenter un gain de temps appréciable. N'hésitez pas à faire des commentaires à ce sujet si vous souhaitez faire un retour d'expérience.

En outre, nous vous avons proposé ici une génération côté serveur (en php), mais il serait tout à fait possible de le faire côté client en utilisant JavaScript et en parcourant le dom afin de retrouver les éléments nécessaires et les ajouter dans le script de manière dynamique.

Fil d'ariane

Elément assez important également pour le référencement. Voici un balisage factice.


‹script type="application/ld+json"›
{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [{
    "@type": "ListItem",
    "position": 1,
    "name": "Outils Web",
    "item": "https://exemple.com/outils-web"
    },{
    "@type": "ListItem",
    "position": 2,
    "name": "Vidéos",
    "item": "https://exemple.com/outils-web/videos"
    },{
    "@type": "ListItem",
    "position": 3,
    "name": "Lecteurs disponibles",
    "item": "https://exemple.com/outils-web/videos/lecteurs-disponibles.html"
    }]
}
‹/script›
Tester le code

Balisage d'événements

Quelques recommandations préalables avant l'énumération des propriétés :

  • Le type Event est la base de confection du balisage.
  • Chaque évènement doit être défini par une url unique.
  • Chaque évènement devra comporter un titre, une date de début et une localisation.
  • Eviter de baliser des non-évènements en évènenents.
  • Marquer les évènements se déroulant sur plusieurs jours convenablement :
    • Indiquer le début et la fin de l'évènement.
    • S'il y a plusieurs manifestations durant l'évènement, les définir chacune comme étant un évènement à part entière.

Les propriétés à utiliser :

Propriétés obligatoires Description
location L'emplacement au format Place. Exemple :
"location": {
    "@type": "Place",
    "name": "Bureaux d'Alsacreations"
}                   
location.address L'adresse détaillée :
"address": {
    "@type": "PostalAddress",
    "streetAddress": "10 Place du Temple Neuf",
    "addressLocality": "Strasbourg",
    "postalCode": "67000",
    "addressCountry": "FR"
}                  

Bonnes pratiques :

  • Si l'évènement a lieu dans plusieurs rues ou emplacements, définir l'emplacement de départ et indiquer davantage d'informations dans la propriété description.
  • Si aucun lieu n'est défini précisément, utiliser le nom de ville ou l'emplacement le plus représentatif.
  • Si l'évènement à lieu à différents endroits, créer un évènement pour chaque emplacement.
name Le titre de l'évènement. Par exemple :
"name": "Alsacreations : KiwiParty 2019"

Bonnes pratiques :

  • N'indiquer qu'un seul aspect de l'évènement.
  • Ne pas ajouter de promotions, de publicité, de prix.
startDate La date et l'horaire au format ISO 8601.
"startDate": "2019-03-21T08:00"
Si vous ne connaissez pas l'horaire, ne pas l'ajouter.
"startDate": "2019-03-21"  
Propriétés recommandées Description
description Décrire le plus précisément l'évènement. Google n'affichera qu'une partie de cette description.
endDate Voir startDate.
image Plusieurs occurrences de ImageObject ou URL. Il faudra respecter les préconisations suivantes :
  • Les images devront avoir une largeur minimum de 720px.
  • Elles devront se trouver sur la page Web associée sous forme de balise ‹img›.
  • Chaque page devra comporter au moins une image. Le choix d'affichage sera fait en fonction du ratio et de la résolution (définition)
  • Trois formats d'image sont pris en charge : .jpg, .png, .gif.
  • Afin d'améliorer les résultats, fournir plusieurs images à haute résolution (minimum : 500 000px) dont les ratios sont les suivants : 16x9, 4x3 et 1x1. Exemple :
    {
       "image": [
       "https://exemple.fr/img/photo-1x1.jpg",
       "https://exemple.fr/img/photo-4x3.jpg",
       "https://exemple.fr/img/photo-16x9.jpg"
     ]
    }  
offers

Basé sur Offer. Une offre donnant accès à des droits ou fournissant un service (exemple : achat de billets).

"offers": {
    "@type": "Offer",
    "availability": "https://schema.org/InStock",
    "price": "39",
    "priceCurrency": "EUR",
    "validFrom": "2019-01-20T16:20-08:00"
    "url": "https://www.exemple.com/offre/vente-de-billets"
}                     
  • availability indique la disponibilité des billets. 3 possibilités :
    • InStock : disponibles.
    • SoldOut : plus disponibles.
    • PreOrder : pré-commande.
  • price : le premier prix (le billet le moins cher).
  • priceCurrency est défini par le format de devise ISO 4217.
  • ValidFrom : à partir de quand peut-on acheter les billets ?
  • L'url indique l'emplacement de la page sur laquelle on peut acheter les billets, elle doit être accessible par un lien présent sur la page de l'évènement.
performer Basé sur PerformingGroup ou Person. Est considéré comme "PerformingGroup", un groupe, un orchestre, un cirque,…
"performer": {
    "@type": "PerformingGroup",
    "name": "Orchestre Philharmonique de Strasbourg"
}                      

Exemple de balisage d'un évènement, la KiwiParty 2018 (données de balisage tirées de cette page Web) :

‹script type="application/ld+json"›
{
    "@context": "https://schema.org",
    "@type": "Event",
    "name": "Alsacreations: KiwiParty 2018",
    "url": "http://2018.kiwiparty.fr/",
    "startDate": "2018-06-15T08:45",
    "location": {
      "@type": "Place",
      "name": "Télécom Physique Strasbourg",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "Pôle API - 300 Bd Sébastien Brant",
        "addressLocality": "Illkirch Graffenstaden",
        "postalCode": "67400",
        "addressCountry": "FR"
      }
    },
    "image":"http://2018.kiwiparty.fr/assets/img/photo.jpg",
    "description": "La conférence Web d'une journée dédiée à la qualité, au design, à la performance et à l'accessibilité du Web.",
    "endDate": "2018-06-15T19:00",
    "offers": {
        "@type": "Offer",
        "availability": "https://schema.org/InStock",
        "url": "https://ti.to/alsacreations/kiwiparty-2018",
        "price": "0",
        "priceCurrency": "EU",
        "validFrom": "2018-06-01T08:00"
      },
    "performer": [
        {
        "@type": "PerformingGroup",
        "name": "Alsacreations",
        "url": "https://alsacreations.fr"
        },
        {
        "@type": "PerformingGroup",
        "name": "Wdstr",
        "url": "http://wdstr.fr/"
        }
    ]
}
‹/script›    
    
Tester le code

Petits commentaires :

  • Là encore, une seule image associée à cet évènement au lieu des 3 nécessaires.
  • La propriété Offers est réclamée par le validateur Google (avertissements si elle manque), mais n'est pas obligatoire. Voici la signification des différentes sous-propriétés dans cet exemple :
    1. Il reste des places.
    2. L'url est l'adresse de la page d'inscription.
    3. C'est gratuit.
    4. La devise utilisée est l'Euro.
    5. Le début des inscriptions est fixé au 1er juin à 8H00.
  • Concernant la propriété performer, nous aurions pu ajouter tous les intervenants de la KiwiParty sous forme de @Person.

Conclusion

Bien d'autres propriétés sont prises en charge, il suffit de se rendre sur la page de références des données structurées proposée sur Google Developers pour en prendre connaissance. Nous sommes hélas dépendant du géant de la recherche mais c'est également grâce à lui que les choses progressent dans le domaine du Web, il est donc important de se conformer à ses directives.

Voici les ressources qui ont été utilisées pour confectionner cet article :

Publié par Alsacreations.com

Actualité : Votre éditeur de code favori en 2019 ?

$
0
0

Le choix d'un éditeur de code avec lequel on est à l'aise est crucial pour maîtriser ses outils et gagner du temps. Cependant, on sait aussi qu'il est difficile de changer ses habitudes et de remettre en cause ses préférences au fil des évolutions, de plus en plus rapides, des outils de conception.

Et vous, quel éditeur de code a comblé vos attentes ?

Peut-être utilisez-vous le vôtre depuis plusieurs années, que vous venez d'en tester un tout neuf qui vous a rendu accro, ou encore que vous cherchez la perle rare sans parvenir à mettre la souris dessus... Dans ce cas, pourquoi ne pas jeter un coup d'oeil du côté de vos voisins ?

Alors, dites-nous tout ! 

Publié par Alsacreations.com


Actualité : Microsoft Edge passe à Chromium

$
0
0

Après l'avoir annoncé, Microsoft dévoile la première version de son navigateur Edge tournant avec le moteur Chromium, téléchargeable pour Windows sous plusieurs saveurs si vous avez l'esprit d'aventure : beta (bientôt), dev (compilé toutes les semaines), et canary (compilé tous les jours).

Microsoft Edge insider channels

Après avoir fait souffrir donné du fil à retordre aux intégrateurs web durant des années avec Internet Explorer qui représentait à lui seul à une époque plus de 90% de parts de marché, après avoir amorcé une grande refonte et tenté un changement d'image et de nom avec Edge et son moteur EdgeHTML, c'est une petite révolution. Quelles en sont les motivations ? Gagner à nouveau des utilisateurs, faire des économies (développer un moteur web de nos jours demande de nombreuses ressources), disposer d'un plus grand catalogue d'extensions, concurrencer Chrome sur son propre terrain ainsi que sur le mobile.

D'un autre côté, cela ne profite pas à la diversité du web et de ses moyens d'accès en concentrant encore plus de pouvoir autour des développeurs de Chrome/Chromium. Opera avait déjà fait le pas il y a quelques années en abandonnant son propre moteur (Presto), et la plupart des autres navigateurs y font appel aussi, hormis bien sûr Firefox qui dispose toujours de Gecko et Safari de WebKit. Notez que Chromium est un fork de WebKit datant de 2013, ce qui explique quelques similitudes.

Edge sous Chromium

Microsoft voudra cependant s'affranchir de Google tout en contribuant au projet open-source, ce qui n'est pas chose aisée en reprenant un tel moteur, ne serait-ce qu'avec le service de géolocalisation qui est lié par défaut aux services de Google ; Firefox lui-même sollicite Google Location Services. Mais les développeurs ont désactivé ou remplacé la majorité de ces services qui communiquent des données utilisateur à Google (Translate, Pay, Ad Block, Safe Browsing, la reconnaissance vocale, etc), preuve qu'il ne s'agit pas d'une simple copie revêtant une autre peau. D'ailleurs ces premières versions sont encore incomplètes, les testeurs sont encouragés à faire des retours et consulter le site officiel Microsoft Edge Insider.

Du côté de l'accessibilité, Microsoft Edge 16 accomplissait déjà l'exploit d'afficher de bons résultats et un score de 100% au test HTML5 Accessibility. Il y a donc tout ce travail qui devra être réintégré ainsi que les fonctionnalités propres à Microsoft. Les efforts persistants du côté des standards devraient être soutenus, dont des propositions d'implémentations à venir telles que HTML Modules et une concentration sur des domaines tels que l'économie d'énergie, le touch, la sécurité, ARM64 ou encore les polices.

La plupart des menus, options et composants ont été transités vers un nommage "Microsoft", avec une recherche par défaut sur Bing. L'interface reprend les codes déjà établis par Edge pour ne pas trop dépayser, tout en exposant la même mécanique et les mêmes outils de développement (F12) que la famille Chrome. La chaîne d'User-Agent se fait bien sûr passer à la fois pour Edge, WebKit, Chrome, Safari, mais on sait depuis longtemps qu'il ne faut plus surveiller ce genre d'indication : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3757.0 Safari/537.36 Edg/75.0.124.0.

Enfin, si vous voulez explorer ce qui se cache sous le capot, faites un tour à l'URL edge://edge-urls/

Publié par Alsacreations.com

Actualité : Votre outil de design privilégié pour 2019 ?

$
0
0

Quelques jours plus tôt, nous vous avions interrogés sur votre éditeur de code favori. Cette fois-ci, c'est au tour des designers de nous parler de leur outil préféré pour la création d'interfaces web ! Nouvelle bonne résolution ou coup de cœur sur la durée, certain·e·s préfèrent continuer leur route avec un compagnon de longue haleine tandis que d'autres tenteront l'aventure avec les solutions les plus récentes.

Et vous, de quelle team faites-vous parti ?

Toujours à l'aise sur les logiciels qui ont fait leurs preuves comme Photoshop ou Illustrator ? Plutôt testeurs·es des avants-premières comme Invision Studio ? À randonner hors des sentiers battus avec Affinity ? Ou préférez-vous adopter des solutions qui se sont taillé une place entre les géants du marché, comme Sketch, Adobe XD ou Figma ?

Publié par Alsacreations.com

Astuce : Copier du texte dans le presse-papier système

$
0
0

Copier vers le presse-papier du système d'exploitation une information provenant du document est une tâche que l'on souhaite parfois réaliser pour faciliter la vie de l'utilisateur, lors de l'utilisation d'une application web : une chaîne aléatoire complexe, une URL, une clé, ou tout simplement un message... C'est à la portée de la fonction JavaScript execCommand() qui prend en paramètre l'opération que l'on souhaite réaliser copy (copier), cut (couper), paste (coller).

On retrouve ce principe souvent sur les fonctions de partage de document par lien tel que sur Google Drive :

Google Drive partage par lien

Ceci fait l'objet d'une spécification "non officielle" execCommand pourtant très bien supportée par tous les navigateurs. A terme, on devrait plutôt s'orienter vers ContentEditable et Input Events

Supposons que vous avez structuré le texte à copier de la façon suivante, dans un quelconque élément HTML :

<p>
   Copiez cette adresse : <span id="tocopy">https://www.knacss.com/</span>
</p>

On va y adjoindre un bouton d'action pour lancer la copie, doté d'une classe js-copy pour lui lier un événement JavaScript et un attribut data-target permettant de ne pas coder "en dur" dans la fonction correspondante l'élément cible. Ceci a l'intérêt de pouvoir réutiliser cette même classe js-copy avec de multiples éléments, chacun définissant quelle est sa "source" d'information.

<p>
   Copiez cette adresse : <span id="tocopy">https://www.knacss.com/</span>
   <input type="button" value="Copier" class="js-copy" data-target="#tocopy">
</p>

Sans plus attendre, le script associé, qui va se servir des méthodes createRange et getSelection pour sélectionner une portion de contenu dans le document et ensuite exécuter par-dessus la commande de copie :

var btncopy = document.querySelector('.js-copy');
if(btncopy) {
    btncopy.addEventListener('click', docopy);
}

function docopy() {

    // Cible de l'élément qui doit être copié
    var target = this.dataset.target;
    var fromElement = document.querySelector(target);
    if(!fromElement) return;

    // Sélection des caractères concernés
    var range = document.createRange();
    var selection = window.getSelection();
    range.selectNode(fromElement);
    selection.removeAllRanges();
    selection.addRange(range);

    try {
        // Exécution de la commande de copie
        var result = document.execCommand('copy');
        if (result) {
            // La copie a réussi
            alert('Copié !');
        }
    }
    catch(err) {
        // Une erreur est surevnue lors de la tentative de copie
        alert(err);
    }

    // Fin de l'opération
    selection = window.getSelection();
    if (typeof selection.removeRange === 'function') {
        selection.removeRange(range);
    } else if (typeof selection.removeAllRanges === 'function') {
        selection.removeAllRanges();
    }
}

Démo

See the Pen Copier by Alsacreations (@alsacreations) on CodePen.

Pour savoir si une commande est supportée par le navigateur, on peut interroger la méthode queryCommandSupported en lui passant en paramètre le nom de la commande :

document.queryCommandSupported('copy')

Publié par Alsacreations.com

Actualité : Drupagora 2019

$
0
0

Drupagora 2019 aura lieu le jeudi 27 juin à l'Université Pierre et Marie Curie, Paris 5ème.

Cet événement centré autour de Drupal (mais pas que) accueille jusqu'à 400 participants pour 20 conférences, ateliers et retours d'expériences.

Vous pouvez d'ores et déjà consulter le programme qui aborde des thématiques aussi diverses que l'architecture, la performance, la sécurité, le développement en général, la méthodologie, les contraintes règlementaires, l'e-commerce, etc.

Si ces sujets vous interpellent et que le monde du web est votre quotidien, inscrivez-vous !

Afflurence à Drupagora

Publié par Alsacreations.com

Tutoriel : Grid Layout et positionnement absolu

$
0
0

Si Grid Layout nous permet aujourd’hui de créer des designs fluides et responsive de manière très simple et permettant de favoriser la sémantique et la lisibilité de notre HTML, saviez vous que cette propriété CSS fonctionne également très bien avec des enfants en position absolue ?

Ma grille de base

Une des forces de Grid Layout est de pouvoir créer un motif de ligne qui va se répéter dès qu’elle sera pleine. Pour le design de mon site, disons que mon graphiste travaille avec une grille de 12 colonnes. Je vais donc créer ma ligne de grille de base :

<body>
  <section class="grid">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    ...
  </section>
</body>
body {
  padding: 2.5rem;
  background-color: AntiqueWhite;
}

* { 
  box-sizing: border-box;
}

.grid {
  display: grid;
  grid-gap: 1.5rem;
  grid-template-columns: repeat(12, 1fr);
}

.item {
  padding: 1.5rem 0;
  background-color: coral;
}

Ma grille simple de 12 colonnes

Comme on le constate, par défaut, si j’ai plus de 12 objets, grid va créer une nouvelle ligne de 12 colonnes et ainsi de suite. Tous les éléments de grilles générés ainsi sont appelés grille implicite. Nous en verrons l'intérêt plus tard.

En passant, petite astuce pour vous simplifier la vie lorsque vous travaillez avec les grilles en CSS. Si vous avez un navigateur digne de ce nom, vous devriez pouvoir afficher un overlay d'aperçu de votre grille en cliquant sur un de ces boutons dans votre inspecteur:

Afficher ma grille dans l'inspecteur du navigateur

Voyons un cas concret

Notre graphiste nous donne ce très beau bloc à intégrer.

Mon beau design

On peut découper cette maquette en 3 blocs de contenus qui vont apparaitre dans ma grille :

  • Un bloc de titre
  • Un bloc de texte
  • Un bloc illustration

Ce qui nous donne le code html suivant :

<body>
  <section class="grid">
    <h1  class="item text-content">Titre</h1>
    <p   class="item text-content">Texte</p>
    <div class="item illustration">Illus.</div>
  </section>
</body>

Jusqu'ici pas de pépins, passons au style.

Contenu textuel

Le titre et le texte commencent à la première colonne de la grille et font 8 colonnes de large. Vu que grid génère automatiquement des lignes en fonction du contenu, le bloc <p class="item text-content">Texte</p> va se trouver dans une nouvelle ligne de la grille. Pas besoin donc de spécifier de grid-row pour ces blocs la.

.text-content {
  grid-column: 1 / span 8;
}

Contenu illustrationnel

Le bloc illustration commence à la colonne 9 et fait 4 colonnes de large. Il est aussi haut que le titre et le texte, donc il doit prendre 2 lignes de ma grille. Voici le code que l'on ajoute:

.illustration {
  grid-column: 9 / span 4;
  grid-row: 1 / span 2;
}

Voilà le résultat:

Nos blocs mis en forme

Versions alternatives

Petit aparté: grid nous permet d'écrire les choses de différentes manières. Par exemple si j'avais énoncé ma problématique autrement, j'aurais pu dire que les blocs de texte commençaient à la colonne 1 et finissaient à la 9. Ou encore que le bloc d'illustration faisait 4 colonnes de large et terminait à la dernière colonne.

.text-content {
  grid-column: 1 / 9;
}

.illustration {
  grid-column: span 4 / -1;
  grid-row: 1 / 3;
}

Le rendu sera exactement le même, c'est simplement une autre façon de faire. Il n'y a pas de meilleur manière de l'écrire, le tout est de rester cohérent. Enoncer le comportement que doit avoir un bloc comme nous l'avons fait est une bonne manière de procéder.

Web is about flexibility

Super, nous sommes arrivés à nos fins (je vous fait volontairement fi de la couche graphique, ici c'est la grille qui nous intéresse). Après une petite démo notre graphiste est satisfait·e et nous soumet les déclinaisons suivantes :

Mon beau design décliné

En clair, quel que soit le nombre de blocs de texte, notre image doit toujours faire toute la hauteur de ces derniers (et donc de la grille). Pas de soucis, grid est un outil très puissant, voyons comment se comporte notre code en l'état.

Si j'ajoute un paragraphe :

layout avec deux paragraphes

Si je laisse uniquement le titre :

layout avec titre uniquement

On est plutôt pas mal, vu qu'on ajoute la classe .text-content à nos blocs textuels, ils occuperont toujours le même espace de la grille, créant ainsi de nouvelles lignes et ainsi de suite. Notre bloc illustration quant à lui commence à la ligne 1 de la grille et prend actuellement 2 lignes de haut, il faudrait pouvoir le faire commencer à la première et finir à la dernière ligne. On pourrait se dire que grid-row : 1 / -1 pourrait faire l'affaire mais il n'en est rien. Pourquoi donc ?

Tout simplement parce qu'une valeur de -1 à grid-row-end va cibler la dernière ligne explicite de la grille. Je vous le rappelle, ici c'est le contenu qui fait la grille, vu que les lignes ne sont pas définies (avec grid-templates-rows par exemple), les lignes sont générées. Il s'agit donc de lignes implicites. Pourquoi définir un nombre de lignes alors qu'on ignore encore la quantité de contenu qu'elles vont accueillir ? Que faire dans ce cas ?

Positionnement absolu à la rescousse !

La solution la plus simple pour nous va être de positionner notre bloc d'illustration en absolu par rapport à la grille. Ajoutons donc le code suivant à notre css et observons le résultat:

.grid {
  ...
  position: relative;
}
.illustration {
  ...
  position: absolute;
}

Bien que notre bloc soit positionné de manière absolue dans notre grille, il a quand même l'air de bien se placer par rapport à ses confrères. Pourtant il est bien sensé être positionné par défaut en haut à gauche de son conteneur relatif le plus proche, alors pourquoi ne se superpose-t-il pas avec notre bloc de titre? What sorcery is this?

Mon référentiel de positionnement absolu dans la grille

En fait c'est plutôt simple à comprendre. Dans une grille, le référentiel d'un element en absolu est défini en largeur par grid-column-start et grid-column-end s'ils sont renseignés. Mon left: 0 correspondra donc ici au début de ma colonne numéro 9, plutôt intéressant non ?

En prenant compte de cette information, je vais ajouter le code suivant à mon bloc illustration:

.illustration {
  ..
  left: 0; 
  top: 0;
  right: 0;
  bottom: 0;
}

Il prendra donc toute la largeur de 4 colonnes en commençant à la colonne 9. Qu'en est-il de la hauteur ? Le bloc va-t-il prendre toute la hauteur de ma grille ? Non mais presque. Comme je l'ai expliqué, si le referentiel est défini en largeur par les propriétés grid-column, il en est de même pour la hauteur avec grid-row: actuellement notre bloc commence à la première ligne et prend deux lignes. Son référentiel bas est donc le bas de la deuxième ligne de la gille. En supprimant la propriété grid-row je lui rend son référentiel en hauteur par défaut à savoir le haut et le bas de ma grille.

C'est gagné, mon élément prendra bien toute la hauteur de sa grille, peu importe le nombre de lignes. De plus nous n'aurons pas à craindre que du contenu textuel soit recouvert vu qu'ils s'arrêtent tous à la fin de la 8eme colonne. Voici un codepen avec le code final. N'hésitez pas à vous l'approrier et tester par vous même.

See the Pen Etape 3 : mon illustration en absolue by olivierstl (@olivierstl) on CodePen.

Pour aller plus loin

Nous avons abordé ici une intégration d'une maquette assez simple avec certaines des nouvelles propriétés qui gravitent autour des spécifications Grid Layout mais nous n'avons fait qu'effleurer la surface. La manière d'utiliser les grilles que je vous ai présenté n'est qu'une des nombreuses manière d'intégrer notre bloc.

Définir les lignes de notre grille

Pour le moment, la grille génère de nouvelles lignes automatiquement lorsque c'est nécessaire. Il est possible de renseigner une hauteur minimale et maximale pour ces lignes par exemple. Ici on définit la taille d'une ligne de grille créée de façon implicite en lui disant qu'elle doit faire au minimum 3rem de haut et au maximum, la taille de son contenu.

.grid {
  ...
  grid-auto-rows: minmax(3rem, auto);
}

Afficher notre image dans notre bloc illustration

Avec notre bloc illustration étirable, le portrait de notre cher Nicolas Cage risque d'être quelque peu déformé et maltraité. Nous pourrions utiliser une background-image et appliquer background-size afin que notre image prenne bien la taille de son conteneur mais on perdrait la possibilité d'avoir une image qui pourrait s'avérer sémantiquement nécessaire dans notre html. Comment faire donc ? Mais avec la propriété super chouette object-fit pardi !

<div class="item illustration">
  <img src="https://tinyurl.com/y5ehdyup" alt="Nicolas FTW">
</div>
.illustration img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Ici on spécifie à l'image qu'elle doit prendre 100% de son conteneur en hauteur et largeur. Ensuite object-fit va fonctionner comme background-size et évitera à l'image de se déformer. Résultat, aucune espace vide, elle est pas plus belle la vie ? Vous noterez que j'ai supprimé le padding sur le bloc illustration pour être sur que l'image arrive aux bords du bloc.

See the Pen Etape bonus : Nicolas ftw by olivierstl (@olivierstl) on CodePen.

Image à la une par Simone Hutsch sur Unsplash

Retrouvez l'intégralité de ce tutoriel en ligne sur Alsacreations.com

Viewing all 405 articles
Browse latest View live