Si, comme moi, vous aimez triturer un peu la mise en page de vos histoires Twine, les grilles CSS ont toutes les chances de vous intéresser. Il s’agit d’un outil très polyvalent, qui permet de disposer des éléments sur une grille en deux dimensions et qui est pris en charge par la plupart des navigateurs récents. Pour mieux comprendre son fonctionnement et les possibilités qu’il apporte, je vous propose de le découvrir à l’aide de trois petits exemples.
Pour pouvoir suivre ce tutoriel, il est recommandé d’être un peu à l’aise avec les langages HTML et CSS. Si ce n’est pas votre cas, je ne peux que vous recommander d’aller en apprendre un peu plus ; les bases ne sont pas très compliquées, et ça ouvre les portes vers plein d’options pour personnaliser l’apparence de vos histoires. Par exemple, commencez par notre article d’introduction au CSS pour Twine, et enchaînez avec un tutoriel plus avancé !
En-tête, menu et pied de page
Pour commencer, créons une mise en page simple comprenant un en-tête, une barre de menu à gauche, un espace à droite pour le contenu et un pied de page. Comme ceci :
Commençons par ouvrir un nouveau passage, et créons-y la structure de notre page : un bloc « contenant » à l’intérieur duquel on placera nos quatre autres blocs.
{
<div class="contenant">
<div class="entete"><h1>Titre</h1></div>
<div class="menu">Menu</div>
<div class="contenu">Contenu</div>
<div class="pieddepage">Pied de page</div>
</div>
}
Il nous faut ensuite modifier la feuille de style de l’histoire. Il faut tout d’abord indiquer au contenant de se comporter comme une grille. Pour cela, rien de plus simple, il suffit d’ajouter ces lignes :
.contenant {
display: grid;
}
Il faut ensuite définir le nombre, et la taille, des lignes et des colonnes de la grille. Pour notre modèle simple, nous n’avons besoin que de trois lignes, et de deux colonnes, que nous allons définir à l’aide des propriétés grid-template-rows
et grid-template-columns
, respectivement. On en profitera pour définir la hauteur et la largeur de notre grille, et lui assigner une couleur de fond. Notre code devient :
.contenant {
display: grid;
background-color: #7c8cbf;
width: 100%;
height: 100vh;
grid-template-rows: 2fr 5fr 1fr;
grid-template-columns: 1fr 2fr;
}
Pour la largeur, on ne s’est pas embêtés : 100%
, ça veut dire qu’il va garder la même largeur que son parent (tw-story
si on travaille avec Harlowe).
Pour la hauteur, ça se complique : par défaut, les éléments HTML n’ont pas de hauteur, et s’ajustent à leur contenu ; or, on souhaiterait ici que notre grille occupe toute la hauteur de la page, même lorsqu’elle est vide. C’est ce que permet l’unité vh
: elle définit la hauteur d’un élément en proportion de la taille de la fenêtre : 20vh
, c’est 20 % de la hauteur du viewport, 100vh
correspond donc à la hauteur totale du viewport.
Pour les lignes et les colonnes, on a choisi l’unité fr
, qui, si elle peut paraître un peu étrange, est en réalité très pratique. Examinons notre ligne grid-template-columns: 1fr 2fr;
. Elle signifie que nous voulons diviser notre grille en deux colonnes, celle de droite étant deux fois plus large que celle de gauche. Le navigateur va s’occuper tout seul de calculer leur largeur en fonction de l’espace disponible.
Vous me direz : pourquoi ne pas avoir utilisé les %
? Il y a plusieurs raisons à cela. La première : imaginons que, plus tard, je change d’avis, et je décide d’ajouter une troisième colonne, de même taille que la première. Si j’avais utilisé les %
, je devrais non seulement ajouter la taille de ma troisième colonne, mais aussi ajuster celles des deux premières colonnes. Avec les fr
, il suffit d’ajouter 1fr
à la suite de la ligne, et c’est le navigateur qui s’occupe de faire le calcul. Idem si je décide d’élargir la colonne de droite : avec les fr
, je ne modifie que la valeur de la deuxième colonne, la largeur de la première s’ajustera automatiquement, alors qu’avec les %
, j’aurais dû rectifier les deux valeurs. La deuxième raison n’est pas évidente dans cet exemple, on en reparlera plus tard. L’utilisation des fr
n’est évidemment pas obligatoire, on peut utiliser toute autre unité de longueur acceptée par CSS.
Maintenant que notre grille est formée, il va falloir la remplir. Pour cela, ciblons les blocs que nous avons créés dans notre passage. Nous allons leur assigner la place qui leur convient dans la grille. Ajoutons ces lignes à notre feuille de style :
.entete {
background-color: #152866;
grid-area: 1 / 1 / span 1 / span 2;
padding: 20px;
}
.menu {
background-color: #4b61a8;
grid-area: 2 / 1;
padding: 20px;
}
.contenu {
grid-area: 2 / 2;
padding: 20px;
}
.pieddepage {
background-color: #152866;
grid-area: 3 / 1 / span 1 / span 2;
padding: 20px;
}
La propriété qui nous intéresse, c’est grid-area
. Elle permet de définir la cellule de départ et la taille de chacun de nos blocs. Analysons par exemple la ligne correspondante pour l’en-tête : grid-area: 1 / 1 / span 1 / span 2;
. Les deux premiers nombres définissent le point de départ de notre zone : ici, la première ligne et la première colonne. Quant au span 1
et au span 2
, ils signifient respectivement que notre zone doit occuper une seule ligne, et deux colonnes. Il est important de citer les valeurs dans cet ordre, et de les séparer par des « / ». Pour les blocs qui n’occupent qu’une seule cellule, on peut omettre les deux dernières valeurs : on se contente de spécifier la ligne et la colonne choisis, comme on l’a fait pour le menu et le contenu.
Si vous voulez réutiliser la même interface tout au long de votre histoire, vous pouvez bien sûr écrire le début du code HTML (jusqu’à <div class="contenu">
par exemple) dans un passage taggé header
et la fin (à partir de </div> <div class="pieddepage">
), dans un passage taggé footer
; seul le contenu sera modifié d’un passage à un autre, et ça vous épargne bien des copier-coller.
Il ne reste plus qu’à ajouter du contenu dans toutes ces zones ! À moins que vous ne préfériez en apprendre un peu plus sur les grilles avec un deuxième projet…
Retrouvez et téléchargez ce premier projet ici !
Un calendrier
Attelons-nous maintenant à un projet un peu plus compliqué, comportant bien plus de lignes et de colonnes : nous allons créer une page de calendrier.
Nous avons donc besoin d’un tableau à 7 colonnes de même largeur (une par jour de la semaine) et à 6 lignes (une plus petite pour spécifier le jour de la semaine, 5 plus grandes pour les cases quotidiennes). On remarque que l’on veut trois types de cellules différentes : des cellules turquoise, d’autres gris clair et des gris foncé. Commençons par nous attaquer au passage Twine qui contiendra tout ça. On y ajoute le titre, notre bloc « contenant » et toutes les petites cases. Il y en a beaucoup, mais le code est très similaire, donc on peut allègrement copier-coller.
<h1>Juin 2018</h1>
{
<div class="calend">
<div class="jour">L</div>
<div class="jour">Ma</div>
<div class="jour">Me</div>
<div class="jour">J</div>
<div class="jour">V</div>
<div class="jour">S</div>
<div class="jour">D</div>
<div class="vide"></div>
<div class="vide"></div>
<div class="vide"></div>
<div class="vide"></div>
<div class="date">1</div>
<div class="date">2</div>
<div class="date">3</div>
<div class="date">4</div>
<div class="date">5</div>
<div class="date">6</div>
<div class="date">7</div>
<div class="date">8</div>
<div class="date">9</div>
<div class="date">10</div>
<div class="date">11</div>
<div class="date">12</div>
<div class="date">13</div>
<div class="date">14</div>
<div class="date">15</div>
<div class="date">16</div>
<div class="date">17</div>
<div class="date">18</div>
<div class="date">19</div>
<div class="date">20</div>
<div class="date">21</div>
<div class="date">22</div>
<div class="date">23</div>
<div class="date">24</div>
<div class="date">25</div>
<div class="date">26</div>
<div class="date">27</div>
<div class="date">28</div>
<div class="date">29</div>
<div class="date">30</div>
<div class="vide"></div>
</div>
}
On a bien nos trois classes de cases différentes, et on n’oublie pas les accolades qui font ignorer les sauts de ligne à Twine, sans quoi on risque d’avoir quelques surprises
On ouvre ensuite notre feuille de style pour mettre tout ça en forme ; commençons par le contenant :
.calend {
background-color: #212A2A;
width: 600px;
min-height: 400px;
padding: 10px;
display: grid;
grid-gap: 8px;
grid-template-columns: repeat(7, 1fr);
grid-template-rows: 1fr repeat(5, 2fr);
grid-auto-flow: row;
overflow-x: hidden;
}
Outre les propriétés classiques qui définissent ses dimensions et sa couleur, on trouve bien sur le display : grid
, et les grid-template-rows/columns
. Pour ces derniers, la valeur de la propriété (la partie à droite des deux-points) est un peu différente de l’exemple précédent. En effet, plutôt que de déclarer une à une les largeurs (hauteurs) voulues pour chaque colonne (ligne), on a utilisé repeat
pour pouvoir créer d’un seul coup un grand nombre de colonnes (lignes) de même dimension. Ainsi, repeat(7, 1fr)
signifie « je veux 7 colonnes de même largeur », tandis que 1fr repeat(5, 2fr)
signifie « je veux une première ligne d’une certaine hauteur, puis 5 autres qui sont toutes deux fois plus grosses que la première ».
On a aussi écrit une ligne grid-gap: 8px;
, qui permet d’ajouter de l’espace entre les cellules, appelé gouttière, ce qui permet de les séparer sans leur ajouter de bordure. Cette petite ligne apparemment bien innocente va nous permettre d’aborder le deuxième avantage des fr
sur les %
. En effet, si on avait défini la largeur de nos colonnes en %
, en s’arrangeant pour que la somme fasse 100 %, cet espace de 8 petits pixels entre les colonnes aurait fait déborder nos cellules à l’extérieur du contenant (et bien oui, 100 % de la largeur + 48 pixels, c’est strictement plus grand que 100 %). Plutôt que de devenir fou à essayer de tout recalculer par nous-même, on utilise les fr
pour laisser le navigateur s’en occuper.
Enfin, dernière ligne consacrée à la grille :grid-auto-flow : row ;
. C’est une propriété qui est très utile quand on a plein de cases à ajouter qui s’agencent de manière simple. Plutôt que de déclarer une par une la position de chaque case, on lui dit de commencer en haut à gauche, puis de remplir la première ligne. Une fois que toutes les colonnes de la première ligne sont remplies, on passe à la deuxième, en commençant à gauche, etc. Et ce jusqu’à avoir atteint la dernière case.
Comme on laisse toutes les cellules se placer automatiquement, pas besoin de spécifier leur position avec grid-area
, les déclarations des classes jour
, date
et vide
contiennent donc uniquement des propriétés de couleur ou de placement du texte très classiques.
Retrouvez et téléchargez ce calendrier ici !
Un plan
Pour finir, un projet encore un peu plus complexe : nous allons créer un plan avec des liens cliquables permettant de se déplacer dans diverses pièces d’un manoir.
Si vous remarquez quelques différences dans la présentation du plan, c’est normal : celui du rez-de-chaussée a été créé en utilisant des dimensions en %
et des cases entourées de bordures noires, tandis que celui du premier étage utilise des dimensions en fr
et grid-gap
. Je vous laisse deviner lequel je préfère…
Cet exemple va permettre d’illustrer une autre manière de positionner les cellules dans la grille : en les nommant. On commence comme d’habitude, en créant la structure HTML dans un passage Twine.
<h2>Rez-de-chaussée</h2>
<div class="plan">\
<div class="smanger">[[Salle à Manger]]</div>\
<div class="bibli">[[Bibliothèque]]</div>\
<div class="cuisine">[[Cuisine]]</div>\
<div class="hall">[[Hall]]</div>\
<div class="salon">[[Salon]]</div>\
</div>
[[Monter à l'étage|Plan 1]]
La classe plan
va nous servir de grille, et on crée une cellule pour chaque pièce de notre manoir. Dans la feuille de style, on va donc inscrire :
.plan {
display: grid;
grid-template-columns: 14.28% 14.28% 14.28% 14.28% 14.28% 14.28% 14.28%;
grid-template-rows: 16% 16% 16% 16% 16% 16% 4%;
}
.smanger {
grid-area: smanger;
}
.bibli {
grid-area: bibli;
}
.cuisine {
grid-area: cuisine;
}
.hall {
grid-area: hall;
}
.salon {
grid-area: salon;
}
La grille est donc bien définie, avec ses lignes et ses colonnes, et on a donné un nom à chacune des pièces à situer sur notre plan. Maintenant, on va pouvoir utiliser ces noms avec la propriété grid-template-areas
pour expliquer où va quelle pièce sur le plan. Si on veut qu’une case de la grille reste vide, on inscrit juste un point à l’emplacement correspondant.
.plan {
display: grid;
grid-template-columns: 14.28% 14.28% 14.28% 14.28% 14.28% 14.28% 14.28%;
grid-template-rows: 16% 16% 16% 16% 16% 16% 4%;
grid-template-areas:
"smanger smanger bibli bibli bibli bibli bibli"
"smanger smanger bibli bibli bibli bibli bibli"
"smanger smanger hall hall hall salon salon"
"smanger smanger hall hall hall salon salon"
"cuisine cuisine hall hall hall salon salon"
"cuisine cuisine hall hall hall salon salon"
". . hall hall hall . . ";
}
On crée donc une sorte de tableau : les lignes sont délimitées par des guillemets et les colonnes, par au moins une espace. Je conseille toutefois d’an ajouter plus pour aligner vos colonnes, ça rend votre feuille de style bien plus lisible.
Il ne reste plus qu’à faire le même travail pour le premier étage, et bien sûr à créer une histoire mettant à profit cette interface !
Retrouvez et téléchargez ce dernier exemple ici !
10 avril 2020 at 16 h 06
Bonjour,
J’essaye désespérément de faire un plan depuis plus de deux heures… Mais les grilles ainsi que les bordures de mon plan n’apparaissent pas. Je cherche dans la feuille de style d’où vient le problème, sans comprendre. Si quelqu’un pouvait m’aider j’apprécierais grandement !
10 avril 2020 at 16 h 53
Rebonjour,
J’ai fait un copier-coller pure et simple du code inscrit plus haut sur la page, pour créer un plan. Cela ne fonctionne tout simplement pas, les délimitations (bordures) du plan ne s’affichent pas.
Je me demande donc si ce plan a été fait avec la version 1 de Twine (vu que j’utilise la seconde).
10 avril 2020 at 18 h 27
Bonjour,
Tous les exemples de code de cet article ont été réalisés avec Twine 2 Harlowe, mais devraient être compatibles avec toutes les versions de Twine.
Pour créer ce genre de mise en page, il faut d’une part créer les différents blocs à l’aide de code html (de la forme …), qui doit être inscrit dans un passage Twine.
D’autre part, changer la mise en forme de ces blocs à l’aide de la feuille de style CSS (avec du code de la forme .plan { display: grid; …}).
Avez-vous bien ces deux types de code et sont-ils au bon endroit ? Si oui, le problème est un peu plus compliqué à régler, surtout sans voir à quoi ressemble votre projet.
N’hésitez pas à récupérer les projets complets : il suffit de faire un clic droit sur les liens, d’enregistrer l’adresse du lien quelque part sur votre ordinateur et d’ouvrir le fichier html obtenu avec Twine. Vous pourrez ainsi vérifier s’ils s’exécutent correctement en appuyant sur le bouton « lancer » de Twine et comparer le projet avec le votre.
J’espère que ce message vous aidera un peu.
2 janvier 2021 at 22 h 43
Que de matière ; merci encore, je me régale à découvrir et parcourir ça !
Votre technique de télécharger la page html et de la recharger dans Twine marche à merveille ; pour le premier projet, je l’ai trouvé en remplaçant les espaces par des « tirets du bas » (« Mise_en_page.html ») ; et ça marche à merveille, je ne connaissais pas non plus les balises, et celles-ci (« header » et « footer ») fonctionnent automatiquement !
Et le plan de la maison me donne tout de suite des envies de jeu type « Cluedo » ou « Escape game »… 🙂