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 !"
Toutes ces boîtes qu'on emboîte… comment font-elles pour rentrer les unes dans les autres ? Comment le navigateur s'y prend-il quand on ne lui donne aucune indication de dimension ? Et quand on lui en donne trop ? Et si on a prévu trop large ou trop serré ? Voilà les sujets du jour.
Il s'agit ni plus ni moins d'une présentation (allégée…) du chapitre 10 et d'une partie du chapitre 11 de la spécification CSS 2, qui seuls peuvent vous donner une information complète. Comme d'habitude, je me bornerai à y grappiller ce qui me semble le plus utile et à l'orner d'exemples, de jeux de mots faciles et de quelques règles issues de la pratique.
Dans le deuxième article, Sortons en boîte
, nous en avions déjà parlé. Résumé :
blocou
en-ligne, possède en son centre un contenu. Ses dimensions sont positives ou nulles. Pour une boîte
blocce contenu est forcément d'un seul tenant et rectangulaire. Pour une boîte
en-ligne, ce contenu peut être coupé par les sauts de ligne, c'est un assemblage de rectangles.
Bloc,
en-lignekézako ? L'essentiel est dans le troisième article.
boîte de contenu(content box), une épaisseur de padding (
remplissage) dont on peut préciser la valeur, positive ou nulle, pour chacun des quatre côtés.
Notez que je n'ai été, jusqu'à maintenant, vraiment précis que pour ce qui entoure la boîte de contenu. J'ai seulement signalé, à l'occasion, que les dimensions de cette boîte de contenu s'indiquent par width et height pour une boîte de bloc, et ne s'indiquent pas, en général, pour une boîte en ligne.
Quelles sont les dimensions de cette boîte de contenu
, quand on laisse faire la nature, et même pour les boîtes en-ligne ? En général
est une formule prudente, mais quels sont les cas particuliers ? On y vient, mais il faut d'abord préciser quelque chose.
Lecteur attentif, vous avez en mémoire tout ce que j'ai déjà dit, donc il est inutile de vous rappeler que, dans le premier article, vous aviez subi un assez long développement sur l'organisation arborescente d'une page HTML, avec les notions de parent
, d' enfant
, d' ancêtre
et de descendant
(suis-je faux-jeton, tout de même… ).
En très court : le parent est celui qui contient l'autre, body est l'ancêtre de tout ce qui s'affiche, html est l'ancêtre de tout le monde. Cette arborescence est une arborescence des informations, des éléments HTML. Les boîtes emboîtées (que j'aime cette assonnance, décidément !) affichées à l'écran en composent une autre. Puisque les boîtes proviennent directement des éléments HTML, ces deux arborescences sont superposables – abstraction faite du rameau
head qui ne s'affiche pas. Fin du rappel.
Le placement d'une boîte se fait, le plus souvent, par rapport à la boîte qui la contient. De même, quand les dimensions sont exprimées en pourcentage, la base 100 est la dimension correspondante de la boîte contenante. Très précisément, la référence est la boîte de contenu de la boîte parent ; le capiton de padding, border et margin ne compte pas. Cette boîte de contenu de la boîte parent, c'est elle qu'on appelle le bloc conteneur de ce qui est immédiatement à l'intérieur.
Cette définition du bloc conteneur s'applique à la plupart des boîtes, elle recoupe certainement votre expérience de trifouilleur de blog. Mais il faut penser aussi à la moinpart
des boîtes :
Voilà un peu de concret. Dans un blog OverBlog, au départ aucun élément n'a de positionnement particulier ( = autre que static), et un élément que vous mettrez en absolu se calera par rapport au body. Pause. MAIS si cet élément absolu
se trouve, de près ou de loin, inclus dans un autre élément que vous avez déclaré absolu
ou fixe
ou relatif
, il se placera par rapport à ce dernier.
Renversons le point de vue, vous y verrez peut-être plus clair : un élément que vous déclarez absolu
, fixe
ou relatif
devient par là-même la référence, le point zéro
des autres éléments absolus
qu'il peut contenir. Aaaaaaah boooooon… C'est bien moins abstrait que vous ne le pensez, lisez la suite.
Soit un brave blog, péniblement mis au point au fil des semaines. Un jour, vous jugez que le module Recherche
serait plus utile s'il était en haut à gauche de la page. Pourquoi pas ? Vous ajoutez ceci au CSS :
.recherche {position:absolute; top:10px ; left:20px} Bien bien. Plus tard, parce que vous avez un très haut bandeau en haut de page, vous vous dites aussi que ça serait bien de remonter la colonne de modules de 50 pixels, pour qu'on la voie mieux. Supposons qu'elle soit, comme ici, à droite des articles : elle s'appelle donc cl_1_1 et une ligne de CSS suffit pour la faire grimper :
#cl_1_1 {position:relative; top:-50px} Ça marche aussi… mais c'est la cata pour le module de recherche : le voilà qui s'invite dans le haut de cette colonne déplacée, à 10 pixels du haut et 20 de la gauche ! Explication : la colonne de modules, en devenant relative
, est aussi devenue le bloc conteneur
du module recherche
, dont les coordonnées sont désormais comptées à partir de cette colonne.
Comment s'en sortir ? Ou bien en changeant les coordonnées top et left du module de recherche, ou bien en remplaçant la deuxième ligne de CSS par :
#cl_1_1 {margin-top:-50px} Question à toujours se poser : absolute oui, mais par rapport à quoi ?
Je n'ai pas de règle simple à vous donner, tout dépend de votre projet d'ensemble si vous en avez un.
La seule méthode qui vaille est de ne pas céder à la panique. Plutôt que d'empiler des rustines pour redresser à toute force un CSS et/ou un HTML bancals, mieux vaut détricoter toutes les modifications scabreuses et reconstituer pas à pas le blog, en observant ce que fait chaque étape pour repérer le moment critique. Et ça c'est un enseignement de l'expérience – parce que le coup du module baladeur, je l'ai vécu…
Les explications rigoureuses sont ici pour la largeur et ici pour la hauteur, je vous suggère d'y aller voir quand vous aurez digéré mon article.
Comme toujours, c'est assez simple et intuitif quand on ne précise rien. En première approche, et pour des boîtes normales
, qui restent dans le flux ( static ou relative) , on peut dire que :
remplacés) ont les dimensions propres à ce contenu, on peut les outrepasser avec width et height même si ce sont des éléments
en-ligne: arrivé en fin de ligne, on ne coupe pas une image en deux comme on le fait pour du texte, on la renvoie au début de la ligne suivante – ouf !
Le principe est que, pour la boîte incluse dans l'autre, la somme largeur de contenu (width) + padding + bordures + marges
soit égale à la largeur du bloc conteneur, autrement dit au width de la boîte contenante et à lui seul (nota : pour les boîtes absolues et fixes, left et right s'ajoutent à la somme). Le même principe vaut pour la hauteur.
Un piège classique est de ne comparer que les width ou les height en oubliant remplissage, bordures et marges de la boîte incluse, or il suffit de rajouter hâtivement une bordure autour des articles (par exemple) pour faire exploser un design construit au pixel près – je vous renvoie à cette démo déjà vue dans le deuxième article.
Si on ne précise pas tout, le navigateur ajuste les termes laissés libres (= ceux de valeur auto qui n'est valeur par défaut que pour width et height) pour satisfaire l'égalité. Sans répéter ici tous les détails de la spécification CSS, retenez que :
Si on précise tout (= aucune valeur auto) ya un blême. C'est alors la marge droite (pour des pages écrites de gauche à droite, ce qui est notre cas) qui est ajustée d'autorité. Et voilà, je crois, tout ce qui sert le plus souvent.
Le coup des marges auto
est à la base de la classe CtreTexte qui sert à centrer une image. Définition de cette classe :
.CtreTexte {display:block; margin: 0 auto} /* les marges gauche et droite sont auto*/ Quand on l'applique à une image :
L'idée essentielle de ce qui précède, c'est que le contenu s'ajuste au contenant et pas l'inverse. Exception (évidemment qu'il y en a une…) : les éléments absolus et fixes – prochain article, on est déjà assez occupés comme ça.
Autre exception, mais ça c'est un bug d'IE, l'interprétation de width : 100%. En toute logique, elle signifie que le contenu est aussi large que le contenant, pas plus et pas moins. Pour IE, seul de son espèce, elle signifie que le contenant peut s'élargir pour accueillir le contenu. Veuillez croire que j'ai souffert pour faire rentrer mes photos extra-larges dans les articles… La parade a été de leur donner une largeur de… 99.9% – on ne rit pas.
Et si le contenu est trop grand
? D'accord, on ajuste sa marge droite, on la rend négative pour retomber sur l'égalité sacrée, n'empêche que cet élément contenu dans l'autre déborde du bloc conteneur.
Hé oui, il déborde. Vous avez peut-être déjà croisé un maladroit qui, dans un commentaire, donne_un_lien_vers_un_site_absolument_génial_mais_avec_une_URL_à_coucher_dehors_qui_ne_veut_pas_rentrer_dans_ce_fichu_cadre (donne un lien vers un site absolument génial mais avec une URL à coucher dehors qui ne veut pas rentrer dans ce fichu cadre) , vous voyez donc ce que je veux dire.
Que faire de ce qui dépasse du conteneur ? La propriété overflow , avec ses quatre valeurs visible, hidden, scroll(plus rarement employée) et auto est là pour ça. Notez bien qu'on l'attribue au bloc qui contient l'autre, pas l'inverse : le contenant commande le contenu.
Avec visible, comme ici, le surplus est affiché, avec hidden on le coupe à ras du conteneur. scroll fait apparaître des barres de scroll même si rien ne déborde alors que auto ne fait apparaître ces barres qu'en cas de débordement. On peut même distinguer le débordement horizontal du vertical en utilisant les propriétés overflow-x et overflow-y non encore normalisées mais très largement supportées.
Exemple de overflow:auto : les modules du petit bateau, modules auxquels j'ai imposé une hauteur. Lorsqu'il y a eu trop de liens pour tous les voir dans le module Ailleurs …
est apparue une barre de défilement.
Pas très dur, vous verrez que le chapitre 11 de la spécification CSS2 n'en dit guère plus.
La chose intéressante à savoir est que, par défaut, les grandes zones d'un blog OverBlog, les #ln_0, #ln_1, #cl_1_0, #cl_1_1, etc. sont toutes en overflow:hidden. Ce choix est sage, il vise à ne pas perturber les blogueurs novices : un texte ou une image brutalement rognés c'est triste, mais moins laid et moins déroutant que si ça bave sur le reste du blog ou qu'une barre de scroll apparaît sans prévenir pour deux pixels de dépassement.
Seulement seulement… Ce rognage s'applique naturellement à tout le contenu du bloc, même si on veut exprès le faire déborder. On peut vouloir ? On peut : l'icône de catégorie que j'affiche au coin supérieur gauche de certains articles fait partie du bandeau supérieur, or elle en déborde et c'est exprès. Il y a donc dans un coin de mon CSS #ln_0 {overflow:visible} sans lequel elle serait rognée, toute image en position : absolute qu'elle soit.
De même, pour le module recherche
de tout à l'heure, il a fallu un #cl_1_1 {overflow:visible} pour le rendre visible, puisqu'il débordait de la colonne de modules.
Oui mais toi t'es un fada pervers, un maniaque de la mise en page, tout le monde sait ça.
Merci du compliment, cependant il y a d'autres choses qui peuvent avoir à déborder du bandeau supérieur : par exemple, des menus déroulants…
Ah vous ouvrez un œil, là ! Un de ces jours je pondrai moi aussi un papier sur la confection de menus comme exercice d'application de cette série d'articles. En attendant, suffit pour aujourd'hui.
Pas compris ? Pas d'accord ? Parlez-en en commentaire.