Infoforall

8 - Création d'une interface

Nous traiterons ici de la façon de placer précisement et définitivement(au pixel près) les éléments de votre page.

interface finale

Jusqu'à présent, nous avons travaillé avec des éléments placés uniquement en fonction de :

Nous allons voir aujourd'hui comment déplacer les éléments affichés où vous voulez en donnant directement et de façon fixe les coordonnées en x et en y.

Voici les axes de coordonnées utilisés :

les axes x et y

L'avantage est que le placement des éléments est assez intuitif :

Le désavantage est qu'on ne gère pas réellement la taille des écrans.

Nous allons ici créer une interface pour un jeu où il faudra détecter les animaux féroces.

Remarque : il existe également la méthode utilisant les propriétés flex.

L'intéret de la méthode flex est que l'affichage va pouvoir être modifié facilement et automatiquement en fonction de la taille de l'écran.

Le premier désavantage est que le placement n'est pas fixe. Or, parfois, on veut que les éléments soient placés à un endroit précis et pas ailleurs. Pour un jeu par exemple.

Le deuxième désavantage est que l'utilisation de flex n'est pas forcément facile à comprendre.

Par contre, si votre but est d'obtenir un placement dynamique, il va falloir aller voir l'activité sur FLEX un jour.

1 - Première version sans utiliser position

Nous avons 9 animaux, féroces ou non. Nous voudrions pouvoir les afficher selon un regroupement en 3x3 sans utiliation de tableau.

Commençons par voir ce que cela donne en plaçant simplement les images :

ANIMAUX FEROCES

agneau canard chaton ecureuil koala lapin suricate tarentule tigre

On peut voir que les éléments sont tous sauf bien alignés. De plus, si vous modifiez la taille de la fenêtre, vous pourrez constatez que les images changent de place. Pourquoi ?

Rappel : il existe trois types de façon d'afficher une balise :

En display : inline, les éléments sont placés les uns à la suite des autres sur la même ligne et on ne peut pas définir de largueur pour les éléments. Il s'agit par défaut de la balise span, strong, ... Bref, toutes les balises affichant des bouts de texte.

En display : block, les éléments sont placés les uns en dessous des autres : on passe à la ligne avant d'afficher le block et on ne place qu'un bloc sur une 'ligne'. C'est par défaut le cas des balises div, h, p ...

Enfin, il existe un cas intermédiaire : display : inline-block. Dans ce cas, on place les éléments les uns derrière les autres mais ils possèdent néanmoins des attributs height et width. C'est le cas, par défaut, des images.

Comme nous affichons des images, elles sont donc placées les unes derrière les autres.

Voici le code :

<img src="agneau.jpg" alt="agneau" width="259" height="194">

<img src="canard.jpg" alt="canard" width="259" height="194">

<img src="chaton.jpg" alt="chaton" width="275" height="183">

<img src="ecureuil.jpg" alt="ecureuil" width="259" height="194">

<img src="koala.jpg" alt="koala" width="276" height="183">

<img src="lapin.jpg" alt="lapin" width="212" height="238">

<img src="suricate.jpg" alt="suricate" width="225" height="225">

<img src="tarentule.jpg" alt="tarentule" width="260" height="194">

<img src="tigre.jpg" alt="tigre" width="260" height="194">

Comme nous voudrions des cases 'images' de taille identique, nous allons placer chaque image dans des balises div, elles-mêmes contenues dans une div nommée "conteneur".

Voici le code :

<!DOCTYPE html>

<html>

    <head>

        <meta charset="UTF-8" />

        <title>INTERFACE GRAPHIQUE</title>

        <meta http-equiv="content-Language" content="fr" />

        <link rel="stylesheet" href="animaux-feroces.css" />

    </head>

    <body>

        <header>

            <h3>ANIMAUX FEROCES</h3>

        </header>

        <section>

            <div id="conteneur">

                 <div>  <img src="agneau.jpg" alt="agneau" width="259" height="194">  </div>

                 <div>  <img src="canard.jpg" alt="canard" width="259" height="194">  </div>

                 <div>  <img src="chaton.jpg" alt="chaton" width="275" height="183">  </div>

                 <div>  <img src="ecureuil.jpg" alt="ecureuil" width="259" height="194">  </div>

                 <div>  <img src="koala.jpg" alt="koala" width="276" height="183">  </div>

                 <div>  <img src="lapin.jpg" alt="lapin" width="212" height="238">  </div>

                 <div>  <img src="suricate.jpg" alt="suricate" width="225" height="225">  </div>

                 <div>  <img src="tarentule.jpg" alt="tarentule" width="260" height="194">  </div>

                 <div>  <img src="tigre.jpg" alt="tigre" width="260" height="194">  </div>

            </div>

        </section>

        <footer>

            <p>Ici, c'est le footer.</p>

        </footer>

    </body>

</html>

On obtient alors ceci, ce qui n'est pas beaucoup mieux pour l'instant :

ANIMAUX FEROCES v2

agneau
canard
chaton
ecureuil
koala
lapin
suricate
tarentule
tigre

01° Téléchargez le fichier HTML, le fichier CSS et les 9 images. Placez le tout dans un même dossier.

02° Lancer à nouveau l'ensemble avec cette fois les modifications faites au css. Vous devriez avoir quelque chose qui ressemble à cela :

ANIMAUX FEROCES v3

agneau
canard
chaton
ecureuil
koala
lapin
suricate
tarentule
tigre

03° Ouvrir le fichier css dasn Notepad++. Vous pourrez constater que nous y avons inséré quelques régles.

Explications :

On commence par modifier les marges de la balise qui va contenir l'ensemble.

/* Cette première définition permet d'avoir des blocs qui se collent, sans marge et autres */

#conteneur

{

    margin:0px;

    padding: 0px;

    border: 1px solid #660000;

}

Nous allons maintenant modifier la façon dont les balises div contenant les photos vont s'afficher :

#conteneur div {

    display: inline-block;

    margin: 0px;

    padding: 0px;

    width: 300px;

    height: 300px;

    border: 1px solid #777777;

}

Erreur typique : une fois sur deux lorsqu'on m'appele sur ce type d'activité, c'est que l'affichage ne gère pas bien les largeurs. D'où vient souvent problème ? Du fait que vous laissez un espace entre les valeurs et le px qui indique l'unité. Ainsi 300 px ne sera pas compris correctement, là où 300px fonctionnent. Attention aux espaces donc.

Reste la gestion CSS des images. On les transforme en balise block (elles sont initialement en inline-block) et on supprime les marges internes et externes.

#conteneur div img{

    display: block;

    margin: 0px;

    padding: 0px;

}

Comme vous pouvez le voir, c'est mieux mais nous n'avons pas 3x3 images.

04° Rajouter dans votre code HTML quelques balises br (entre les balises div) pour passer à la ligne de façon à avoir 3 images par lignes.

Relancez. C'est mieux mais l'image n'est toujours pas centrée dans la div. Comment faire ?

05° Pour centrer horizontalement, c'est simple, il suffit d'utiliser une marge extérieur automatique : on passe donc de margin: 0px à margin : auto.

#conteneur div img{

    display: block;

    margin: auto;

    padding: 0px;

}

ANIMAUX FEROCES v4

agneau
canard
chaton

ecureuil
koala
lapin

suricate
tarentule
tigre

C'est bien beau, mais ca reste encore mal centré verticalement !

L'une des solutions est d'utiliser le Flex mais nous l'avons déjà vu.

Une autre solution issue du CSS3 : nous allons forcer le début de l'image à descendre de la moitié de l'espace disponible dans la div. Comment ? Avec l'instruction suivante : margin-top: 50%;. J'ai choisi les unités en pourcentage. Cela veut dire qu'on descend l'image de 50% de la hauteur de la div qui contient l'image.

#conteneur div img{

    display: block;

    margin: auto;

    padding: 0px;

    margin-top: 50%;

}

06° Modifier le code CSS des images pour décaler l'image de 50% de la taille de la div.

ANIMAUX FEROCES v5

agneau
canard
chaton

ecureuil
koala
lapin

suricate
tarentule
tigre

Bon, toujours pas top car on sort carrèment l'image de la place disponible. Mais on a bien le début de l'image à 50% de la hauteur de la div.

Il nous reste à remonter les images. De combien ? Et bien, nous aimerions que la moitié de la div corresponde à la moitié de l'image. Il faudrait donc remonter l'image de 50% de sa propre hauteur. Ca tombe bien, il existe une propriété qui permet de faire cela : transform: translateY(-50%).

07° Modifiez une dernière fois le CSS de façon à obtenir l'affichage ci-dessous.

#conteneur div img{

    display: block;

    margin: auto;

    padding: 0px;

    margin-top: 50%;

    transform: translateY(-50%);

}

ANIMAUX FEROCES v6

agneau
canard
chaton

ecureuil
koala
lapin

suricate
tarentule
tigre

On notera qu'avec transform: translateY(-50%), si vous notez 50% cela veut dire 50% de la hauteur de l'image elle-même.

Par contre, avec margin-top: 50%;, si vous notez 50%, cela veut dire 50% de la hauteur de la div qui contient votre image.

Vous auriez pu également noter margin-top: 50px; : on décale alors de 50 pixels.

Ou encore : margin-top: 50vh; où vh veut dire vertical height. On décale alors de 50% de la hauteur de l'écran.

Cette dernière unité peut être très utile si vous voulez adapter votre interface à la place disponible.

08° Réduire la taille de l'écran. Est-ce que cela fonctionne encore ?

Pour imposer la taille du conteneur et éviter le retour à la ligne, il suffit de le signaler via le CSS :.

/* Cette première définition permet d'avoir des blocs qui se collent, sans marge et autres */

#conteneur

{

    margin:0px;

    padding: 0px;

    border: 1px solid #660000;

    borderwidth: 1200px;

}

09° Tester. Cette fois, on gardera la bonne disposition même si l'écran devient trop petit.

Néanmoins, cela ne suprime pas les effets du site infoforall vis à vis des tailles d'écran mais chez vous, cela ne devrait pas poser de problème.

ANIMAUX FEROCES v7

agneau
canard
chaton

ecureuil
koala
lapin

suricate
tarentule
tigre

Ce n'est pas si difficile à comprendre une fois qu'on a compris l'intérêt de chaque ligne de code mais il faut avouer qu'il faut penser à beaucoup de choses.

Nous allons voir maintenant des méthodes de placement plus directes.

2- Avec position: relative

Nous allons voir maintenant une méthode plus directe et préicse pour positonner les éléments dans un élément conteneur.

Imaginons que nous voulions obtenir ceci : un affichage de 800 pixels sur 650 pixels (un carreau correspondant à 50 pixels).

interface voulue

Ainsi le carré bleu commence en (x=50;y=50). Le carré orange commence en (x=300;y=50)...

Avec la gestion habituelle, il est possible de les placer exactement à ses endroits mais cela va demander un certain temps de réflexion (gestion des marges ...).

Nous allons voir comment faire cela plus rapidement avec position: relative.

Le 'relative' veut dire qu'on va pouvoir modifier la position de l'élément relativement à la position 'normale' qu'aurait l'élément.

Voici la partie HTML :

<div id="web080_test7">

    <div id="bleu"></div>

    <div id="orange"></div>

    <div id="vert"></div>


    <div id="rouge"></div>

    <div id="jaune"></div>

    <div id="noir"></div>


    <div id="violet"></div>

    <div id="cyan"></div>

    <div id="gris"></div>

</div>

Regardons ce que donne le positionnement 'normal' dans une div de 800px sur 650px :

Et voici un début de code CSS :

On commence avec la div-conteneur :

#web080_test7{

    margin: 0px;

    padding: 0px;

    border: 1px solid #660000;

    width: 800px;

    height: 650px;

}

Je définis une balise div-conteneur en lui donnant la bonne largeur (800px) et hauteur (650px).

On passe maintenant au CSS commun des div de couleurs contenues dans la div-conteneur. Nous créons des carrés de 150px de côté :

#web080_test7 div {

    display: inline-block;

    margin: 0px;

    padding: 0px;

    width: 150px;

    height: 150px;

    border: 1px solid #777777;

}

Nous pouvons maintenant décrire le CSS de chaque div de couleur, une à une :

#bleu{

    background-color: blue;

    position: relative;

    top: 50px;

    left: 50px;

}

On précise que cette balise aura un positionnement relatif par rapport à sa position normale.

On donne ensuite en pixels le décalage à effectuer à la boite à l'aide de top et left.

Nous aurions également pu donner d'autres points de coordonnées : right pour le bord droit et bottom pour le bord bas. Attention néanmoins : si vous imposez left et right, vous ne pouvez pas en même temps imposer width puisqu'on trouve la largeur en fonction de la position du bord gauche et du bord droit !

Nous aurions également pu donner des valeurs négatives.

#orange{background-color: orange;}


#vert{

    background-color: green;

    position: relative;

    top: 50px;

    left: 50px;

}

#rouge{

    background-color: red;

    position: relative;

    top: 0px;

    left: -50px;

}

#jaune{background-color: yellow;}

#violet{background-color: purple;}

#noir{background-color: black;}

#cyan{background-color: cyan;}

#gris{background-color: grey;}

Ce sont les autres balises div colorées.

Voici le résultat pour l'instant :

Voici une image qui vous permettra de comprendre pourquoi les balises sont positionnées ainsi : on y trace un point corresopndant la position 'normale" du coin supérieure gauche et le trajet jusqu'à la position actuelle.

interface voulue

Comme on le voit, positionner un ou deux éléments de cette façon est possible mais le faire pour la totalité est plutôt délicat. En effet, nous devons d'abord avoir une idée précise de la position de l'élément AVANT modification pour ensuite modifier sa position... Ce n'est pas très intuitif puisqu'il n'existe par d'origine commune de coordonnées.

C'est normal, nous aurions dû utiliser une autre valeur pour cette propriété : position: absolute.

10° Positionner néanmoins les trois premiers carrés correctement avec position: relative par rapport à l'interface voulue. Pour rappel :

interface voulue

3- Avec position: absolute

Cette fois, nous allons pouvoir placer les éléments par rapport à une orgine de coordonnées commune à toutes nos balises.

Une subtilité néanmoins : si la div-conteneur ne possède pas elle-même de propriété position, l'élément possèdant une propriété position: absolute va se positionner par rapport à l'origine de la page elle-même ! Le point (0,0) serait alors le coin supérieur gauche de la page elle-même. Il faut faire extrêmement attention à cette subtilité.

Regardons un code HTML et CSS utilisant ce principe :

<div id="web080_test8">

    <div id="bleu"></div>

    <div id="orange"></div>

    <div id="vert"></div>


    <div id="rouge"></div>

    <div id="jaune"></div>

    <div id="noir"></div>


    <div id="violet"></div>

    <div id="cyan"></div>

    <div id="gris"></div>

</div>

Et pour le CSS :

#web080_test8{

    margin: 0px;

    padding: 0px;

    border: 1px solid #660000;

    width: 800px;

    height: 650px;

    position: relative;

}

11° Cette div possède-t-elle une propriété 'position' ? Dans la mesure où on ne précise rien, comment va-t-elle être positionnée ?

...CORRECTION...

Oui, le css indique ceci : postion: relative

Dans la mesure où on ne donne aucune indication de décalage ensuite, cela veut dire qu'on reste à la position 'normale'.

Cette ligne ne sert qu'à fournir une origine des postions pour les div dans cette div-conteneur.

On retrouve ensuite les données communes des div-carrés colorés :

#web080_test8 div {

    display: inline-block;

    margin: 0px;

    padding: 0px;

    width: 150px;

    height: 150px;

    border: 1px solid #777777;

}

Regardons maintenant les div colorées : les carrés bleu, vert et rouge sont déclarées en position absolue : les indications données sur le coin supérieur gauche va donc correspondre à leurs coordonnées finales dans la div-conteneur. Cette fois, il ne s'agit plus d'un décalage par rapport à leur postion 'normale', mais d'un décalage par rapport à l'origine de la div-conteneur.

#bleu{

    background-color: blue;

    position: absolute;

    top: 50px;

    left: 50px;

}

#orange{background-color: orange;}


#vert{

    background-color: green;

    position: absolute;

    top: 100px;

    left: 50px;

}

#rouge{

    background-color: red;

    position: absolute;

    top: 150px;

    left: 50px;

}

#jaune{background-color: yellow;}

#violet{background-color: purple;}

#noir{background-color: black;}

#cyan{background-color: cyan;}

#gris{background-color: grey;}

Le résultat en image :

12° Vérifier que les coordonnées des trois div bleu, vert et rouge soient bien cohérentes avec le code. Modifier quelques coordonnées pour bien comprendre le principe.

...CORRECTION...

Certaines divs ont la propriété suivante : postion: absolute

Cela veut dire qu'elles seront positionnées par rapport à l'origine choisie. Ici, puisque le div conteneur possède une valeur position : relative, c'est la position (0,0) de la div conteneur qui sera choisie comme origine.

Ainsi, tous les décalages left de 50 px placent les div à la même position horizontale.

13° Modifier le CSS en supprimant la référence postion: relative de la div-conteneur. Que constatez-vous ?

...CORRECTION...

Si la div-conteneur ne possède pas de propriété position, le navigateur remonte le long des div-conteneurs. Comme il ne trouve aucune propriété position, il choisit comme référence le (0,0) de la page elle-même !

Ainsi, la nouvelle référence est simplement le point en haut à gauche de votre page.

14° Modifier maintenant le CSS pour obtenir l'interface voulue depuis le début, à savoir :

4- Les autres valeurs possibles de position

Nous allons voir rapidement deux autres valeurs possibles :

Premièrement, postion: static veut dire que la div ne possède pas en réalité de valeur de position : elle est gérée automatiquement par le navigateur. Pourquoi l'utiliser au lieu de ne rien préciser ? Il est possible que le CSS impose une valeur à position à un ensemble de div via une classe et que vous vouliez uniquement placer certaines d'entre elles de façon "automatique". Attention, une valeur de ce type sur une balise conteneur veut dire qu'elle ne possède pas de propriété position. Attention pour les autres balises contenues dans celle-ci.

Deuxième nouvelle valeur : postion: fixed. Cette fois, vous fixez la balise sur l'écran et elle apparaitra toujours au même endroit même en bougeant la molette de la souris et en faisant dérouler la page. C'est pratique pour les menus de sélections ou autre.

Voici pour le positionnement précis de vos éléments sur vos interfaces graphiques.

Il y a encore deux petites choses que vous pouvez trouvez facilement sur internet, sur W3School par exemple. Aucune explication ici car cela ne concerne pas directement les interfaces.

  • position: sticky qui permet de gérer normalement une balise (en mode relative) mais qui permet de ne pas la faire disparaitre lorsqu'on va trop bas lors du déroulement de la page : on passe alors en static et la balise restera par exemple en haut de page même si vous continuez à faire dérouler la page.
  • On peut gérer quelle div passe devant l'autre en cas de chevauchement avec la propriété CSS z-index (par exemple z-index:-1) où on donne la valeur de la 'couche' sur laquelle on désire placer la div. On peut ainsi préciser qui passe au dessus de quoi.