Exercice HTML : DHTML  

Thème

Positionnement absolu d'éléments dans une page Web, sans recourir à des tableaux (technique alourdissant considérablement le code source de la page).

Principes de base

Le DHTML (Dynamic HTML) n'est pas à proprement une extension au langage HTML (il n'existe pas de norme DHTML à part entière). C'est l'association d'un ensemble de techniques permettant le développement de pages HTML plus interactives, c'est-à-dire dont le contenu peut être modifié par des évènements (mouvement de la souris, survol d'un élément par le curseur...) après que la page ait été chargée. Ces différentes techniques sont : La technique des feuilles de style (CSS1 et 2) n'étant implémentée qu'à partir de la version 4 des logiciels Netscape, Internet Explorer et Opera (et même partiellement seulement), les pages utilisant les techniques DHTML ne s'afficheront pas correctement sur des navigateurs antérieurs. D'autre part, l'implémentation du modèle DOM n'étant pas identique sur Netscape et IE, la programmation JavaScript devra prendre en compte ces différences (dédoublement partiel du code...) pour que le résultat soit le même sur ces 2 navigateurs.

Le DHTML introduit la notion de couches (calques, layers) pour positionner de façon absolue les éléments dans la fenêtre du navigateur. Mais avant que CSS2 ne soit défini :

Pour définir des couches et les positionner dans le navigateur, la "technique correcte" (i.e. fonctionnant sous Netscape>=4, Internet Explorer>=4 et Opera>=4) consiste à :
    - utiliser, à choix, l'une des 2 balises-conteneur <SPAN> ou <DIV>
    - associée aux propriétés de positionnement CSS2 : position: absolute; left: pixelspx; top: pixelspx;
Ce positionnement s'exprime en général en pixels de façon absolue à partir de l'angle supérieur gauche de la fenêtre du navigateur (marges left et top).

Les couches peuvent se superposer les unes par dessus les autres (et donc se masquer), selon l'ordre dans lequel elles sont définies. À moins que l'on utilise encore la propriété z-index: numéro spécifiant un ordre de superposition de couche ; dans ce cas, les couches d'un numéro donné masqueront les couches de numéro inférieur, quel que soit l'ordre dans lequel elles sont définies dans le fichier HTML. Le z-index des éléments normaux de la page est 0.

Les éditeurs HTML évolués permettent de "dessiner" des calques de façon totalement WYSIWYG, par exemple l'outil [Dessiner un calque] de Macromedia Dreamweaver (outil qui, selon ce que l'on aura spécifié dans Édition>Préférences>Calques, fera usage du conteneur <SPAN> ou <DIV>).

L'animation des éléments s'effectue ensuite en modifiant leurs propriétés CSS (position, hauteur, largeur, z-index...) à l'aide de JavaScript en fonction des évènements utilisateur (clic souris, déplacement curseur...). L'accès aux containers <DIV ID=ident> s'effectue de la façon suivante :

Pour illustrer ces possibilités d'animation par JavaScript, voir les exemples animation, yeux et flocons et étoiles.

Netscape 4 possède un bug qui fait que les objets perdent leur positionnement lorsque l'utilisateur change la taille de la fenêtre du navigateur. Pour cette raison, il est conseillé de faire recharger automatiquement la page chaque fois que la fenêtre est redimensionnée, ce que l'on réalise avec le code JavaScript suivant (de Macromedia) dans la partie <HEAD> ... </HEAD> de la page :

    function reloadPage(init) {
      if (init==true) with (navigator) {
        if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
          document._pgW=innerWidth;
          document._pgH=innerHeight;
          onresize=reloadPage;
        }
      } else if (innerWidth!=document._pgW || innerHeight!=document._pgH) location.reload();
    }
    reloadPage(true);

Balises et propriétés CSS2

Selon que l'on définit les attributs de positionnement dans une feuille de style ou directement dans les balises <SPAN> ou <DIV>, on peut donc envisager les 2 modes d'écriture suivants :

1) Positionnement via feuille de style CSS2

<HEAD>
  ...
  <STYLE TYPE="text/css">
  <!--
    #id1    {position: absolute; left: ...px; top: ...px; }
    #id2    {position: absolute; left: ...px; top: ...px; }
    SPAN.t1 {font-size: xpt; font-family: ...; font-weight: ...; color: ...; }
  --> 
  </STYLE>
  ...
</HEAD>
<BODY>
...
<SPAN ID="id1">
   <IMG SRC="image">
</SPAN>
<SPAN ID="id2" CLASS="t1">
   Texte s'affichant par-dessus la photo...
</SPAN>
...
</BODY>

2) Attributs de style/positionnement CSS2 dans les balises <SPAN> ou <DIV>

<BODY>
...
<SPAN STYLE="position: absolute; left: ...px; top: ...px; ">
   <IMG SRC="image">
</SPAN>
<SPAN STYLE="position: absolute; left: ...px; top: ...px; ">
   <FONT COLOR=... FACE=... SIZE=...><B>Texte s'affichant par-dessus la photo...</B></FONT>
</SPAN>
...
</BODY>

Remarques

Références

Donnée de l'exercice

Réalisez la page illustrée par la figure ci-dessous superposant une image, du texte un graphique de type histogramme. Indications :

Corrigé de l'exercice

Vous pouvez afficher ici le résultat de la première et de la seconde solution de cet exercice. Vous verrez qu'en ce qui concerne la barre verte on fait usage d'un gif-animé (p.ex. pour attirer l'attention du visiteur) !

1ère solution : positionnement via feuille de style CSS2

<HTML>
<HEAD>
  <TITLE>Exercice DHTML solution 1</TITLE>
  <STYLE TYPE="text/css">
  <!--
    BODY {background-color: #ffeedd}
    #photo  {position: absolute; left:  40px; top:  60px; z-index: 1; }
    #titre  {position: absolute; left: 100px; top:  80px; z-index: 2; }
    #histo1 {position: absolute; left: 150px; top: 200px; }
    #histo2 {position: absolute; left: 150px; top: 240px; }
    #histo3 {position: absolute; left: 150px; top: 280px; }
    .t1 {font-size: 20pt; font-family: verdana; font-weight: bold; color: yellow; }
    .t2 {font-size: 16pt; font-family: courier; font-weight: bold; }
  --> 
  </STYLE>
</HEAD>
<BODY>

<SPAN ID="titre" CLASS="t1">
   Destinations préférées
   <!-- ce texte ne sera pas masqué par l'image ci-dessous s'affichant après lui,
        car son z-index est supérieur à celui de l'image ! -->
</SPAN>

<SPAN ID="photo">
   <IMG SRC="ocean.jpg">
</SPAN>

<SPAN ID="histo1" CLASS="t2">
   <FONT COLOR="red">Afrique  25% </FONT>
   <IMG SRC="pixel_rouge.gif" WIDTH="100" HEIGHT="10">
</SPAN>

<SPAN ID="histo2" CLASS="t2">
   <FONT COLOR="lime">Amérique 45% </FONT>
   <IMG SRC="pixel_vert.gif" WIDTH="180" HEIGHT="10">
</SPAN>

<SPAN ID="histo3" CLASS="t2">
   <FONT COLOR="blue">Asie     30% </FONT>
   <IMG SRC="pixel_bleu.gif" WIDTH="120" HEIGHT="10">
</SPAN>

</BODY>
</HTML>

2ème solution : attributs de style/positionnement CSS2 dans les balises <SPAN> ou <DIV>

Pour varier un peu, dans cette seconde solution :
on a inclu le code JavaScript qui recharge la page lorsque l'on redimensionne la fenêtre du navigateur Netscape 4 (en raison du bug de ce navigateur)
remarquez comment on a imbriqué les éléments qui prennent place dans l'image dans le conteneur de l'image afin qu'ils soient solidaires de celle-ci (positionnement absolu de ces éléments non pas par rapport à l'angle supérieur gauche de la fenêtre, mais par rapport à l'angle supérieur gauche de l'image).

Dans la partie <HEAD> :

  <SCRIPT LANGUAGE="JavaScript">
  <!--
    // Reloads the page if Netscape Navigator 4 Window is resized (Macromedia)
    function reloadPage(init) {
      if (init==true) with (navigator) {
        if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
          document._pgW=innerWidth;
          document._pgH=innerHeight;
          onresize=reloadPage;
        }
      } else if (innerWidth!=document._pgW || innerHeight!=document._pgH) location.reload();
    }
    reloadPage(true);
  // -->
  </SCRIPT>
Dans la partie <BODY> :
<SPAN STYLE="position: absolute; left:  40px; top:  60px;">
   <IMG SRC="ocean.jpg">

   <SPAN STYLE="position: absolute; left: 60px; top:  20px;">
      <FONT COLOR="yellow" FACE="verdana" SIZE="6"><B>Destinations préférées</B></FONT>
   </SPAN>
   
   <SPAN STYLE="position: absolute; left: 110px; top: 140px;">
      <FONT COLOR="red" FACE="courier" SIZE="5"><B>Afrique  25% </B></FONT>
      <IMG SRC="pixel_rouge.gif" WIDTH="100" HEIGHT="10">
   </SPAN>
   
   <SPAN STYLE="position: absolute; left: 110px; top: 180px;">
      <FONT COLOR="lime" FACE="courier" SIZE="5"><B>Amérique 45% </B></FONT>
      <IMG SRC="pixel_vert_clignotant.gif" WIDTH="180" HEIGHT="10">
   </SPAN>
   
   <SPAN STYLE="position: absolute; left: 110px; top: 220px;">
      <FONT COLOR="blue" FACE="courier" SIZE="5"><B>Asie     30% </B></FONT>
      <IMG SRC="pixel_bleu.gif" WIDTH="120" HEIGHT="10">
   </SPAN>

</SPAN>


Exercices HTML © J.-D. Bonjour / ENAC-IT1, EPFL / Révision 17.3.2002