Mes impressions sur le web, les standards et autres…


Favicon et requètes sauvages

À destination de toute personne utilisant Firefox ou autres navigateurs basés sur Mozilla, mode d’emploi pour désactiver les requètes sauvages à destination d’un hypothétique fichier favicon.ico à la racine des sites que vous visitez :

  • Tapez about:config dans la barre d’adresse du navigateur puis validez
  • Cherchez dans la liste l’option browser.chrome.favicons
  • Double-cliquez sur la ligne de l’option en question ou clic droit sur la ligne puis sélectionnez Toggle dans le menu contextuel ou sélectionnez la ligne en question avec les touches fléchées du clavier puis tapez sur la touche entrée
  • Redémarrez le navigateur

Juste un petit extrait du contenu de mes logs :

83.200.*.* - - [07/Aug/2005:16:48:03 +0200] "GET /favicon.ico HTTP/1.1" 404 6714 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.7.10) Gecko/20050717 Firefox/1.0.6"
83.200.*.* - - [07/Aug/2005:16:48:03 +0200] "GET /favicon.ico HTTP/1.1" 404 6714 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.7.10) Gecko/20050717 Firefox/1.0.6"
83.200.*.* - - [07/Aug/2005:16:48:04 +0200] "GET /favicon.ico HTTP/1.1" 404 6319 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.7.10) Gecko/20050717 Firefox/1.0.6"
83.200.*.* - - [07/Aug/2005:16:48:15 +0200] "GET /favicon.ico HTTP/1.1" 404 6714 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.7.10) Gecko/20050717 Firefox/1.0.6"

Non, non, y en a pas. Je sais, c’est dur à accepter mais c’est comme ça. Le jour où j’ajouterai une icône personnalisant ce site, je l’indiquerai proprement dans mes pages.

Ne validez pas cette pratique stupide initiée par IE et que Mozilla s’est bêtement senti obligé de suivre en laissant cette option active, mes logs et ma bande passante vous remercieront et ceux de beaucoup d’autres serveurs aussi (bon, en fait, c’est plus une question de principe que du gâchis de ressource).

Note : Opera et la règle-at @charset

Je viens d’être confronté à ce qui semble être un bug d’Opera (version 8.01). Je l’avais déjà précédemment rencontré (je ne retrouve pas où j’ai pu en parler J’en faisais mention dans ce commentaire) mais je n’avais pas poussé alors mes investigations. Le problème survient lors de l’utilisation de la règle-at @charset :


@charset "UTF-8"; /* Notez le saut de ligne qui précède la règle-at */
html { background-color: green; }

Résultat obtenu : L’arrière-plan reste blanc. J’ai obtenu deux cas de figure "corrigeant" le problème :

@charset "UTF-8"; /* Pas de saut de ligne avant la règle-at, le fichier commence directement par @charset… */
html { background-color: green; }

@import url("404.css");
@charset "UTF-8";

html { background-color: green; }

Bizzare non ? Cependant, ce bug ne semble affecter que les versions Windows et Linux d’Opera 8

Safari et arrière-plans multiples

L’information n’a pas fait grand bruit bien qu’elle soit d’importance : Safari supporte les arrière-plans multiples, dont la syntaxe (que je trouve toujours aussi peu intuitive) est définie dans le module CSS3 Backgrounds and Borders. Exemple d’utilisation.

Safari supporte maintenant également les propriétés border-image, background-clip, background-origin et border-radius. Des liens vers les impressions d’écran sont disponibles dans les commentaires de l’annonce sur le blog Surfin’ Safari.

Bugs en série

Continuant de travailler sur la nouvelle version à venir de webnaute.net (Beaucoup de travail a été fait mais il reste encore quelques parties à faire et d’autres à terminer), j’ai été confronté au niveau du redesign à un certain nombre de bugs de différents navigateurs. À tel point que j’ai décidé d’en faire la liste ici pour vous en faire profiter un peu (En noir et blanc, les impressions d’écran, je veux pas vous gâcher la surprise ^^).

Styles CSS des select et :focus

Le bug ne se produit que sur Gecko/Linux (grrr…) lorsqu’on applique certains (n’importe quel ?) styles CSS à un élément select lorsque celui-ci gagne l’attention (focus). Dans le cas présent, j’appliquais un changement de couleur et de style de la bordure du select (non fonctionnel sur Firefox 1.0 mais ok sur Deerpark). Résultat, il est nécessaire de cliquer trois fois sur le select pour que Gecko daigne enfin dérouler la liste des options.

Pour contrer le bug, et comme je ne souhaite pas pénaliser les autres navigateurs supportant ces effets (et notamment Deerpark sur Windows), j’ai opté pour la solution DOM, avec une petite routine qui supprime la règle CSS en cause si le navigateur utilise Gecko (détection de fonctions spécifiques à ce moteur) et que l’OS est Linux (détection via navigator.platform, pas moyen de faire autrement).

[Bug 149981] : must click three times on <select> form controls before dropdown appears when pref browser.display.focus_ring_on_anything is enabled

Génération de contenu et saut de ligne

#id span::after { content: "\A"; }

Cette règle CSS fonctionne parfaitement sur Opera mais pas avec Gecko. Pour une raison qui demeure pour moi mystérieuse, la règle CSS ne fonctionne sur Gecko que si on y ajoute la déclaration white-space: pre; (à défaut d’utiliser pre-line qui n’est pas supporté non plus par Gecko).

"\A" in generated content does not break lines (marqué comme étant INVALID)

La définition de la propriété white-space dans CSS 2.1 indique en effet que les valeurs pre, pre-wrap et pre-line doivent permettre les sauts de ligne dans la mise en page en présence de sauts de ligne dans le code source mais aussi de sauts de ligne dans le contenu généré par CSS.

Par opposition, cela signifierait effectivement que si white-space a la valeur normal (valeur par défaut) ou la valeur nowrap, les sauts de ligne dans le contenu généré (tout comme ceux présents dans le code source) doivent être normalisés (fusion des séquences de caractères blancs en une unique espace).

Styles CSS de tableau

Imaginez le tableau (désolé, j’ai pas résisté) : Une déclaration border: 1px solid une_couleur; sur l’élément table ainsi que sur les th, et les td parés d’un attribut scope="row". Puis une déclaration border: 1px dashed une_couleur; sur les éléments td. J’utilise également la pseudo-classe :empty (CSS3) pour styler les cellules vides (celle en haut à gauche sur les impressions d’écran suivante).

Le résultat sur Firefox 1.0 (idem sur Deerpark) :
Les bordures des td de base ne sont pas 
			en dashed mais en solid

On y est presque mais mes cellules du centre n’ont pas de bordures sous forme de trait discontinu mais en trait solide. Un autre bug lié au table est le fait que les marges externes des tableaux ne fusionnent pas dans Firefox, pour les autres navigateurs (sauf Opera), je ne sais pas ce qu’il en est.

Le résultat sur Opera 8 :
Il manque le stylage de la cellule vide

Presque parfait également, il manque juste le support de la pseudo-classe :empty.

Le résultat sur Safari 2.0 :
Parfait

Le rendu est exactement celui attendu (le bug sur le contenu généré, "»", sera traité dans le prochain billet).

Un grand merci à J.J Solari pour les impressions d’écran.

min-width, position en absolu et Firefox

J’applique une déclaration min-width sur un élément en position absolue et dont le contenu en-ligne est stylé d’une manière assez précise et ne doit pas revenir à la ligne. Firefox applique bien le min-width sur le bloc, mais le contenu du bloc revient à la ligne pour ne pas déborder de la fenêtre (alors que le min-width est justement ajouté dans l’optique de permettre cela). Le bug peut être contourné en ajoutant également une déclaration white-space: nowrap; pour éviter que le contenu du bloc ne revienne à la ligne. Ce bug est corrigé dans Deerpark. Voir le bug.

Allez, ce sera suffisant pour ce soir, je vous garde le plus gros pour le prochain billet tellement c’est rocambolesque.

Bugs en série - suite

Continuant mon voyage fantastique au pays des bugs, je m’en vais maintenant vous relater comment je me suis trouvé aux prises avec deux bugs CSS teigneux, l’un affectant Safari, l’autre, beaucoup plus vicieux, continue de me résister et affecte selon les cas au moins Opera et Firefox.

Safari et styles de sélection de texte

J’applique les styles suivants sur tous les éléments de la page et, notamment, sur des paragraphes dont le contenu est justifié (text-align: justify;) :

*::selection { background-color: une_couleur; color: autre_couleur; }
*::-moz-selection { background-color: une_couleur; color: autre_couleur; }

Résultat sur Safari 2.0 (cliquez sur les images pour les voir grandeur réelle) :
Lorsque l’utilisateur sélectionne du texte, celui-ci part en sucette
Lorsque l’utilisateur sélectionne du texte, celui-ci part en sucette

Safari a manifestement quelques problèmes pour gérer et la justification de texte et les styles CSS sur la sélection de celui-ci.

J’ai d’abord fait quelques recherches sur l’existence éventuelle d’un pseudo-élément ::-khtml-selection, ce qui m’aurait permis d’annuler ces styles de sélection uniquement pour les navigateurs basés sur KHTML (pour peu que les mots-clés CSS nécessaires fussent gérés aussi par KHTML) :

*::selection { background-color: une_couleur; color: autre_couleur; }
*::-moz-selection { background-color: une_couleur; color: autre_couleur; }
*::-khtml-selection { background-color: Highlight; color: HighlightText; }

Mais ce pseudo-élément n’existe apparamment pas. Étant donné que je me posais déjà la question de savoir si la justification de texte était adaptée pour un rendu à l’écran, ce bug n’a fait que me pousser à prendre la décision de retourner au plus raisonnable text-align: left;.

Feuilles de styles et encodage

Tout est parti d’un bug de Safari lié à la génération de contenu. Voici la règle CSS en cause (vous pouvez en voir le résultat dans Firefox, Opera et Safari dans le billet précédent) :

table td[scope="row"]::after { content: "\00A0»"; }

Safari affiche donc » au lieu d’afficher  » (le guillemet fermant est précédé d’une espace insécable). J’ai d’abord simplement pensé sans réfléchir que Safari ignore simplement le paramètre charset de l’en-tête HTTP Content-Type et utilise le jeu de caractère ISO-8859-1 pour les feuilles de styles. En fait, ça semble être un plus tordu.

Mon hypothèse est la suivante : Safari ignore effectivement le paramètre charset de l’en-tête HTTP (premier bug) et utilise donc le jeu de caractère ISO-8859-1, mais fait une autre boulette en résolvant les appels de caractères (ici, \00A0) avant de convertir la feuille de style dans le même encodage (ici, l’UTF-8) que celui de la page liant la feuille de style. Résultat, l’espace insécable se retrouve encodée deux fois de suite en UTF-8. Le test suivant semble confirmer mon hypothèse puisque j’obtiens alors ce qu’affiche Safari (sauf l’espace, apparamment supprimé par Safari) :

<?php
header('Content-Type: text/plain; charset=UTF-8');

echo utf8_encode("\xC2\xA0");// \xC2\xA0 est l’espace insécable encodée en UTF-8 Le résultat affiché est  suivi d’une espace
?>

Bon, mon raisonnement est débile. Si Safari utilisait ISO-8859-1 pour la feuille de style, le guillemet fermant s’afficherait aussi de façon foireuse. Donc forcément, Safari utilise bien l’UTF-8 pour la feuille de style

Les appels de caractères (\00A0 en tout cas) sont donc résolus et le caractère résultant encodé dans le charset de la feuille de style. Ça semble être plus logique comme explication.

L’enfer des règles-at

Pensant d’abord pouvoir régler son compte au bug d’encodage avec la règle-at @charset (c’était avant d’en arriver à l’hypothèse du paragraphe précédent), et malgré le bug d’Opera et de la règle-at @charset que j’allais devoir lui aussi tenter de contourner, je décide d’ajouter des @charset "UTF-8"; (Rappel pour ceux qui n’ont pas vu ; Opera Mac ne semble pas affecter par le bug de la règle @charset, seules les versions Windows et Linux le sont). Par exemple, là :


@charset "UTF-8";
@import url("/une_feuille");
@import url("/une_autre");

html { font-size: .9em; }

Cela ne fait ni chaud ni froid à Safari (le bug du contenu généré demeure). Comme prévu, Opera perd la boule et ignore toutes les règles-at qui suivent immédiatement (ici, les deux @import) ainsi que la règle CSS suivante (ici, html { font-size: .9em; }). Quant à Firefox, les tests que j’avais fait à une certaine époque m’avaient fait constater qu’il ne gérait pas lui non plus la règle @charset, cependant, il a le bon goût de tenir compte de ce que je lui dis dans les en-têtes HTTP, il n’était donc pas concerné par ces tests. Et pourtant, j’ai la surprise de constater qu’il zappe lui aussi purement et simplement les deux règles @import. Gasp…

Après pas mal d’essais infructueux, un éclair de lucidité me pousse à retourner lire la recommandation CSS, dont la traduction n’était d’ailleurs pas accessible à ce moment-là. Heureusement, j’en ai une copie complète sur mon disque dur ;¬). Bref, je suis tombé là-dessus :

Il ne peut y avoir qu'une règle @charset dans une feuille de style externe et elle doit survenir au tout début de celle-ci, aucun caractère ne devant précéder. Cette règle ne doit pas apparaître dans une feuille de style incorporée.

Ah, forcément, fallait le savoir. Je comprends mal les raisons de cette limitation. Cela veut dire que toutes les feuilles de styles importées ont l’obligation d’être dans le même jeu de caractère que la feuille de styles principale. Et puis il y a un autre problème du coup :

La règle @import permet aux utilisateurs l’importation de règles de style à partir d’une autre feuille de style. Les règles @import doivent précéder toutes autres règles dans la feuille de style.

Ah ouais… Comment que je fais moi ? Bon, heureusement, CSS 2.1 vient éclaircir les choses comme toujours :

CSS 2.1 user agents must ignore any @import rule that occurs inside a block or after any valid rule other than an @charset or an @import rule.

Bon, je passe sur les essais avec @namespace pour contourner le bug d’Opera (que de toute façon, c’est pas valide puisque @charset doit être en premier) et les heures à tester/modifier/retester sinon, ce billet risque d’être déraisonnablement long. Encore une fois, merci à J.J Solari pour ses tests du design sur les navigateurs Mac et les impressions d’écran fournies. Il va finir par devenir mon testeur mac attitré si ça continue ;¬)

Tiens, un bug de plus :

label { float: left; width: 15em; }/* La présence du width n’est pas significative */
label { float: none; }

La mise en flottant passe automatiquement la boîte en type bloc (comme si on mettait explicitement display: block; (jusque là, tout est normal). Avec la règle suivante, on enlève le caractère flottant de la boîte. La boîte reste de type bloc sur Firefox 1.0 (Deerpark n’est pas affecté par ce bug).

Nouvelle structure en place

Et voilà, la nouvelle structure du blog est en place. Extérieurement, vous ne constaterez pas de grands changements au niveau fonctionnalité, par contre, sous le capot, ça a bien évolué. Les données restent désormais en UTF-8 d’un bout à l’autre de la chaîne de traitement (MySQL 4.0.x derrière, mais la version 4.1.x devrait être installée dans le courant de l’automne). Le code est également plus propre et plus lisible à mon goût (c’est à dire jamais assez). Mais parlons plutôt de ce qui est le plus visible pour vous :

Nouveau design

Évidemment, c’est le changement le plus flagrant. L’inspiration a mis du temps à me venir et le résultat n’est bien sùr pas du niveau des œuvres de Dave Shea. L’association des couleurs me semble toutefois correcte et l’ensemble agréable à l’œil. Tout commentaire ou critique est bien entendu le bienvenu :¬)

Pour les personnes utilisant Firefox ou un autre navigateur basé sur un Gecko relativement récent, si les choix de couleurs de la sélection de texte ne vous satisfont pas ou vous gènent, vous pouvez annuler ces styles avec le bloc CSS suivant dans votre feuille utilisateur userContent.css (testé avec succés) :

@-moz-document url-prefix(http://blog.webnaute.net/)
{
	*::-moz-selection { background-color: Highlight; color: HighlightText; }
}

Pour les nostalgiques où ceux qui n’aiment pas le nouveau design, le précédent design est toujours disponible dans le sélecteur de style et porte maintenant le nom Bleu hivernal (il a quand même dù subir quelques adaptations).

Changement d’adresse

Autre changement d’importance, le passage du blog de l’adresse http://webnaute.net/Journal/ à http://blog.webnaute.net/. En effet, le blog suivant désormais son propre chemin au niveau du design vis à vis du reste du site, et constituant un sous-ensemble particulier du site, j’ai jugé que ce changement d’adresse s’imposait pour bien refléter cet aspect.

Bien entendu, toutes les dispositions ont été prises pour que les liens ne soient pas cassés (mise en place de redirections HTTP). J’ai fait le test avec Liferea, la redirection est bien suivie et l’adresse du fil RSS mise à jour automatiquement. N’hésitez pas à vérifier que votre propre aggrégateur, si vous en utilisez un, a fait de même.

L’erreur étant humaine, il est tout à fait possible, malgré les vérifications que j’ai faites, que des liens soient cassés. N’hésitez pas dans ce cas à me faire part de cette erreur.

Système de rétroliens

Webnaute dispose désormais de son système de rétroliens (de son appellation d’origine, Trackback, mais j’aime bien la version francisée). Je vous renvoie vers cette page du petit dotclear illustré pour des explications pratiques.

J’ai d’ailleurs un billet en réserve concernant dotclear et sa gestion des trackback, ayant dù me résoudre à certaines adaptations pour être compatible avec 98 % de la blogosphère francophone.

Pages d’erreur 404 moins obscures

Ceci ne s’applique que lors de l’appel d’une URL de la forme /YYYY/MM/DD/Billet-name/ renvoyant une erreur HTTP 404 Not Found. Le moteur du blog recherche alors les billets ayant un nom proche de celui demandé et les propose en tant que possibilités.

Ça devrait être pratique dans le cas d’une faute de frappe dans l’URL (par l’internaute ou par une personne ayant fait un lien vers un billet depuis une page externe).

Un "bug" de certains agents utilisateurs devrait être également esquivé grâce à ce système. En effet, il arrive qu’un UA, suivant une URL contenant des caractères non-ascii non urlencodés sous la forme %XX, encode la-dite URL sous une forme un peu bizzare (exemple : /Journal/2005/06/19/En_vrac_jeux_de_caract\xc3\xa8res/).

Cependant, je ne suis pas sùr du tout que les URLs contenant des caractères non-ascii soient autorisées dans les pages (X)HTML. La recommandation HTML indique que de tels URLs sont illégales, cependant, la notion d’IRI a depuis fait son apparition (Oups, mais je viens de voir que c’est méchamment récent, janvier 2005; Bobe trop en avance sur son temps ?). Bref, cela fait partie des billets en cours de réflexion.

Autres changements

Un système anti-spam de commentaires/trackback très sommaire et basé sur l’IP a été mis en place. Jusqu’à maintenant, je n’ai pas eu à me plaindre de telles pratiques à l’encontre de webnaute.net mais mieux vaut prévenir que guérir.

Pour les personnes utilisant des navigateurs gérant les liens relationnels (avec <link>), deux nouveau liens relationnels sont maintenant présents dans les pages de billet et menant aux billets précédents et suivants.

Le fil RSS a été légèrement remanié pour utiliser les modules Creative Commons et Content (contenu des billets en entier avec content:encoded). De plus, deux nouvelles URLs sont disponibles :

Je constate d’ailleurs à l’instant que les deux nouveaux modules utilisés semblent spécifiques à RSS 1.0. Bon tant pis, je verrai ça plus tard…

Et en vrac : un seul cookie (+ un autre éventuel pour le style css choisi) au lieu d’une rafale (moi qui râle après les sites qui font ça, c’était un comble); favicon.ico vide à la racine pour éviter les erreurs 404 et l’envoi d’octets superflus (page d’erreur 404).

Dans les cartons

Il me reste encore quelques ajouts à faire ultérieurement :

  • Mécanisme pour mettre en avant les derniers billets actifs au niveau des commentaires
  • Possibilités de mise en forme pour les commentaires (syntaxe wiki, HTML ou autre). Ce n’est toujours pas fait :¬(
  • L’utilitaire d’aide à la composition des billets et commentaires (pour insérer des caractères rarement utilisés/difficiles d’accés au clavier) dont je parlais il y a quelques temps
  • Mécanisme pour pouvoir suivre l’ajout de commentaires sur un billet sans devoir systématiquement passer sur le site
  • Pour mon admin, le module me permettant de dialoguer avec les système de trackback des autres blogs (je l’avais complètement zappé)

Voilà, j’espère que toutes ces nouveautés vous plaisent autant qu’à moi. Je tiens à remercier une nouvelle fois J.J Solari pour son aide précieuse pour les tests du design sur les navigateurs Mac ainsi que pour ses conseils, ainsi que toutes les personnes m’ayant donné leurs avis ou critiques sur ce nouveau design.

Pour les curieux, deux impressions d’écran de ma très sommaire interface d’administration :

Dotclear, rétroliens et UTF-8

Comme indiqué dans mon précédent billet, j’ai implémenté un système de rétroliens sur mon blog, suivant les informations données dans la spécification existante et regardant le code source de Dotclear pour bien comprendre le fonctionnement de ce mécanisme.

Justement, il y a un petit problème avec Dotclear. Lorsqu’un blog dotclear réglé pour utiliser l’UTF-8 pingue l’URL qui va bien, il commence d’abord par envoyer une requète HTTP avec le paramètre __info et s’attend à recevoir une réponse sous forme d’XML et précisant l’encodage acceptable par le blog récepteur.

Le problème est que si le blog récepteur ignore la requète avec le paramètre __info (ou répond qu’il veut du latin1), Dotclear passe les données à envoyer dans la fonction PHP utf8_decode(), or cette fonction est destructrice. Si un caractère présent dans les données n’a pas de code assigné dans le jeu de caractère latin1, il est purement et simplement remplacé par un point d’interrogation. Il y a donc perte de données.

Dotclear n’est pas vraiment en cause, c’est le mécanisme de rétroliens qui n’a pas été pensé à la base pour tenir compte des problèmatiques d’encodage (latin1 ou pire, us-ascii, sinon rien). Néanmoins, il y a ici une perte de données et ce n’est jamais une solution acceptable.

Une solution serait donc de transformer les caractères non présents dans le jeu latin1 en en entités XML avant de passer les données dans la fonction utf8_decode(). Ce n’est pas très propre étant donné que c’est du texte brut urlencodé qui est envoyé et non du XML, c’est néanmoins cette solution qui a été retenue par la plupart des navigateurs pour gérer cette même problèmatique avec les formulaires HTML.

J’ai soumis cette suggestion sur le forum de Dotclear (sans réponse de l’équipe de développement au moment où je rédige ce billet). Au début, j’étais assez réticent quant à l’obligation pour moi d’implémenter le mécanisme du paramètre __info, mais après mùre réflexion, c’est probablement la moins mauvaise solution.

L’autre grief que j’ai à l’encontre de Dotclear est qu’il nécessite la présence du paramètre utf8=1 à la réception d’un ping, sans quoi, les données sont considérées comme du latin1 et, si le blog récepteur utilise l’UTF-8, passées dans la fonction utf8_encode() (donc affichage dégueulasse sur le blog récepteur). Là, l’alternative existe clairement et se trouve dans le protocole HTTP. Elle est d’ailleurs également indiquée dans la spécification sur les rétroliens :

POST http://www.example.com/trackback/5
Content-Type: application/x-www-form-urlencoded; charset=utf-8

title=Foo+Bar&url=http://www.bar.com/&excerpt=My+Excerpt&blog_name=Foo

Les prochaines versions semblent se tourner vers la détection de l’UTF-8 pour le traitement des données reçues, mais toujours pas de prise en compte du paramètre charset.

Pour ma part, je me restreindrai pour l’instant à ne pinguer que les blogs Dotclear en UTF-8. Pour les blogs en latin1, il me faudrait passer mes données en latin1 avant envoi, ce qui signifierait une perte de données (donc là, pareil, affichage dégueulasse sur le blog en face puisque certains caractères seront remplacés par un point d’interrogation).