Accueil

Traduction

Débuter en programmation web - sommaire

Débuter en programmation web - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

HTML & CSS : Mise en forme du contenu

Dans ce chapitre je vais vous montrer comment améliorer la présentation du contenu grâce au CSS.

Pour les nouveautés notables apportées par la version 5 de HTML et la version 3 de CSS, je vous renvoie aux tutos "HTML5" et "CSS3" dans le même site. En effet je ne vais pas rentrer dans les détails, je me contente d'évoquer les grands principes dans la mise en forme.
HTML version 5
CSS version 3

Principes du CSS

Deux grands principes gouvernent le CSS : héritage et cascade.
Ces deux notions doivent être parfaitement maitrisées.

Héritage

L'héritage signifie que tout élément HTML enfant va hériter des styles de son parent sauf s'il s'agit de de propriétés non héritables (qui sont peu nombreuses).

Connaissant le principe de l'héritage les feuilles de style peuvent être très succinctes !

Exemple

Extrait d'une feuille de style :

	body {font-family : arial ; font-size : 12px ;}
	h1,h2,p,a, ul,ol,li {font-family : arial ; font-size : 12px ;}

La deuxième règle de style est totalement inutile !
En effet les propriétés font-family & font-size sont héritables. Donc ce qui s'applique à BODY s'applique à ses descendants (les balises qui sont contenues dans BODY : balises titres, balises de liste, balises pour tableaux, ...).
Attention certaines propriétés (peu nombreuses) ne peuvent être héritées par les descendants.
C'est le cas des propriétés de bordurage, de marges (internes et externes), de remplissage donc concrètement les raccourcis border, margin, padding, backgroud et toutes les propriétés préfixées par ces mots telles : margin-top, ... padding-left, ... border-style, ... background-image, ...

Cascade

Le CSS peut avoir plusieurs sources :

Il peut y avoir un conflit pour une ou plusieurs propriété concernant un élément.
Par exemple plusieurs règles de style définissent une couleur de texte différente pour la même balise.

Exemple

Par défaut, le navigateur affiche le texte en noir sauf les liens (balise A) qui sont en bleu.
Extrait de la feuille de style externe : p {color : navy; }
Extrait de la feuille de style interne : p {color : olive; }
Une instruction dans la partie BODY : < p style ="color : purple;"> Je porte une soutane violette ! <p >
Le texte "je porte une soutane violette !" sera t-il en noir ou bleu marine ou olive ou encore en violet ?

Retenez : la règle en ligne est prioritaire sur la règle interne qui elle-même est prioritaire sur la règle externe qui elle-même est prioritaire sur la valeur par défaut. C'est ce qu'on appelle "la cascade".

Exercice sur cascade et héritage

Je vous communique le code d'une page avec feuille de style interne et lien vers une feuille de style externe.

Le code de la page (extraits)

Notez le lien vers une feuille de style externe.
Notez que dans la feuille de style interne, certaines propriétés ont pour valeur : none.

Le contenu de "feuille_externe.css"

Travail à faire

Remplissez le questionnaire ci-dessous.

Correction

Voir la fin du chapitre !

Les pseudo classes

Les pseudo-classes sont :active & :hover
Grâce aux pseudo-classes du CSS on peut réaliser des effets visuels simples.

Exemple

Une page avec des images et un tableau.

La feuille de style

Notez des sélecteurs tels img:active & h1:hover

Le code HTML de la page (partie BODY)

Le rendu dans un cadre :

Nouveautés du code HTML

Dans un premier temps je vous ai dit que pour construire un tableau de données il fallait utiliser quatre conteneurs : TABLE contenant des balises TR ; conteneurs TR contenant des balises TH ou TH.

Ces quatre conteneurs sont facultatifs mais facilitent la mise en forme du tableau via le CSS.

<a href = "#" ... : si pour la balise A, la valeur de l'attribut href est # cela veut dire retour vers le haut de la même page.

Analyse de la feuille de style

Il y a énormément de nouveautés dans cette feuille de style :
Je commente uniquement les règles de style avec des nouveautés.

* { font-family : sans-serif ; font-size : 20px; text-decoration : none ; }  : la valeur de la propriété font-family peut être un nom de police ou une famille de police ;sans-serif est une famille de police. Donc ici le navigateur va afficher le texte avec une police sans empattement installée sur le PC (Arial en général). C'est une solution beaucoup plus souple !
Rappel : Times New Roman est une police avec serif c'est à dire avec empattements alors que Arial est une police sans serif c'est à dire sans empattements.
Text-decoration : none : pour toutes les balises les surlignage et soulignage sont supprimés. Donc les liens hypertexte (balise A) ne seront plus soulignés.

body { width : 90% ; border : 1px solid black ; margin : 20px auto ; } : dans le cadre du "responsive web design" (adaptation de la page à tous types d'écrans) la largeur de la page est exprimée en % de la largeur de l'écran. je n'en dis pas plus pour l'instant.
La méga propriété margin peut être suivie de 2 valeurs pour marges verticales et horizontales.
Retenez la syntaxe : margin : verticale horizontale
Il existe aussi la syntaxe : margin : haute droite bas gauche

img { display : block ; width : 300px ; opacity : 0.5 ; } : les images deviennent des éléments "block" (saut de ligne avant et après) avec une largeur de 300 pixels et sont à demi transparentes.
la valeur opacity est comprise entre 0 (image transparente) et 1 (image complètement opaque).

img.deforme {height : 100px;}  : si on applique la classe deformee à une image celle-ci alors affichée avec les dimensions 300 par 100 c'est à dire un rapport 3 sur 1.
Il y a en effet deux règles de style qui s'appliquent alors : img {width : 300px;} et img.deforme {height : 100px ;}. Or les trois images ont pour dimensions d'origine 800 par 600 donc un rapport 4/3.
La règle de style concernant la classe "deforme" est mal écrite. Il aurait fallu écrire : img.deforme{height:100px ; width : auto;} . Ce qui veut dire que dans ce cas la largeur est recalculée en fonction de la hauteur pour qu'il y ait respect des proportions.

img:active {visibility : hidden; }: durant le clic l'image cliquée devient invisible mais les éléments HTML situés en dessous ne remontent pas ; l'emplacement est réservé.
:active est une pseudo classe qui peut aussi être associée à n'importe quelle balise.

h1 {text-align : center ; font-size :150% ; text-transform :uppercase ; }: la propriété text-transform avec la valeur uppercase convertit le texte en majuscules.
Moralité : lorsque vous saisissez le texte ne tapez jamais directement en majuscules car vous vous priveriez des lettres majuscules accentuées.

h1:hover , a:hover {color: red; text-decoration : underline overline ; } : si survol d'une balise H1 ou A alors le texte de l'élément devient rouge avec soulignement et surlignement.
Certains propriétés CSS peuvent être suivies de plusieurs valeurs. On dit que ce sont des méga-propriétés. Pensez aussi à margin : haut droite bas gauche.

p{margin : 10px ; } : remplace avantageusement 4 propriétés (margin-top :10px; margin-bottom :10px ; margin-left :10px ; lmargin-right :10px;)

p:first-line{font-weight : bold ; font-style : italic ; } : la première ligne du texte balisé par P est en gras et en italique

p:first-letter {font-family : serif ; font-size : 200% ; } : la première lettre du texte balisé par P sera une lettrine ; taille de 40px (200 % de 20px) et la lettre aura des empattements (police avec serif telle TNR (Times New Roman)

:first-line et :first-letter sont aussi des pseudo-classes.

table {width :80% ; } : les tableaux de la page auront une largeur de 80% mais non pas de l'écran mais de la page ! En effet TABLE est "descendant" de BODY donc la largeur est exprimée en % de celle de son container.

caption {text-align :center ; font-weight : bold; } : la légende de chaque tableau sera centrée horizontalement dans sa boite et aura de la graisse

thead {background-color : grey ; opacity : 1;} : l'en-tête de chaque tableau aura comme couleur de fond un gris opaque.

tr {height : 40px ; }  : la hauteur de chaque ligne des tableaux ne sera pas auto (hauteur ajustée au contenu) mais toujours 40 pixels. Par défaut le texte d'une cellule de tableau est toujours centrée verticalement dans sa cellule.

td {padding-left :5px ;} : ne pas confondre margin (marges extérieures à la bordure) avec padding (marges intérieures à la bordure) .
Grâce à une marge interne gauche le texte contenu dans une cellule balisée par TD ne colle pas à la bordure gauche.

td.droite {text-align : right ; padding-right : 5px ;} : classe droite spécifique au conteneur TD. Par défaut dans les cellules balisées par TD le contenu est aligné à gauche. Or pour faciliter l'addition de la colonne les montants doivent être alignés à droite (mais sans coller à la bordure droite).

tbody {background-color : grey ;opacity : 0.5;} : le corps du tableau aura comme couleur de fond un gris clair obtenu en appliquant une certaine transparence à un gris soutenu. Il y avait une autre solution en utilisant une seule propriété : {background-color : lightgrey ;} ou {background-color : rgb(190,190,190) ;}

Gestion du débordement

Dès qu'une boite a une taille fixe son contenu peut éventuellement déborder ...

Exemple avec bug

Le code la page (extraits) :

Le rendu :

Trois boites ; chacune contenant un texte en latin.

C'est la catastrophe ; le texte déborde de sa boite et recouvre le texte de la boite suivante.
De plus mais c'est moins grave, le titre n'est pas centré verticalement dans sa boite.

Mais au fait pourquoi le débordement ?
Il y a une propriété CSS overflow dont la valeur par défaut est visible ce qui veut dire que si il y a "surplus" (contenu dépassant le contenant) alors ce "surplus" est quand même affiché et déborde de son conteneur.

Les nouveautés CSS dans la feuille de style

*{font-family :cursive ; font-size : 14px ;} : il y a trois familles de police : serif, sans-serif et cursive
Les polices cursives sont celles qui imitent l'écriture manuscrite.

h1{height : 50px ; font-family:arial } : la valeur par défaut de la propriété height est auto ; c'est à dire que la hauteur est ajustée au contenu. Ici la boite H1 aura une hauteur de 50 pixels quelque soit le contenu. Pour que le titre ne s'affiche pas en cursive il faut procéder à une rupture d'héritage c'est à dire redéfinir la police à utiliser pour le sélecteur H1 car sinon H1 hérite de BODY qui lui même hérite de *

div {height: 150px ; border : 1px dashed red ;} : DIV est une balise de type block très utilisée pour créer de grandes zones dans la page. Ici chaque boite DIV sera bordurée par un trait discontinu (dashed) rouge. Chaque boite DIV aura toujours une hauteur de 150 pixels quelque soit le contenu ...
Rappel : valeur par défaut de la propriété height est auto (ajustement de la hauteur de la boite au contenu).

p {text-indent : 50px ; text-align : justify ; margin-left : 5px ; margin-right :5px ;} : retrait de première ligne (indentation) de 50 pixels ; justification du texte ; marges gauches et droite de 5 pixels pour que le texte ne colle pas aux bordures de la balise parente (DIV).

p:first-line {font-variant : small-caps ; } : la première ligne de chaque paragraphe sera en petite majuscules.
Ne confondez pas avec text-transform : uppercase ; : majuscules normales.

Version correcte

Le rendu dans un cadre :

Le titre de niveau 1 est désormais parfaitement centré verticalement dans sa boite.

Dans chaque DIV le "surplus" est masqué (donc il n'y a pas de débordement) mais dès que la boite est survolée par la souris (ou le doigt) elle s'agrandit en hauteur pour afficher tout son contenu.

On s'est contenté d'ajouter trois règles de style.

Les ajouts dans la feuille de style

Expliquons ces ajouts !

h1 {line-height : 50px ; } : un texte est toujours centré verticalement dans sa ligne. Donc si la ligne unique d'un texte a la même hauteur que la boite qui la contient alors le texte sera de facto centré verticalement dans sa boite.

Attention sur un écran de tablette ou smartphone le titre va tenir sur 2 lignes donc une hauteur totale de 100px. Le titre va déborder de son conteneur (H1)!
Je ne vous donne pas la solution pour l'instant mais sachez qu'elle existe : les medias queries !

div {overflow :hidden ; } : signifie que l'éventuel "surplus" de texte (contenu dépassant le contenant) est masqué.

div:hover {height :auto ; } : si survol de la boite par la souris la hauteur de celle-ci s'adapte au contenu !

Positionner les images

Le code de la page (extraits)

Le rendu dans un cadre :

Les images de cette page sont affichées selon deux méthodes totalement différentes.
Les deux premières s'affichent avec une largeur de 400px et sont centrées horizontalement dans la page.
Les deux suivantes sont positionnées à gauche dans leur boite DIV.
Notez que les deux premières sont "enfants" de body et les deux suivantes sont "enfants" de DIV !

Nouveautés dans le code CSS

* {font-family : tahoma, calibri, arial ; ... } : si le navigateur ne trouve pas la police tahoma il va utiliser calibri, si il ne trouve pas calibri il va utiser Arial, etc.

h1{height : 50px ; line-height : 50px ; ... }: centrage vertical du titre dans sa te. Attention ça suppose que le titre tient sur une seule ligne sinon débordement du titre de H1. Je rappelle que ce risque est réel sur des petits écrans ...

body img {display : block ;... } : une image "enfant" de BODY est transformée en élément "bloc" pour pouvoir appliquer le centrage horizontal (margin_left / margin-right à auto).

div {height : 200px ; overflow : auto ; } : affichage éventuel d'une barre de défilement vertical dans chaque boite DIV pour pouvoir lire le texte initialement masqué.

div img {float : left ; margin :10px;}: une image contenue dans un DIV "flotte" à gauche dans son conteneur sans coller aux bords (marge de 10px ).

Astuces HTML

Dans cette partie je vais évoquer la balise double SPAN ainsi que les entités de caractère.

Le code de la page (extraits)

Le rendu dans un cadre :

Remarques :
Trois boites avec un fond gris clair. Dans les deux premières une image positionnée en haut à droite.
Une lettrine en début de chaque paragraphe.
Dans les deux premières boites le mot important est affiché en gras souligné.
Dans la troisième boite une instruction HTML qui n'est pas interprétée par le navigateur mais simplement affichée …
En dessous une image plus grande que les deux précédentes et centrée.
Sous l'image un clavier tactile … Ce clavier tactile c'est en fait un tableau (3 par 3). Sur les 9 cellules 4 seulement sont remplies avec une entité de caractère qui affiche une flèche. Les cellules vides n'apparaissent pas.

Les nouveautés présentées

Dans le code HTML nous avons des mots commençant par le caractère "&" et se terminant par ";".
Ainsi nous avons l'instruction suivante :

Dans cette instruction nous avons utilisé deux entités de caractère qui représentent respectivement les symboles < et > !
Donc si vous remplacez les chevrons par leur entité de caractère ça ressemble à une instruction HTML mais ça n'en n'est plus une pour le navigateur qui se contente donc d'afficher le texte (mais ne l'interprète pas)!

Il y a aussi une autre instruction HTML étrange ...

Cela signifie la fusion des trois cellules de la ligne en une seule. Donc le tableau comprend trois cellules par lignes sauf pour la première ligne (une seule cellule).

Encore une instruction bizarre ...

Sens : la deuxième ligne du tableau il y a trois cellules dont 2 vides et la cellule non vide contient une entité de caractère qui afficher un symbole (flèche vers le haut).

A propos des entités de caractère

Une entité de caractère permet d'insérer dans une page web certains symboles et lettres accentuées. Supposons que vous vouliez insérer le symbole € mais que le clavier ne dispose pas de cette touche ; il suffit de taper en un seul mot(sans espace) : "&" puis "euro" puis ";"

Un entité de caractère commence toujours par "&" et se termine toujours par ";"
Donc quelques entités :

Certains développeurs Web utilisent aussi les entités de caractère pour représenter les lettres accentuées.
Sachez que si par étourderie (ou ignorance) vous avez encodé en Unicode une page qui est lue avec le système ANSI ou vice-versa les lettres accentuées vont apparaitre de façon bizarre ...
Par contre si les lettres accentuées sont représentées par leur entité de caractère l'affichage sera toujours correct !
Cette notion de système d'encodage (ANSI, UNICODE) sera évoquée un peu plus loin.

Nouveautés CSS

Encore beaucoup de nouveautés dans la feuille de style !

p:first-letter {font-family : serif ; font-size :300% ; } : la première lettre de chaque paragraphe sera une lettrine.

table { empty-cells : hide ; border-spacing : 10px ;} : les cellules vides d'un tableau sont masquées ; espacement entre les bordures de cellules : 10px (par défaut : 1px).

div img {width : 100px ; float : right ; margin : 10px ; } : une image contenue dans un DIV se positionne à droite dans sa boite sans toucher le bord de celle-ci (marge de 10 pixels).

tr {height: 100px ; } : hauteur de chaque ligne d'un tableau : 100 pixels.

td {font-size : 40px ; text-align : center; font-weight : bold ; color : white ; border : 1px solid black ; background : grey ;} : ainsi les flèches (contenues dans des cellules délimitées par TD) apparaissent centrées en blanc gras sur fond gris foncé.

Les balises génériques de HTML

span et div sont des balises génériques (aucune mise en forme par défaut).
Mais span est de type "inline" alors que div est une balise générique de type "block".
La balise span est très utilisé pour mettre en forme une fraction de texte dans un paragraphe. Par exemple pour souligner une fraction de texte il suffit d'écrire : < span class ="souligne" > texte ici souligné </span>
Et bien sûr il doit y avoir une règle de style qui définit la classe : .souligne{text-decoration :underline; }

Arrière plan d'une boite - CSS et tableaux HTML

Le code de l'exemple (extrait)

Le rendu :

Une boite avec en fond une image.
Deux tableaux avec des cellules très hautes.
Dans le premier tableau les bordures contiguës sont fusionnées alors qu'elles sont bien espacées dans le deuxième.
Dans le premier tableau le texte contenu dans chaque TD est aligné verticalement haut alors que dans le deuxième tableau le texte contenu dans chaque TD est aligné verticalement bas.

Analyse de la feuille de style

la boite DIV a pour fond une image et on demande que l'image s'adapte à la taille de la boite avec la propriété background-size : cover.

th, td {border : 1px dotted black ; } : bordures de cellules larges de 1px en pointillés (dotted) et noir.

.tableau1{border-collapse : collapse ; } : l'appel de la classe tableau1 se traduit par la fusion des bordures contigües dans le tableau. Valeur par défaut de border-collapse : separate (pas de fusion).

.tableau2{border-spacing : 10px ; } : l'appel de la classe tableau2 se traduit par un espacement de 10px entre les bordures. Valeur par défaut de border-spacing : 1px

.tableau1 td{vertical-align : top ; } : les cellules TD contenues dans un tableau affecté de la classe tableau1 verront le texte aligné verticalement en haut. Valeur par défaut de la propriété vertical-align : middle (centrage vertical dans la cellule).

.tableau2 td {vertical-align :bottom ; }
Les cellules TD contenues dans un tableau affecté de la classe tableau2 verront le texte aligné verticalement en bas.

Plusieurs boites de front ! Comment ?

Faut-il rappeler que par défaut les boites d'une page se positionnent les unes en dessous des autres. C'est le mode de positionnement normal ou flux normal des éléments de type "block".
Donc dès que vous voulez mettre plusieurs éléments "block" côte à côte vous devez utiliser une technique de positionnement !

Paradoxalement la propriété CSS position avec ses différentes valeurs : absolute, fixed, relative est rarement utilisée pour placer de front plusieurs boites ...

Si vous voulez que plusieurs boites se positionnent côte à côte dans leur conteneur parent il faut que la somme de leur largeur ne dépasse pas celle du parent.
Attention la largeur totale d'une boite peut être supérieure à celle indiquée par la propriété width ; il faut ajouter à la largeur exprimée par width les marges gauche et droite externe et interne ainsi que les bordures gauche et droite.

Exemple

Le code HTML commun aux différentes solutions

BODY contient trois grandes divisions : HEADER, SECTION, FOOTER.
La boite SECTION contient à son tour deux boites : NAV, ARTICLE.
Les boites NAV et ARTICLE sont donc "enfants" de SECTION et doivent être de front.

Le code CSS commun aux différentes solutions

Pour positionner les images dans les différentes boites et formater les titres.

La propriété float est en principe destinée à positionner (à gauche ou à droite) un élément "inline" dans son conteneur. Mais dans la pratique elle est très utilisée pour positionner de front plusieurs grandes divisions de la page.

Les deux boites "enfants" de SECTION doivent être de front.
Il faut donc que la somme de leur largeur ne dépasse pas celle de SECTION.
La boite NAV doit "flotter" à gauche et la boite ARTICLE doit "flotter" à droite.
De plus méfiez vous, si pour ces boites vous avez défini des marges gauche et droite la largeur totale est supérieure à celle indiquée par la propriété width d'où l'importance de supprimer toutes les marges (internes et externes) par défaut avec l'instruction * {margin :0 ; padding :0;}

Le rendu dans un cadre :

Deuxième solution : display :inline-block

Une autre technique consiste à transformer les éléments NAV et ARTICLE en "inline-block" c'est à dire des boites qui par défaut se positionnent côte à côte si il y a de la place bien sûr !

Attention si les éléments "inline-block" n'ont pas la même hauteur ils s'alignent verticalement par rapport à la base. Il faut donc forcer l'alignement vertical par le haut avec vertical-align : top.

La feuille de style

Les boites HEADER, NAV, ARTICLE,FOOTER sont désormais des éléments "inline-block".
Il faut toujours éviter que les boites ne se collent d'où certaines marges externes.
Attention la largeur totale de ARTICLE est 70% : 69% + 1% de marge gauche.

Le rendu dans un cadre :

Troisième solution : display flex

Enfin la version 3 de CSS apporte une solution simple de mise en page : l'outil flexbox !
Dans notre exemple il suffit de transformer la balise SECTION (qui a pour enfants NAV et ARTICLE) en "flex_container" : section {display : flex; }
Grâce à cette simple règle les boites "enfants" de SECTION vont se positionner côte à côte !

La feuille de style

SECTION est désormais un "flex-container" et ses boites "enfants" (article & nav) des "flex-items".

Le rendu dans un cadre :

Dans le tutoriel CSS (dans le même site) il y a tout un chapitre sur les nouvelles techniques de positionnement proprosées par CSS3.

Exercice sur la cascade et l'héritage - solution

Le rendu dans le navigateur :

La page n'a pas de bordure mais un fond de couleur "pink".
Les titres n'ont pas de couleur de fond mais une bordure.
Un titre affecté de la classe 'special' : fond gris ; texte en blanc ; pas de bordure.
Couleur de texte pour une balise P : "navy".
Donc pour la même propriété la règle interne prioritaire sur la règle externe.
Le texte du paragraphe affecté de la classe 'important' : rouge avec graisse.
Donc pour une même propriété la classe est prioritaire sur la règle générale.

Attention ne croyez pas que les enfants de BODY héritent de "background : pink" ; leur fond est rose car la valeur initiale de la propriété background_color est "transparent / none".
Par contre ils héritent des propriétés color, font-size.