Cette partie explique comment fonctionne le modèle de boîte dans Xul, c'est à dire, comment on positionne les composants graphiques d'un écran Xul.
Une boîte est un élément XUL qui contient d'autres éléments XUL. On peut l'appeler aussi conteneur (ou « container »). Elle permet de regrouper les éléments et de les afficher selon une orientation, un alignement, une direction et un type de regroupement défini. La plupart des éléments XUL sont des conteneurs, à commencer par <window>, <dialog>, <box>, <vbox>, <hbox>, etc. Tous les exemples qui suivent sont donc appliquables à la plupart des éléments XUL.
Il y a un élément XUL générique,box, pour définir une boîte. Il possède entre autres choses un attribut orient, qui permet de définir l'orientation de l'alignement des éléments qui le contiennent :
;orient="vertical": les éléments sont disposés verticalement ;orient="horizontal": les éléments sont disposés horizontalementPar défaut (si l'attribut orient n'est pas défini), l'orientation est horizontale.
Il existe deux autres éléments pour faire des boîtes, qui ont une disposition prédéfinie :
Chaque élément XUL peut lui-même contenir d'autres éléments XUL, et donc se comporter comme une boîte.
On peut indiquer la direction dans laquelle les éléments vont être disposés grâce à l'attribut dir du conteneur.
;dir="ltr": (valeur par défaut) les éléments sont disposés de la gauche vers la droite si l'orientation est horizontale (orient = "horizontal" ou <hbox>) ou du haut vers le bas si l'orientation est verticale (orient = "vertical" ou <vbox>). ;dir="rtl": les éléments sont disposés de la droite vers la gauche ou du bas vers le haut suivant l'orientation.Note mnémotechnique : « ltr » signifie « left to right », c'est à dire « gauche à droite ». « rtl » signifie « right to left », c'est à dire « droite à gauche ».
Il y a quatre manières de définir la taille (hauteur et largeur) d'un élément :
Le modèle de boîte XUL pourrait être comparé à celui que l'on trouve souvent dans le monde unix, pour le système X, comme par exemple dans le gestionnaire de fenêtre Motif.
Il permet de définir la taille des boîtes, non pas avec des valeurs fixes, mais en indiquant des proportions. Ainsi l'agencement des boîtes dans une fenêtre se fait automatiquement en fonction de la dimension de la fenêtre, de l'apparition ou disparition d'autres éléments d'interface. Le système s'arrange toujours pour que les éléments gardent les mêmes proportions indiquées lors de la construction de l'interface.
L'attribut flex permet de spécifier ces proportions ou, plus justement, la flexibilité de l'élément. Il contient une valeur entière sans unité, déterminant la taille relativement aux tailles et la flexibilité des boîtes voisines (des boîtes sœurs). Cette proportion agit soit sur la hauteur, soit sur la largeur, en fonction de l'orientation définie par la boîte parente (le conteneur).
Dans cet exemple, les flexibilités définies pour A, B, C s'appliqueront à leur hauteur, puisque la boîte parente est une boîte verticale (vbox).
<vbox>
<box id="A" flex="1"/>
<box id="B" flex="1" />
<box id="C" flex="1"/>
</vbox>
Dans cet autre exemple, les flexibilités définies pour A, B, C s'appliqueront à leur largeur, puisque la boîte parente est une boîte horizontale (hbox).
<hbox>
<box id="A" flex="1"/>
<box id="B" flex="1" />
<box id="C" flex="1"/>
</hbox>
Notez pour commencer que la taille de ces trois boîtes peut être différente, principalement en fonction de leur contenu respectif. C'est la raison pour laquelle ce flex ne doit pas être confondu avec la définition d'une proportion de taille.
Définir le flex des boîtes A, B et C à 1, cela signifie qu'elles réagiront toutes trois de la même façon lorsque, par exemple, la taille de leur conteneur sera modifiée.
Un exemple : Imaginons que nos trois boîtes aient pour parent la fenêtre elle-même :
<window orient="horizontal">
<box id="A" flex="1"/>
<box id="B" flex="1" />
<box id="C" flex="1"/>
</window
Imaginons, que la boîte A ait une largeur « naturelle » de 100 pixels (déterminée par son contenu, p.e. une image qui mesure 100px sur 100px). Imaginons que la boîte B, qui contient un texte court, ait une largeur « naturelle » de 20 pixels, et que la boîte C, qui ne contient qu'un menu, ait une largeur « naturelle » de 40 pixels. Récapitulons :
Imaginons à présent que l'utilisateur modifie la taille de sa fenêtre, en la rétrécissant, en largeur, de moitié. Puisque la flexibilité des trois boîtes est égale, les trois boîtes réagiront de la même façon à ce rétrécissement. Leurs nouvelles largeurs seront :
Notez que les boîtes réagiraient de la même façon si leur flex était à 5 :
<vbox>
<box id="A" flex="5"/>
<box id="B" flex="5" />
<box id="C" flex="5"/>
</vbox>
Les flexibilités des boîtes sont intimement liées les unes aux autres.
À présent, si l'on modifie le flex d'une des boîtes, on modifie physiquement sa flexibilité. Mettre le flex de la boîte A à 3, par exemple, signifiera pour le générateur de rendu (choisissez la formule qui vous plaît ;-)):
Vous pourrez voir ci-dessous comment calculer précisément cette flexibilité des boîtes.
Il se peut, dans certains cas, que le contenu d'une des boîtes impose une taille fixe ou une taille minimum ou maximum (avec les styles width, height, max-width, max-height…). De ce fait, selon la dimension de la boite parente (qui elle-même dépend de sa boîte parente etc. et donc par cascade, selon la dimension de la fenêtre), il est possible que les proportions ne soient pas toujours respectée (rappelez-vous qu'il s'agit plus de flexibilité que de proportion, même si les deux notions sont intimement liées). En effet, le moteur de rendu s'efforce de toujours faire en sorte que tous les éléments soient visibles, quelque soit la taille (bien sûr, quand la fenêtre atteint une taille minimum, il peut arriver qu'il ne soit plus possible de tout afficher).
Calculer mathématiquement la flexibilité des boîtes est assez simple. On prend les valeurs des flexs des boîtes de même niveau (qui ont le même parent, ou boîtes adjacentes si vous préférez), on additionne ces flexs et cela nous donne un diviseur. Ensuite, pour obtenir la véritable proportion de chaque boîte, on divise leur flex par ce diviseur. Exemple :
<vbox id="TOP" style="[[height:100px;"]]>
<box id="A" flex="3"/>
<box id="B" flex="5"/>
<box id="C" flex="2"/>
</vbox>
Le total des flexs vaut 10 (3 + 5 + 2). Par conséquent :
Il n'est pas necessaire de mettre un flex à chaque boîte, les boîtes ayant en priorité une taille au moins égale à celle de leur contenu. Mais il peut être interressant d'en mettre un sur certaines boites pour qu'elle prenne un maximum de place.
<vbox id="TOP">
<box id="A"/>
<box id="B" flex="1" />
<box id="C" />
</vbox>
Ici il n'y a que la boîte B qui a un flex, les autres valant 0 par défaut. Si on suit les calculs, on aura alors :
On remarque donc que la boîte B prendra toute la hauteur de TOP dans l'idéal. En effet, A et C ayant probablement un contenu, elles auront donc une hauteur minimum imposée. Cela permet donc de dire que B devra prendre 100% de la place disponible (c'est à dire la place restant entre la boîte A et la boîte B).
Autre exemple :
<vbox id="TOP">
<box id="A"/>
<box id="B" flex="1" />
<box id="C" flex="1" />
</vbox>
ici, B et C se partageront la hauteur restant sous la boîte A (puisque proportion de 1/2 chacune).
Ces deux attributs permettent de préciser le positionnement des élèments dans une boite.
Les valeurs possibles de pack sont "start", "center", "end".
Pour en voir le résultat, cela implique qu'il n'y ait pas de flex sur les élements.
Les valeurs possibles de align sont "stretch", "start", "center", "end", "baseline"
Indique ce qu'il faut couper dans le contenu textuel, si celui ci est trop grand par rapport à la largeur du contenant.
Un spacer n'est rien d'autre qu'une boîte vide, transparente, qui permet d'espacer les éléments. Tous les attributs décrits précédement s'appliquent, et tout particulièrement la flexibilité : on peut lui donner une taille proportionnelle à ses boîtes voisines. On pourra l'utiliser par exemple pour insérer un espace entre deux boîtes, calant chacune de ces deux boîtes aux extrémités de leur container : il suffit de mettre un flex="1" sur <spacer/>, et pas de flex sur les autres boîtes :
<hbox id="mes-boutons">
<button id="bouton-annulation" label="Annuler" />
<spacer flex="1" />
<button id="bouton-OK" label="OK" />
</hbox>
Dans ce cas, si la boîte "mes-boutons" fait toute largeur de la fenêtre, le bouton « Annuler » se retrouvera tout à gauche et le bouton « OK » tout à droite (le spacer occupant pour sa part toute la place restante entre les deux boutons).
Pour comprendre le rôle de tous les attributs et les différentes manières de positionner et spécifier les éléments, vous pouvez utiliser ce testeur de modèle de boîte : http://xulfr.org/sources/tutoriel/boite/(..)
Les attributs que l'on a vu fixent en fait des styles CSS. On peut donc tout à fait mettre toutes ces propriétés d'agencement, non pas dans le fichier XUL, mais dans un fichier CSS. C'est fortement conseillé, pour séparer d'un côté le contenu et de l'autre l'aspect que doit prendre ce contenu dans la page.
Voici les équivalences
attribut XUL | propriété CSS |
flex | -moz-box-flex |
pack | -moz-box-pack |
align | -moz-box-align |
width | width |
height | height |
(crop ne semble pas avoir d'équivalent)
(à compléter)
Il faut savoir aussi que les éléments XUL ont une propriété CSS display:-moz-box
Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.