Overblog Suivre ce blog
Editer l'article Administration Créer mon blog
2 octobre 2006 1 02 /10 /octobre /2006 13:16

détail du 'Dragon' de Max Escher

Deuxième mouture d'un article tout à fait sérieux, qui a rencontré un vif insuccès. Cette version-ci est un peu plus courte et, je l'espère, moins hallucinante que la première.

En résolvant un problème réellement rencontré, j'essaierai d'aller au-delà de la magie noire et d'expliquer ce que j'ai compris à cette occasion. Ce n'est pas un cours magistral ni une initiation au CSS, plutôt une étude de cas. Mieux vaut avoir déjà un peu tripoté la présentation de son blog pour y comprendre quelque chose.

Dernière précision : le problème ne se pose plus en version 2. Mais la discussion peut vous intéresser tout de même.


1 - Le problème

Pour repeindre ce blog, j'avais d'abord cru qu'une image de fond serait une bonne idée. Erreur : ce motif de livres est plus bigarré qu'il y paraît, aucune couleur de texte n'arrive à ressortir agréablement sur toute la page. Pas assez malin pour penser à faire pâlir cette image ou en réduire la gamme de couleurs, j'ai alors choisi d'isoler les divers éléments dans autant de pavés à fond uni.

C'est plus fastidieux que vraiment difficile, il faut repérer dans le CSS les classes et les id des divers composants du blog – principalement .box et .article – et jouer sur les couleurs de fond : .article {background-color:rose-pétaradant} , par exemple. La manoeuvre est expliquée un peu partout.

Tout content de voir le bébé prendre tournure, j'ai regardé de plus près la nouvelle tête de mes bôôôôs articles et, en bas, ça ressemblait à ça :

alors que je m'attendais plutôt à ça :

2 - Solution à l'aveuglette

Pas mal pour une première tentative, mais pourquoi le cadre de l'article coupe-t-il la dernière ligne de liens ? Normalement, elle devrait rentrer dans le cadre. Boh, pas grave, il suffit de tripatouiller des 'margin' et des 'padding' bien choisis pour s'en sortir. Et c'est vrai, après quelques tâtonnements, on s'en sort avec, par exemple : .article {padding-bottom:AssezGrandpx}

3 - J'aime pas les bidouilles

Ben alors, l'article est fini ?

Non… Non parce que :

  1. le problème et sa solution venaient contredire ma toute fraîche science des CSS. Vexant !
  2. j'aime pas quand ça marche sans (avoir l'impression de) comprendre ce qui se passe : ma foi naïve me dit que ça peut de même planter sans que je comprenne davantage ;
  3. illustration immédiate : le remplissage ('padding') ainsi rajouté s'est tout de suite traduit par un espace assez vilain dans les cas où l'article apparaît sans la liste de liens, par exemple quand on affiche ses commentaires.

4 - Si vous êtes pressé…

La solution est ici mais vous allez manquer quelque chose.

5 - Le roman

Ce qui s'affiche à l'écran, c'est le texte HTML mis en forme selon les indications du CSS – ceci n'est pas une idée neuve. Pour espérer comprendre quelque chose, il faut donc jeter un coup d'œil au source HTML et pas seulement au CSS.

5.1 - Examen du lieu du crime

Voici le code HTML de la zone concernée (on l'obtient en faisant  afficher le code source d'une page). Les div qui composent l'article sont mis en évidence, le reste du texte est entre crochets, j'ai hiérarchisé la présentation et ajouté quelques commentaires :

 <div class="article"[...]> <div class="barreHautArticle">[...]</div> <!-- la ligne de date --> <div class="divTitreArticle">[...]</div> <!-- la ligne de titre --> <div class="contenuArticle"> <!-- corps de l'article --> [...] <!-- le texte lui-même --> <div class="clear"></div> <!-- ajouté automatiquement par OB --> </div> <!-- fin de contenuArticle --> <div class="Option"> <!-- début des deux lignes de 'signature' --> <div class="optionInfo"> <!-- optionInfo : auteur et catégorie --> [...] </div> <!-- fin de optionInfo--> <div class="optionLink"> <!-- optionLink : quatre liens --> [...] <!-- quatre 'span' : un par un lien --> </div> <!-- fin optionLink--> </div> <!-- fin Option--> </div> <!-- fin du div article --> 

La structure d'un article ressort nettement : le  pavé  d'ensemble est le div de classe article , découpé en plusieurs div pour les blocs successifs. Dans l'ordre : la ligne de date, celle de titre, le corps de l'article et enfin les deux  brochettes  de liens, optionInfo et optionLink. Ces deux  brochettes  sont regroupées dans le div de classe Option.

Simple et limpide : les deux lignes font bien partie du div de classe article et devraient rentrer dans le cadre dessiné autour de lui.

Or l'une rentre et pas l'autre : mystère. Ce n'est pas une question de navigateur, quelques essais le prouvent (et puis l'excuse est trop facile). Puisqu'il n'y a rien de particulier dans le HTML, regardons ce qu'il y a dans le CSS à propos de 'Option' et toute sa famille.

5.2 - Vous avez dit CSS ? Oui, mais lequel ?

J'aurais bien voulu vous montrer un échantillon convaincant, mais le fichier CSS, au moins celui du modèle 101 dont j'étais parti, ne dit que ça :

 .Option { padding:5px 0px 0px 0px; margin:5px 0px 5px 0px; border-top:1px dotted #808080; width:100%; text-align:right; font-size:85%;} 

RIEN de particulier sur optionInfo ni optionLink.

Doliprane. Tour du pâté de maisons. Grande méditation.

Avant de crier au bug, cherchons encore. Si ce n'est pas dans mon fichier CSS, où est-ce ?

Il y a trois emplacements possibles pour des indications de style :

  1. à même la balise HTML concernée, en lui donnant un attribut style="padding-bottom:5px;" par exemple. Rien de tel dans notre fichier HTML.
  2. dans une feuille de style incluse dans le head du fichier HTML. Rien de tel non plus ici.
  3. dans un fichier externe, la  feuille de style  proprement dite, que l'on (on = OverBlog) déclare aussi dans l'en-tête du fichier HTML.

TILT !

Que dit l'en-tête du fichier HTML ? Voilà le morceau qui nous intéresse, les lignes où il est question de stylesheet (texte superflu mis entre crochets) :

 <link rel="stylesheet" type="text/css" href="[...]common.css" /> <link rel="stylesheet" type="text/css" href="[...]custom.css" /> 

Ce que vous lisez signifie que le navigateur analyse d'abord le fichier nommé common.css PUIS le fichier custom.css (celui que nous charcutons avec tant d'appréhension). Vous avez peut-être remarqué que la première ligne de ce fichier custom.cssressemble à

 @import url("/css/commonstruct1.css"); /*ne pas enlever cette ligne qui permet l'evolution des css personnalisés*/ 

Commonstruct1.css (le dernier chiffre n'est pas toujours 1, il dépend du design choisi pour le blog) est aussi une feuille de style. Le jeu complet des fichiers CSS fournis au navigateur est donc, en définitive et dans l'ordre où le navigateur les lit :

  1. common.css – création d'OverBlog que vous ne pouvez pas modifier (manquerait plus que ça !)
  2. commonstructX.css – même remarque
  3. custom.css – le vôtre.

C'est parce que votre fichier custom.css vient en dernier que son contenu prévaut sur celui des deux autres en cas de conflit. Mais là, il ne peut pas y avoir de conflit puisque custom.css ne dit rien sur optionLink. Il faut donc regarder les deux premiers fichiers pour espérer comprendre ce qui se passe.

Dans commonstructX, pas grand-chose et de toute façon rien qui concerne nos  brochettes  optionInfo et optionLink.

Mais common.css… Ahhhhhhh, common.css… On y découvre ces lignes :

 .Option,.article {clear:both;} .Option {margin-bottom:15px;} .optionLink{float:right;} .spanliencom,.spanlientrack,.spanlienrecom,.spanaddcomment{float:left;} 

Notons tout de suite que l'indication de margin-bottom (2ème ligne) n'a aucun effet puisque la règle trouvée dans custom.css redéfinit au passage toutes les marges de Option : application directe de ce que nous disions à propos de la résolution de conflits.

Mais venons à l'essentiel : qu'est-ce que tous ces float font ici ? Maîtrisons le tremblement fébrile qui agite nos mains nerveuses et, avant de nous précipiter pour tenter une correction hasardeuse, essayons de comprendre ce qui se passe.

5.3 - Flotte, petit div, flotte joyeusement…

Un float, c'est quoi ? Un clear, c'est quoi ? Allez, un petit rappel de cours, très succinct et sans y passer la nuit.

Le cas normal, d'abord. Pour remplir un div ou un p, un h1, un h2… (tout ce que la spécification CSS2 appelle un  block box ) le navigateur procède ainsi :

  • il reçoit tout ce qui vient après la balise de début du  block box , texte et images, et le dispose soigneusement de gauche à droite ;
  • quand il atteint la largeur du  block box  (d'où la sort-il ? c'est une autre histoire) il passe à la ligne suivante et recommence ;
  • quand il arrive à la balise de fin du  block box , il emballe tout ça d'une couche de padding sur les quatre côtés, puis d'une couche de border. Le background est alors appliqué – quand la bordure est discontinue, on voit ce fond au travers des trous. Le navigateur rajoute enfin une couche de margin toujours sur les quatre côtés ;
  • si l'on n'a pas imposé de hauteur au  block box  avec un height, le box est rendu juste assez grand pour tout contenir. Sinon, le débordement éventuel est coupé, ou affiché, ou encore visible avec des barres de scroll – on peut choisir (propriété overflow). Quoi qu'il en soit, le navigateur range le tout proprement dans l'écran…
  • … puis il passe à la ligne suivante et attaque le prochain  block box . Bien.

Bien, mais les float ? Voilà : un élément (image, fragment de texte…) doté de la propriété float : left ou float : right devient ipso facto un "block box" à lui tout seul, avec tout son capitonnage de padding, border et margin, et file de l'endroit où il aurait dû normalement s'afficher jusqu'au bord gauche ou droit de son  conteneur  , à moins qu'il ne vienne buter contre un autre float déjà présent. Le texte  normal  qui suit le float, lui, est réarrangé pour contourner les float qui se trouvent à l'un ou l'autre bout de la ligne. Vous avez un exemple simple avec l'image du dragon au début de cet article.

Du même souffle, explication du clear : un machin muni de l'attribut clear ( clear:right, clear:left ou clear:both ) refusera vertueusement de se trouver à côté d'un float (de gauche, de droite ou de n'importe où) et exigera de commencer sur une ligne neuve, pas  encombrée . Toujours dans cet article, la barre horizontale qui suit le premier paragraphe est dotée de l'attribut clear:both sans lequel elle se trouverait juste après ce premier paragraphe, et donc partiellement recouverte par le dragon.

5.4 - Retour sur terre

Tout cela est fort instructif, mais où est le rapport avec nos  brochettes  ? On y vient. La vacherie, c'est qu'un élément  flotté  n'est plus pris en compte dans le calcul des dimensions de son conteneur.

Par exemple, imaginons un div contenant quelques mots et une image de 100 pixels de haut. Ce div sera haut d'au moins 100 pixels pour contenir l'image. Mais si l'image est flottée, le div n'aura que la hauteur nécessaire aux quelques mots, même en tenant compte de la nécessité pour eux de contourner l'image. Autrement dit, le bas de l'image pourra déborder du div et même empiéter sur le haut du  block box  suivant… – sauf si celui-ci est muni d'un attribut clear.

Ceci nous explique la première règle .Option,.article {clear:both;} trouvée dans common.css : elle nous met à l'abri des éventuelles mauvaises surprises que causerait un iceberg situé plus haut, et nous assure que Option et article commenceront sur une nouvelle ligne rien que pour eux.

Nous avons déjà parlé de la règle sur le margin, passons aux suivantes : optionLink est déporté à droite et, à l'intérieur d'optionLink, les morceaux de la  brochette  sont tous disposés de gauche à droite. Quelle utilité ? Je ne sais pas. Ce que je vois très bien, en revanche, c'est qu'ainsi optionLink n'entre plus en compte dans le calcul de la hauteur de son conteneur, à savoir Option. Celui-ci n'a plus à prendre en compte que la seule ligne optionInfo. Du coup, la hauteur de article est elle aussi calculée sans tenir compte non plus d'optionLink – et voilà comment la bordure de l'article se trouve dessinée au beau milieu d'une liste de liens

5.5 - Correctif

Il faut évidemment annuler les float. Comme il n'est pas possible de modifier common.css , c'est dans custom.css (= "notre" fichier CSS) qu'on ajoutera la ligne suivante :

 .optionLink,.spanliencom,.spanlientrack,.spanlienrecom,.spanaddcomment {float:none;} 
qui vient contredire les indications de common.css. Et comme elle est placée après common.css c'est elle qui l'emporte.

À quel endroit l'écrire ? Deux choix possibles :

  • ou bien à la fin du CSS si l'on veut y regrouper toutes ses modifications pour laisser inchangé le texte d'origine (à conseiller si vous n'êtes pas très sûr de vous)
  • ou bien dans la section consacrée aux articles si l'on préfère garder ensemble ce qui va ensemble, pour conserver la cohérence du fichier en prévision de modifications futures. C'est ce que j'ai choisi : c'est un choix d'organisation, pas un choix technique. Pour le dire autrement : ça ne marche ni mieux ni moins bien, mais je crois que ça m'évitera de futures erreurs.

6 - Moralité(s) possible(s)

  1. Il y a une explication à tout, et on peut la trouver soi-même.
  2. Pour comprendre, une fois pour toutes, ce que signifient toutes ces classes et identifiants, autant regarder le HTML du blog un bon coup.
  3. Quand une règle CSS semble n'agir avec aucun navigateur, c'est qu'une autre la bloque. Reste à trouver laquelle.

 Ils se marièrent, ils eurent beaucoup d'enfants et ils furent heureux malgré tout.  - - - - - - Zut, ça c'était pour le prochain article.

Avez-vous lu le tutoriel du Site du Zéro ? Pas encore ? Foncez !

Avez-vous au moins survolé la vf de la spécification CSS2 ? Ne vous laissez pas intimider et consacrez-y un moment.

Avez-vous parcouru la vf de la spécification HTML 4.01 ? Ça vaut le détour.

commentaires

Julie 11/07/2007 20:25

Je note, je note ;)

Julie 11/07/2007 17:17

C'est marrant, je suis exactement comme Annak, je marche plus à l'instinct que je fais mes programmations. Mais du coup, j'aime bien tomber sur des articles comme ça, parce que j'apprends en meme temps. Et les bases s'accumulent ;)Comme pour le lien "lir la suite", cet article est sacrément bien expliqué. Tout parait clair comme de l'eau de roche.Merki ;)

Aïe mes doigts ! 11/07/2007 17:36

Merci du compliment, ces articles sont faits exactement pour ça : exposer les bases en démontant un problème concret.Note que cet article ne concerne pas la v2 (non encore sortie à l'époque)

Annak 05/10/2006 12:35

Salut :)
J'ai reçu ton mail. Merci :) Très très clair. Tu permets que je te cite et le rajoute à la suite de l'article sur "Changer la taille des titres des modules" ? C'est facile à comprendre et à travers un cas concret comme cela, je crois que ça fait un déclic dans la compréhension du CSS.
 

Malgré tout 05/10/2006 12:49

Volontiers. Au passage,  j'ai improprement nommé "spécificateur" ce qui est en fait un "sélecteur" - si tu pouvais corriger ? Et j'ai vu que ta brochette est sortie de l'eau ! ;)

Annak 04/10/2006 16:46

Bonjour :)
Oui, c\\\'est plus facile à comprendre. La majorité des lecteurs, qui vont venir chez toi, n\\\'y connait rien ou à peu près en informatique. Il faut leur simplifier la tâche. D\\\'autant plus actuellement où on zappe pas mal...
Je dois donc rajouter à mon CSS :
.optionLink,.spanliencom,.spanlientrack,.spanlienrecom,.spanaddcomment {float:none;}
J\\\'avais compris qu\\\'entre {}, on pouvait mettre différentes informations (oui, j\\\'ai fait des études 8| ). Mais l\\\'inverse est possible aussi ?
Une seule paire de {} peut concerner plusieurs "lieux" ? je pourrais par exemple poser .article, .box {text-align:center;} et le texte des articles et modules serait centré ?
Sinon, j\\\'ai constaté qu\\\'en faisant :
.box h2 {font-size:120%;} rien ne se passait. Quand j\\\'attendais que la taille du titre des modules augmente. J\\\'en ai déduit qu\\\'ailleurs dans le CSS, une information contrariait cet ordre. Tu en penses quoi ? Ou bien ai-je mal fait quelque chose ?
Bonne soirée :)

Malgré tout 04/10/2006 20:19

Que de choses en une seule livraison !  Et on me trouve prolixe ;-)Dans l'ordre de ton commentaire:1-rajout à ton CSS : oui, c'est exactement ça.2-une seule paire d'accolades pour plusieurs "lieux" : oui, c'est exactement ça - tu as fait de très bonnes études ! ;-)3-.box h2 : ça devrait être exactement ça ! rien à reprocher à ce que tu écris.  Mais en effet, s'il y a une autre règle .box h2 APRES celle-ci dans ton CSS, et que cette autre règle définit elle aussi font-size, c'est cette dernière qui prévaudra.C'est pourquoi on conseille, dans le doute, de rajouter les nouvelles règles à la fin du CSS.Va lire le tutoriel du site du zéro, ça va vraiment t'intéresser.  L'auteur part de zéro, et il explique bien mieux que moi !PS : pour ton .box h2 je crois que j'ai trouvé, et c'est assez vicieux - je te fais un email

brendufat 03/10/2006 22:19

Voilà que je commente mes propres articles, ô pauvre de moi !Finalement j'ai rajouté quelques panneaux indicateurs et le raccourci auquel j'avais pensé. Cela rend-il la tartine plus abordable ?

Annak 02/10/2006 20:12

Je suis revenue lire plus attentivement ton article. Cet aprem, j'étais au travail...
J'ai déjà résolu le mystère clear:both  grâce à toi. Je ne voyais pas son utlité dans le CSS. (un peu plus, je l'effaçais;) )
Ton article est hyper pointu, pas tout public. Au rythme où tu vas, tu rejoins Peur et Francisek dans la cour des grands dans 2 mois ;)
C'est marrant, tu intellectualises vachement l'informatique, quand moi, je fais ça à l'instinct.
Une fois que tu auras bien compris le CSS, pourquoi tu n'essayerais pas de créer un menu ? Celui de Peur (le seul sans Javascript) que j'ai trouvé, n'est pas hyper évident à faire.

Malgré tout 02/10/2006 20:26

L'est pas hyper pointu, l'est dé-tail-lé et di-dac-ti-que ! :-DJe suis vraiment passé par les étapes que je décris (sauf le Doliprane et le tour du pâté de maisons).Pour faire la version tout public, c'est facile : il suffit de ne garder que les photos avant/après pour illustrer le problème, puis sauter de "Ben alors c'est fini ?" aux dernières lignes - je pourrais même créer un lien direct à l'intérieur de l'article. Tiens, au fait, ton blog est lui aussi atteint du syndrome de la brochette flottante et tu as ici la solution toute prête  ! Quant à intellectualiser ... il se trouve que l'informatique est ou était mon métier, et que j'ai de ce fait abordé le développement WEB comme n'importe quel autre domaine inconnu : en allant aux sources et en refusant de rester indéfiniment sans comprendre. Pour citer un autre article : "le fumeur de pipe est méthodique"  ;-)Et comme je ne vois pas pourquoi je garderai pour moi ce que j'ai appris, je le livre ici.C'est vrai que ça fait beaucoup d'informations pour quelques malheureux pixels baveurs ...Dernier point : créer un menu à partir des modules c'est tentant, assez facile à faire en pur CSS, mais malheureusement le pur CSS ne marche pas sous IE - quelle surprise. C'est pourquoi je me suis rabattu sur mon système de boutons, que je dépiauterai un de ces jours. Mais patience, c'est long d'écrire des tartines pareilles !

Annak 02/10/2006 18:07

Salut :)
J'ai bien ri en regardant tes liens : je suis entourée d'hommes qui ont le même vice... sans double sens...je précise car j'ai tendance à en glisser beaucoup en parlant ;)
Je t'ai rajouté en liens utiles avec comme résumé "pour mieux comprendre le CSS". Ca te semble bien convenir à ton blog ? sachant que la définition peut évoluer.
Bonne soirée

Malgré tout 02/10/2006 20:05

Il est très flatteur, ce résumé ! Il va sûrement attirer du monde, mais si tu pouvais glisser quelque part que ce blog contient aussi autre chose ? Je l'ai dit dans le premier article de la boîte à pharmacie : je ne cherche pas à faire un site de référence, seulement (mais c'est déjà beaucoup...) à expliquer pourquoi mes recettes marchent - l'intention étant de donner au lecteur de quoi élaborer sa propre cuisine, en comprenant mieux les notions utilisées. En somme ce blog est, comme tous les autres, un exercice d'application des références W3C et ma pharmacie, le corrigé commenté de l'exercice ...

Annak 02/10/2006 15:37

Il commence à prendre belle tournure ton blog.

Malgré tout 02/10/2006 19:58

Merci ! Pourvu que ça dure ...

Archives