jQuery.info
Découvrir et utiliser jQuery, la librairie javascript du XXIIème siècle

Accueil du site > Actualités > Du texte mouvant qui habille une image fixe

Du texte mouvant qui habille une image fixe

lundi 28 décembre 2009, par ARNO*


J’ai développé, pour Blog-Mode.info, un effet que je crois inédit en HTML : il s’agit de faire circuler le texte autour d’une image (en jargon typographique : « habiller l’image avec le texte »), cette image étant fixe dans la page, et le texte conservant ses possibilités de déplacement vertical (scroll).

Comme c’est assez difficile à décrire, autant aller voir à quoi cela ressemble sur cette page.

Tout se passe dans la partie en bas à droite de la page : on a un mannequin, qui se détache sur le fond vert, et le texte s’affiche en suivant les limites de l’image (et non, comme c’est habituellement le cas en HTML, suivant le rectangle du fichier image). Pour réaliser l’habillage, j’utilise le script pour SPIP que j’ai développé en mars 2006, qui fabrique automatiquement le code HTML à partir du fichier image. Ce script a, depuis, été transformé en plugin pour SPIP, et c’est cette version que j’utilise sur Blog-Mode (j’en ai profité, au passage, pour l’améliorer).

Mais, ici, ça n’est pas l’habillage irrégulier (développé en 2006) qui est original : c’est le fait que l’image est fixée en bas à droite de l’écran. Si on fait défiler le texte verticalement, l’image ne « bouge » pas à l’écran, et le texte se déplace en continuant à respecter la forme irrégulière de l’habillage.

Et ça, c’est à ma connaissance totalement inédit.

Commençons par créer le contenu et la structure de notre page.

  1.        
  2. </head>
  3.        
  4. <div id="contenu">
  5.         <div id="elastique"></div>
  6.         <div id="image"><img src="image.png" alt="" width="236" height="300" /></div>
  7.         <div id="pave_texte">
  8.                 <h1>Le titre</h1>
  9.                
  10.                 <div class="texte">
  11.                         <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, sapien vel feugiat hendrerit, ante felis mollis nunc, eget rutrum sapien arcu et turpis. Proin blandit sapien quis ante ullamcorper eget malesuada mi facilisis. Aenean risus velit, eleifend vitae lacinia nec, varius nec lorem. Aenean nisi urna, faucibus et lacinia a, dictum at erat. Maecenas laoreet eros nec felis tempor ac tempus felis lacinia. Vivamus aliquet semper ullamcorper. Donec ligula nisi, pellentesque non aliquet eget, malesuada nec sem. Sed ultricies arcu ut mauris eleifend pretium. Integer mattis, diam quis ultrices faucibus, lectus diam laoreet lectus, eu rutrum nunc lacus eu enim. Suspendisse potenti. Vestibulum hendrerit dolor a eros fermentum nec consectetur massa congue. Proin ornare rutrum arcu non tempor. Aliquam fermentum nulla et justo porttitor sit amet tristique dolor commodo. Fusce turpis sem, suscipit porttitor euismod eleifend, vehicula vestibulum nisl.</p>
  12.                         <p>Cras dui erat, vulputate nec dictum vel, commodo id ante. Fusce bibendum varius fermentum. Maecenas lacinia egestas mi vel ultrices. In augue sapien, gravida quis vestibulum porttitor, congue et enim. Aenean condimentum tempus nisi, at vehicula magna luctus non. Nam ultricies urna in purus facilisis non venenatis ligula tincidunt. Quisque porta varius lectus, vitae vestibulum leo commodo nec. Morbi justo neque, ultrices in egestas ut, consectetur sed neque. Maecenas egestas malesuada gravida. Cras eleifend quam accumsan leo sodales viverra. Aliquam erat volutpat. Morbi nec sapien vel orci commodo volutpat nec ut ipsum.</p>
  13.                         <p>Vivamus nec rutrum est. Curabitur lectus turpis, adipiscing et commodo a, blandit eu nisi. Nulla eget mi id mauris interdum accumsan vel et quam. Morbi sed neque felis. Duis sit amet dolor neque, nec tincidunt magna. Duis iaculis elementum lacus, nec elementum metus vehicula eu. Aenean sed tortor at erat blandit consectetur et vel lectus. Sed ligula nisl, posuere et pretium nec, facilisis ut nisl. Vivamus ultrices suscipit feugiat. Pellentesque eleifend varius lectus et iaculis. In gravida nisl id elit facilisis tempor. Sed eros dolor, fermentum quis aliquet id, ornare bibendum enim. Pellentesque fringilla pharetra sem, vitae interdum tellus varius quis. Sed tempor dignissim risus, vitae mattis quam aliquam in. Mauris facilisis magna a urna ultricies suscipit. Integer semper gravida nibh sed luctus. In hac habitasse platea dictumst. Nulla facilisi. Vivamus ac purus accumsan magna hendrerit ornare.</p>
  14.                         <p>Praesent porta egestas orci, hendrerit consequat mi posuere non. Donec egestas posuere sapien, nec cursus elit sodales vel. Donec hendrerit mi non tellus luctus ullamcorper. Etiam eget magna et ante convallis pellentesque ut id augue. Curabitur tincidunt, velit a hendrerit aliquam, quam est fringilla purus, non scelerisque velit purus auctor est. Proin elit neque, venenatis quis iaculis et, cursus id dui. Quisque vehicula dignissim egestas. Nam viverra tincidunt eros porta sollicitudin. Cras porta mauris mollis ante bibendum id condimentum leo posuere. Maecenas lacinia pretium vehicula. Nam non metus tortor, quis dictum risus. Vivamus facilisis adipiscing arcu a commodo. Nulla consequat pulvinar risus, eu varius diam gravida sed. In hac habitasse platea dictumst. Etiam eget risus dolor, semper aliquam nisi. In hac habitasse platea dictumst. Aenean elementum hendrerit lacus eu luctus.</p>
  15.                         <p>Suspendisse porttitor condimentum enim vitae aliquam. Fusce ultricies tristique sem, vel pellentesque mi consequat id. Nunc vulputate vehicula lorem, non gravida dui vulputate a. Nulla euismod ligula et sem luctus fermentum. Mauris sodales est id magna rhoncus molestie. Praesent non felis in ipsum dapibus feugiat. Nulla eget sem a urna dictum interdum. Proin eu metus sed nisl pellentesque eleifend at vel lectus. Mauris bibendum eros et nulla pretium lobortis. Aenean blandit lacus non nulla mollis mollis. Maecenas non ultricies ligula.</p>
  16.                 </div>
  17.         </div>
  18. </div>
  19. </body>
  20. </html>

La structure est très simple :
- un div #contenu contenant la partie qui nous intéresse ici (on pourra ajouter, évidemment, un #header, un #footer par ailleurs) ;
- un premer div #elastique qui, pour l’instant, ne sert à rien ;
- un div #image qui contient l’image que nous allons chercher à afficher en bas à droite de notre document ;
- un #pave_texte qui contient le texte du document (titre et texte libre).

Commençons par donner un style à ces différents éléments :

  1.         <style style="text/css">
  2.                 body {
  3.                         margin: 0px;
  4.                         padding: 0px;
  5.                 }
  6.                 #contenu {
  7.                         height: 100%;
  8.                         overflow: auto;
  9.                 }
  10.                 #pave_texte {
  11.                         padding: 20px;
  12.                 }
  13.                 #pave_texte .texte {
  14.                         text-align: justify;
  15.                 }
  16.                 #elastique {
  17.                         width: 5px;
  18.                         height: 150px;
  19.                         float: right;
  20.                         overflow: hidden;
  21.                         background-color: blue;
  22.                 }
  23.                 #image {
  24.                         width: 236px;
  25.                         height: 300px;
  26.                         clear: right;
  27.                         float: right;
  28.                         background-color: red;
  29.                 }
  30.         </style>

Quelques astuces sont à noter ici :
- je donne une couleur de fond à #elastique et #image, uniquement dans le but de visualiser mon effet ; dans la version finale, on supprimera évidemment ces couleurs ;
- body colle directement aux bords de la fenêtre, avec margin et padding à zéro ;
- c’est #contenu qui va servir, ici, de fenêtre défilante : on lui donne une hauteur de 100% et un overflow automatique ; il occupe ainsi toute la fenêtre ;
- très important : #elastique et #image sont en float right, ce qui force leur affichage à droite de la fenêtre et oblige le texte à les habiller ; l’astuce ici est d’indiquer, pour #image, un clear right, qui permet d’obtenir l’effet suivant : #image est bien un élément flottant à droite, mais il se positionne sous l’élément flottant précédent (#elastique).

Notez bien : le clear right est à l’intérieur du style de #image, et pas dans un div qui le précéderait. Tout est dans cette séquence de #image :

  1. clear: right;
  2. float: right;

C’est le présence du clear et du float dans le même style qui permet d’avoir cet habillage qui concerne plusieurs float à la suite (le texte qui suit habille à la fois #elastique et #image, qui ont pourtant des largeurs différentes).

On constate ici que :
- l’élément bleu, #elastique, a pour l’instant une hauteur fixée de 150 pixels ;
- l’élément rouge, #image, chasse bien le texte, et commence à 150 pixels du haut de la fenêtre.

Que se passe-t-il si l’on fait varier la hauteur du pavé bleu (#elastique) ? On aurait l’#image qui se décalerait vers le haut ou vers le bas, et le texte l’habillerait à sa nouvelle position.

Et si l’on calcule correctement la hauteur du pavé bleu, on peut décider de positionner, au pixel près, le pavé rouge pour qu’il s’affiche en bas à droite de la fenêtre.

Nous allons donc ajouter du jQuery pour calculer et modifier la hauteur de #elastique.

  1.         <script src="jquery.js" type="text/javascript"></script>
  2.         <script type="text/javascript"><!--
  3.                 function hauteur_elastique() {
  4.                         hpage = $("#contenu").height() - $("#image").height();
  5.                         $("#elastique").height(hpage);
  6.                 }
  7.        
  8.                 $(document).ready(function(){
  9.                         hauteur_elastique();                   
  10.                 });    
  11.        
  12.         --></script>

Et voilà : l’image se positionne en bas à droite de la fenêtre, parce qu’elle est repoussée par le pavé bleu dont la hauteur est calculée en javascript :

La hauteur de l’élastique, c’est tout simplement : la hauteur de la fenêtre moins la hauteur de l’image.

On obtient là le bon affichage au chargement de l’écran. Mais en revanche, ça ne fonctionne pas quand on scrolle...

Modifions donc notre code :

  1.         <script type="text/javascript"><!--
  2.                 function hauteur_elastique() {
  3.                         hpage = $("#contenu").height() + $("#contenu").scrollTop() - $("#image").height();
  4.                         $("#elastique").height(hpage);
  5.                 }
  6.        
  7.                 $(document).ready(function(){
  8.                         hauteur_elastique();                   
  9.                         $("#contenu").scroll(function() {
  10.                                 hauteur_elastique();
  11.                         });
  12.                 });    
  13.        
  14.         --></script>

Désormais, on demande de recalculer la hauteur du pavé bleu à chaque fois qu’on détecte que le contenu a été scrollé (c’est la fonction « scroll » de jQuery qui permet de redéclencher le calcul hauteur_elastique()).

Et, dans le calcul de la hauteur de l’élastique (jusqu’à présent égale à la hauteur de la fenêtre moins la hauteur de l’image), on ajoute la position du scroll de la fenêtre. Si on a scrollé de 100 pixels (le « haut » du pavé de texte se situe donc 100 pixels au-dessus du début de la fenêtre), il faut bien descendre l’image de 100 pixels supplémentaires.

Que se passe-t-il si la hauteur de la fenêtre est inférieure à la hauteur de l’image (ce qui arrive assez souvent si l’image est grande, comme sur Blog-Mode) ? On obtient une hauteur de l’élément #elastique négative ; et on ne doit évidemment pas créer d’élément de hauteur inférieure à zéro ou nulle.

On complète donc par un petit test :

  1.                 function hauteur_elastique() {
  2.                         hpage = $("#contenu").height() + $("#contenu").scrollTop() - $("#image").height();
  3.                         if (hpage < 1) {
  4.                                 $("#elastique").hide();
  5.                         }
  6.                         else {
  7.                                 $("#elastique").show();
  8.                                 $("#elastique").height(hpage);
  9.                         }
  10.                 }

Si la hauteur calculée pour l’élément #elastique est inférieure à 1 pixel, on se contente de cacher l’élément. Sinon on l’affiche et on applique sa nouvelle hauteur.

On a maintenant l’affichage correct au chargement de la page, puis lorsqu’on scroll le texte. Il reste un élément à corriger : quand on redimensionne la page. Il nous suffit de redéclencher le calcul de la hauteur #elastique quand on détecte l’événement $(window).resize(). Notre code devient :

  1.                 $(document).ready(function(){
  2.                         hauteur_elastique();                   
  3.                         $("#contenu").scroll(function() {
  4.                                 hauteur_elastique();
  5.                         });
  6.                         $(window).resize(function(){
  7.                                 hauteur_elastique();                   
  8.                         });            
  9.                 });    

Voilà, le gros du travail est fait, avec un principe très simple et du code javascript/jquery tout aussi simple. Des codeurs avancés pourront certainement rendre le code javascript beaucoup plus compacte, mais j’aime bien conserver un code très simple et très lisible.

Il reste cependant une difficulté à résoudre : à moins de consulter cette page avec Safari ou Chrome, on a un effet de sautillement très disgracieux lors du scroll.

La solution que j’applique : je n’affiche pas l’image directement dans le pavé #image, mais en background du pavé qui contient l’ensemble de la page. Le pavé #image se contente alors de créer l’espace (de hauteur et de la largeur identiques à l’image) pour l’habillage du texte.

On rencontre alors une seconde difficulté : on ne peut pas appliquer l’image en background de #contenu, parce que cet élément est scrollable. Et Internet Explorer se comporte alors d’une façon spécifique : le background se déplace avec le contenu complet de la page et non dans la partie réellement affichable du pavé.

Je fabrique donc, uniquement dans le but de positionner correctement l’image en bas à droite, un pavé supplémentaire (#contenu_image qui contient #contenu).

Mon code est désormais complet :

  1.         <script src="jquery.js" type="text/javascript"></script>
  2.         <script type="text/javascript"><!--
  3.                 function hauteur_elastique() {
  4.                         hpage = $("#contenu").height() + $("#contenu").scrollTop() - $("#image").height();
  5.                         if (hpage < 1) {
  6.                                 $("#elastique").hide();
  7.                         }
  8.                         else {
  9.                                 $("#elastique").show();
  10.                                 $("#elastique").height(hpage);
  11.                         }
  12.                 }
  13.        
  14.                 $(document).ready(function(){
  15.                         hauteur_elastique();                   
  16.                         $("#contenu").scroll(function() {
  17.                                 hauteur_elastique();
  18.                         });
  19.                         $(window).resize(function(){
  20.                                 hauteur_elastique();                   
  21.                         });            
  22.                 });    
  23.        
  24.         --></script>
  25.         <style style="text/css">
  26.                 body {
  27.                         margin: 0px;
  28.                         padding: 0px;
  29.                 }
  30.                 #contenu_image {
  31.                         height: 100%;
  32.                         background: url(image.png) bottom right no-repeat;
  33.                 }
  34.                 #contenu {
  35.                         height: 100%;
  36.                         overflow: auto;
  37.                 }
  38.                 #pave_texte {
  39.                         padding: 20px;
  40.                 }
  41.                 #pave_texte .texte {
  42.                         text-align: justify;
  43.                 }
  44.                 #elastique {
  45.                         width: 5px;
  46.                         height: 150px;
  47.                         float: right;
  48.                         overflow: hidden;
  49.                 }
  50.                 #image {
  51.                         width: 236px;
  52.                         height: 300px;
  53.                         clear: right;
  54.                         float: right;
  55.                 }
  56.         </style>
  57.        
  58. </head>
  59.        
  60. <div id="contenu_image">
  61.         <div id="contenu">
  62.        
  63.        
  64.                 <div id="elastique"></div>
  65.                 <div id="image"></div>
  66.        
  67.                 <div id="pave_texte">
  68.                         <h1>Le titre</h1>
  69.                        
  70.                         <div class="texte">
  71.                                 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, sapien vel feugiat hendrerit, ante felis mollis nunc, eget rutrum sapien arcu et turpis. Proin blandit sapien quis ante ullamcorper eget malesuada mi facilisis. Aenean risus velit, eleifend vitae lacinia nec, varius nec lorem. Aenean nisi urna, faucibus et lacinia a, dictum at erat. Maecenas laoreet eros nec felis tempor ac tempus felis lacinia. Vivamus aliquet semper ullamcorper. Donec ligula nisi, pellentesque non aliquet eget, malesuada nec sem. Sed ultricies arcu ut mauris eleifend pretium. Integer mattis, diam quis ultrices faucibus, lectus diam laoreet lectus, eu rutrum nunc lacus eu enim. Suspendisse potenti. Vestibulum hendrerit dolor a eros fermentum nec consectetur massa congue. Proin ornare rutrum arcu non tempor. Aliquam fermentum nulla et justo porttitor sit amet tristique dolor commodo. Fusce turpis sem, suscipit porttitor euismod eleifend, vehicula vestibulum nisl.</p>
  72.                                 <p>Cras dui erat, vulputate nec dictum vel, commodo id ante. Fusce bibendum varius fermentum. Maecenas lacinia egestas mi vel ultrices. In augue sapien, gravida quis vestibulum porttitor, congue et enim. Aenean condimentum tempus nisi, at vehicula magna luctus non. Nam ultricies urna in purus facilisis non venenatis ligula tincidunt. Quisque porta varius lectus, vitae vestibulum leo commodo nec. Morbi justo neque, ultrices in egestas ut, consectetur sed neque. Maecenas egestas malesuada gravida. Cras eleifend quam accumsan leo sodales viverra. Aliquam erat volutpat. Morbi nec sapien vel orci commodo volutpat nec ut ipsum.</p>
  73.                                 <p>Vivamus nec rutrum est. Curabitur lectus turpis, adipiscing et commodo a, blandit eu nisi. Nulla eget mi id mauris interdum accumsan vel et quam. Morbi sed neque felis. Duis sit amet dolor neque, nec tincidunt magna. Duis iaculis elementum lacus, nec elementum metus vehicula eu. Aenean sed tortor at erat blandit consectetur et vel lectus. Sed ligula nisl, posuere et pretium nec, facilisis ut nisl. Vivamus ultrices suscipit feugiat. Pellentesque eleifend varius lectus et iaculis. In gravida nisl id elit facilisis tempor. Sed eros dolor, fermentum quis aliquet id, ornare bibendum enim. Pellentesque fringilla pharetra sem, vitae interdum tellus varius quis. Sed tempor dignissim risus, vitae mattis quam aliquam in. Mauris facilisis magna a urna ultricies suscipit. Integer semper gravida nibh sed luctus. In hac habitasse platea dictumst. Nulla facilisi. Vivamus ac purus accumsan magna hendrerit ornare.</p>
  74.                                 <p>Praesent porta egestas orci, hendrerit consequat mi posuere non. Donec egestas posuere sapien, nec cursus elit sodales vel. Donec hendrerit mi non tellus luctus ullamcorper. Etiam eget magna et ante convallis pellentesque ut id augue. Curabitur tincidunt, velit a hendrerit aliquam, quam est fringilla purus, non scelerisque velit purus auctor est. Proin elit neque, venenatis quis iaculis et, cursus id dui. Quisque vehicula dignissim egestas. Nam viverra tincidunt eros porta sollicitudin. Cras porta mauris mollis ante bibendum id condimentum leo posuere. Maecenas lacinia pretium vehicula. Nam non metus tortor, quis dictum risus. Vivamus facilisis adipiscing arcu a commodo. Nulla consequat pulvinar risus, eu varius diam gravida sed. In hac habitasse platea dictumst. Etiam eget risus dolor, semper aliquam nisi. In hac habitasse platea dictumst. Aenean elementum hendrerit lacus eu luctus.</p>
  75.                                 <p>Suspendisse porttitor condimentum enim vitae aliquam. Fusce ultricies tristique sem, vel pellentesque mi consequat id. Nunc vulputate vehicula lorem, non gravida dui vulputate a. Nulla euismod ligula et sem luctus fermentum. Mauris sodales est id magna rhoncus molestie. Praesent non felis in ipsum dapibus feugiat. Nulla eget sem a urna dictum interdum. Proin eu metus sed nisl pellentesque eleifend at vel lectus. Mauris bibendum eros et nulla pretium lobortis. Aenean blandit lacus non nulla mollis mollis. Maecenas non ultricies ligula.</p>
  76.                         </div>
  77.                 </div>
  78.        
  79.        
  80.         </div>
  81. </div>
  82. </body>
  83. </html>

En pratique, j’ai encore quelques modifications : la hauteur de #contenu_image n’est pas de 100% de mon écran (je veux afficher un footer et un header), et les solutions purement CSS ne fonctionnent pas avec Internet Explorer 6 (alors que la bidouille Javascript, elle, est totalement compatible, je ne vais donc pas me fâcher avec MSIE 6 juste parce que je dois calculer la hauteur d’un pavé).

J’ajoute donc un petit morceau de script qui calcule la hauteur réelle de #contenu_image en fonction de la hauteur de la fenêtre.

Sous Internet Explorer, la barre de scroll verticale de la fenêtre complète ne disparaît pas : elle est seulement désactivée, et la scrollbar de #contenu apparaît « à l’intérieur » au lieu de bien se positionner à sa place. J’ajoute donc un élément de style pour la compatibilité avec IE 6 et IE 7 :

  1. html, body {
  2.         overflow: hidden;
  3. }

Attention à n’insérer ce genre de bidouille que tout à la fin de vos développements : en effet, il ne faut surtout pas utiliser ce genre de choses pour masquer des éléments « qui dépassent » de votre page — ces éléments devraient être corrigés proprement dans vos feuilles de style —, mais simplement pour ne pas afficher les scrollbar désactivées. Le overflow hidden du body doit jamais servir à masquer la misère d’un code mal fichu (ici, il s’agit seulement de masquer des scrollbar qui sont déjà inactives).

Je passe dans SPIP

Il nous reste à réaliser l’habillage irrégulier. Pour cela, il suffit de supprimer le pavé #image et de le remplacer par la série de div calculés par le filtre image_ragged de SPIP.

  1. <div id="elastique"></div>              [(#LOGO_ARTICLE_NORMAL||image_reduire{0,300}
  2.         |image_ragged{right,5}
  3.         |replace{url(.*),rien.gif})]

Je prends le logo de mon article, je force sa hauteur à 300 pixels, et là-dessus je demande à SPIP de me fabriquer les éléments flottants très fins qui permettent l’habillage irrégulier. Chacun de ces éléments flottants contient (comme pour le #image initial) la séquence clear right et float right (attention à ne pas installer le logo passé par image_ragged à l’intérieur d’un grand pavé tel que #image : sinon on casserait la séquence d’éléments flottants).

Comme j’ai décidé de placer l’image en fond de #contenu_image, je ne dois logiquement pas la réafficher ici, et ne conserver que les div qui fabriquent la forme irrégulière. Or, image_ragged place l’image en fond (background) de chacun des div qu’il fabrique. Le filtre |replace{url(.*),rien.gif} me permet donc de remplacer les images en fond par l’image vide par défaut de SPIP.

Je dois finalement modifier légèrement mon javascript : dans hauteur_elastique, je ne peux plus demander de retirer $("#image").height() à la hauteur de la fenêtre, puisqu’il n’y a plus de pavé #image. Comme j’ai décidé de forcer la hauteur de mon image à 300 pixels, inutile de faire faire le calcul par jQuery, je peux directement indiquer la valeur de mon choix : ici 320 (parce qu’image_ragged ajoute un bloc de 20 pixels en haut de l’image, pour éviter que le texte ne vienne se superposer sur le haut de l’image) :

  1. hpage = $("#contenu").height() + $("#contenu").scrollTop() - 320;

Inconvénients

Il y a deux principaux inconvénients liés à cette méthode.

- Le premier est un problème de lisibilité du texte ; la largeur de chaque ligne de texte qui habille l’image change lorsqu’on scrolle (puisque l’image habillée, elle, ne se déplace pas). On a donc, pendant le scroll, des mots qui changent de ligne en permanence, et c’est très difficile à lire.

Pour limiter les dégâts : n’appliquer l’effet que sur des textes courts et avec des paragraphes pas trop longs (les changements de paragraphes sont plus faciles à retrouver quand la mise en page a changé lors du scroll).

- Vous ne pouvez utiliser aucun élément de type float dans le texte. Même pas des float left. La séquence float right, clear right rejette en effet tous les float en dehors de la page, y compris les éléments flottant à gauche. Pas d’images flottantes, donc, dans le corps de votre article.

Répondre à cet article

4 Messages de forum


Derniers commentaires