Paris, photo, humeurs, un peu de HTML/CSS pour faire sérieux. Feinte innocence et vraie naïveté (ou vice-versa). Encore un blog qui agite ses petits bras en couinant "Viens me lire !"
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.
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 :
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}
Ben alors, l'article est fini ?
Non… Non parce que :
La solution est ici mais vous allez manquer quelque chose.
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.
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.
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 :
feuille de styleproprement 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 :
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.
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 :
block box, texte et images, et le dispose soigneusement de gauche à droite ;
block box(d'où la sort-il ? c'est une autre histoire) il passe à la ligne suivante et recommence ;
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 ;
block boxavec 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…
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.
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
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;} À quel endroit l'écrire ? Deux choix possibles :
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.