Propriétés de base en CSS

Ici, on parle de taille, de couleur, de typographie, de marge et de positionnement. Ces éléments de base de CSS nous permettront d'avancer sur notre projet zombie.

Auteur :
Jonathan Marco
Difficulté :
Initiation au rêve (débutant)

Bienvenue les cadettes et le cadets ! Dans ce chapitre, nous allons parler de taille, de couleur, de police de caractères, de marge et de positionnement. Ces éléments de base de CSS nous permettront d'avancer sur le style du header de notre projet zombie.

L'inspecteur

Pour ouvrir l'inspecteur :

  • PC : F12 ou Mac : ⌘ + ⌥ + I
  • Avec la souris : clic droit + Inspecter

Dans l'inspecteur, on y retrouve, entre autres, le HTML et le CSS. Il permet de déboguer le CSS en vérifiant les éléments qui sont appliqués et ceux qui ne le sont pas, en voyant d'où viennent certaines marges ou en testant en direct les changements de certaines valeurs CSS.

Mise en place du projet

Création des fichiers index.css et style.css dans le dossier assets/css. Le premier servira pour le code spécifique à la page index.html, le second au code qui sera commun aux différentes pages, comme la nav et le footer.

Ajout des link et d'id sur les éléments parents dans le index.html

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8"/>
    <title>RZ</title>

    <link rel="stylesheet" href="assets/css/style.css"/>
    <link rel="stylesheet" href="assets/css/index.css"/>
</head>
<body>
    <header id="main_header">...</header>
    <section id="main_section">...</section>
    <footer id="main_footer">...</footer>
</body>
</html>
L'ordre des link n'est pas anodin ! Le fichier spécifique à la page index.css est mis en-dessous pour profiter du système de cascade du CSS (cf. : Mes débuts en CSS).

Les commentaires en CSS

/* Commentaire*/

Ils peuvent être utilisés pour mettre des annotations dans votre code pour se rappeler certaines choses ou, comme dans notre projet, pour séparer le fichier *.css en différentes parties pour mieux s'y retrouver.

Les tailles

width/height

L'option width indiquera la largeur de votre élément et height sa hauteur. Les tailles peuvent avoir des unités relatives ou absolues.

Les unités

Absolues

Dans la liste des unités absolues vous avez :

  • mm : millimètre
  • cm : centimètre
  • in : inche (1in = 2.54cm)
  • px : pixel
  • pt : point
  • pc : pica

Dans cette liste, on utilise rarement autre chose que les px. En effet, les autres unités peuvent, dans certains cas, avoir des valeurs relatives à la résolution de l'écran, ce qui peut provoquer des tailles erronées. Comme on parle en px pour la taille de notre écran, exemple 2560px de largeur pour 1440px de hauteur, on aura plus de facilité à définir la taille de nos éléments en pixels.

Lien vers la documentation MDN - Unités de longueur absolues

Relatives

Ces unités peuvent être définies relativement à d'autres unités ou à des éléments de contexte.

Selon la taille de l'écran/du parent = le pourcentage

Vous pouvez écrire :

p {
    width: 50%;
}

Si le paragraphe n'a pas de parent, il aura une largeur qui sera égale à la moitié de la largeur de la page. S'il en a un, ce sera la moitié de la largeur de ce parent.

Selon la taille de la police de caractère = em/rem

em et rem ont un fonctionnement similaire. Elles vont être des multiples d'un font-size. Pour notre exemple, imaginons que nous avons ce code HTML :

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Exemple em/rem</title>
</head>
<body>
    <nav>
        <ul>
            <li>Lien 1</li>
            <li>Lien 2</li>
            <li>Lien 3</li>
        </ul>
    </header>
</body>
</html>

Si nous avons ce code CSS :

nav {
    font-size: 20px;
}

li {
    margin-left: 1em;
}

...notre margin-left du li, sera de 20px. En effet, le em va définir une valeur relative à la valeur du font-size dont hérite notre élément. Notre élément li hérite de la valeur que définit nav car c'est dans la chaîne du HTML : html > body > nav > ul > li, le dernier parent qui définit une valeur. Si nous avions eu 1.5em, la valeur aurait dont été de 30px => 20px * 1.5.

Le rem, quant à lui, va récupérer le font-size dit "root". Généralement, on définira une valeur de font-size sur html ou sur body. C'est alors cette valeur qui servira de base pour calculer la valeur de rem.

Mais dans quels cas utiliser ces unités ?

Elles sont pratiques pour définir des valeurs qui seront dépendantes de la taille de la police de caractère. Comme certains utilisateurs définissent une taille de police de caractère différente de celle que vous avez déterminée, pour leur confort de lecture ou parce qu'ils sont porteurs d'un handicap, cette taille différente va alors être problématique si vous avez défini toutes vos tailles en px. Vu que les texte seront plus grands, ils risquent de casser votre design. En utilisant une taille relative à cette police de caractère, lorsque vos utilisateurs vont changer celle-ci, vos autres éléments adapteront leurs tailles, marges, positions, etc.

Il existe d'autres unités relatives à différents éléments des polices de caractères, mais elles sont moins utilisées. Vous pouvez les retrouver dans le lien de la doc ci-dessous.

Lien vers la documentation MDN - Longueurs relatives à la police de caractère

Selon le viewport = vh/vw, dvh/dvw, lvh/lvw, svh/svw

Le viewport est la partie visible de votre page. Relativement à cette valeur, on pourra utiliser deux unités et leurs dérivés : vw = viewport width et vh = viewport height.

Si l'on écrit : 

header {
    width: 100vw;
}

...notre header prendra 100% de la largeur de notre viewport.

Si vous mettez 100vw c'est tout le viewport qui est compris ! Cela englobe aussi la barre de défilement sur la droite. Ce qui fait que votre header sera plus grand que juste la partie affichage de votre viewport, car il dépassera sous la barre de défilement et fera qu'on aura alors une barre de défilement horizontal pour compenser ce dépassement. Il est donc parfois mieux de lui préférer le pourcentage ou faire en sorte que la barre de défilement soit dans l'item principal et non au niveau de html/body.

Pour la hauteur :

section {
    height: 100vh;
}

...notre section prendra 100% de la hauteur de notre viewport.

Le vh est indispensable contrairement au vw. Si, par exemple, dans votre page vous n'avez que la section dans body. Si vous mettez au niveau de section que sa hauteur est de 100%. Elle fera en sorte de faire 100% de body. Sauf que dans ce cas, 100% de body c'est 0px de haut, vu qu'il n'y a que la section dedans et qu'elle est vide. Pour indiquer la hauteur du viewport, il est donc indispensable de passer par vh, ou un de ses dérivés !

Depuis le début de l'année 2023, des dérivés à vh/vw ont été créés :

  • dvh/dvw
  • lvh/lvw
  • svh/svw

Ces dérivés permettent de prendre en compte un problème que l'on rencontrait souvent dans le design des sites sur smartphone : le fait que la barre d'URL se replie sur ces appareils.

On voit sur l'impression écran de gauche que la barre d'URL est dépliée et sur celle de droite qu'elle est repliée.

Si l'on utilise vh, cette unité correspondra à la hauteur du viewport lorsque la barre d'URL est dépliée. Ce qui fait que lorsqu'on scrolle vers le bas, cette dernière va se replier et on aura un "trou" de la hauteur de cette barre dans notre design. 

Pour résoudre ce problème, on a maintenant à notre disposition de nouvelles unités : 

  • svh = small vh = hauteur du viewport quand la barre est dépliée, c'est l'équivalent de vh.
  • lvh = large vh = hauteur du viewport quand la barre est repliée.
  • dvh = dynamic vh = hauteur du viewport recalculée en fonction de l'état de la barre. C'est cette unité que je vous conseille aujourd'hui pour éviter les trous dans le design.

Mais si vw est équivalent à 100% de la largeur de l'écran, pourquoi ne pas utiliser directement l'unité % ?

Il y a deux cas d'usage où le % n'est pas utilisable :

  • Si l'on est dans un enfant et qu'on veut déterminer sa taille en fonction de l'écran et non du parent.
  • Si l'on veut définir la hauteur d'un élément par rapport à la hauteur de la page. En effet, la hauteur d'une page web ne correspond pas à la hauteur de l'écran qui nous permet de la visualiser mais bien à la hauteur de tout son contenu ! Donc, si vous prenez cette page comme exemple, 100% de la page, c'est ce que vous voyez à l'écran, mais aussi tout ce qui est au-dessus et tout ce qui est en-dessous. Donc si vous voulez dire la hauteur de l'écran, on utilisera plutôt vh ou un de ses dérivés.

Lien vers la documentation MDN - Longueurs liées au viewport

object-fit

Quand on met une largeur et une longueur à une image, on encoure le risque de la déformer. En effet, si le ratio entre la largeur et la longueur définies n'est pas le même que le ratio initiale de notre image, elle sera alors déformée. Pour éviter ça, on peut ajouter l'option objet-fit qui va permettre de dire à notre image de réagir différemment.

contain

Avec la valeur contain, l'image va faire en sorte d'être visible entièrement. Pour compenser, elle va ajouter des marges en haut et en bas ou à gauche et à droite pour combler le vide qu'elle laisse.

cover

Avec la valeur cover, l'image va faire en sorte de remplir tout l'espace et va se rogner en haut et en bas ou à gauche et à droite.

La propriété object-position peut compléter object-fit pour indiquer comment l'image s'aligne quand elle ajoute les marges ou qu'elle se rogne.

Les longueurs du projet

Si on regarde sur la maquette du projet pour notre client, on voit que la barre de navigation fais 64px de hauteur et 1920px de largeur.

header nav {
    height: 64px;
    width: 1920px;
}

Si on prend en compte les conseils donnés ci-dessus, la largeur correspond à toute la largeur de la page. Quant à la hauteur, elle pourrait être indiquée par une unité relative, au cas où les utilisateur modifieraient la taille de leur police de caractère. Si on garde la valeur par défaut du font-size de l'élément root, on a une valeur de 16px => 64 / 16 = 4.

header nav {
    height: 4rem;
    width: 100%;
}

Les couleurs

La notation RGB

RGB = Red Green Blue = rouge vert bleu.

Cette notation donne le taux de chacune des couleurs primaires de 0 à 255 :

p {
    color: rgb(255, 0, 0);
}

Ici, les paragraphes seront en rouge, car le taux de rouge sera à 255, le taux de vert à 0 et le taux de bleu à 0. Cette notation est particulièrement intéressante car elle permet d'utiliser la fonction rgba pour ajouter un quatrième paramètre, qui sera l'opacité de la couleur, prenant une valeur de 0 à 1.

p {
    color: rgba(255, 0, 0, 0.5);
}

...Là, les paragraphes seront écrits en rouge à 50% transparent (ou 50% opaque = verre à moitié vide/à moitié plein, toussa toussa 😉).

Lien vers la documentation MDN - rgb

La notation hexadécimale

Cette façon d'écrire les couleurs est très proche de la notation RGB, car elle est basée sur le même système = taux de rouge/vert/bleu, mais, au lieu d'avoir une base 10 = décimal, on a une base 16 = hexadécimal, petit rappel :

  • binaire : 0 ou 1 ;
  • décimal : 0, 1, 2, 3, 4, 5, 6, 7, 8 ou 9 ;
  • hexadécimal : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e ou f.

Exemples décimale <=> hexadécimal :

  • 0 <=> 0
  • 15 <=> f
  • 128 <=> 80
  • 199 <=> c7
  • 255 <=> ff

Comme en notation rgb le taux peut aller de 0 à 255, en hexadécimal le taux peut aller de 0 à ff. Si on reprend l'exemple des paragraphes ci-dessus :

p {
   color: #ff0000;
}

On voit qu'avant la notation hexadécimale on ajoute un #.

La notation hexadécimale permet également de faire de la transparence en ajoutant un dernier caractère qui va également de 0 à 255 en hexadécimal :

p {
    color: #ff00007f;
}

... ici le rouge est à nouveau à 50% d'opacité car 7f = 127 ≈ 50% de 255.

Il est à noter que l'écriture peut, dans certains cas, être simplifiée. Vous verrez parfois cette écriture :

p {
   color: #f00;
}

...est équivalent à :

p {
   color: #ff0000;
}

Cette écriture simplifiée, permet de compresser les différentes parties quand elles sont écrites par un double caractère : ff devient alors f.

La notation hsl

HSL = Hue Saturation Lightness = teinte saturation luminosité.

Si on reprend l'exemple des paragraphes :

p {
   color: hsl(0, 100%, 100%);
}

Le premier paramètre est la teinte, elle correspond à l'angle sur le cercle des couleurs ci-dessus en commençant à l'horizontal sur la droite comme pour un cercle trigonométrique, puis on suit le sens antihoraire ou sens trigonométrique. Exemples :

  • 0° = rouge ;
  • 60° = jaune ;
  • 120° = vert ;
  • 180° = cyan ;
  • 240° = bleu ;
  • 300° = magenta.

Le second paramètre est le taux de saturation qui va de 0% à 100%, où 0% = gris et 100% = couleur pure ; Le troisième paramètre a les mêmes limites et 0% = saturation absente (noir), 50% = couleur pure et 100% = saturation pleine (blanc).

À noter que le hsla existe et permet d'ajouter le paramètre d'opacité comme pour le rgba.

Lien vers la documentation MDN - hsl

La notation "nom de la couleur"

Pour finir, il est possible d'écrire la couleur en toutes lettres, une liste de 140 couleurs a été définie pour le web.

Autres

À noter qu'il existe d'autres notations : hwb, lch, oklch mais elles sont pour certaines expérimentales, mais surtout moins utilisées.

Lien vers la documentation MDN - tous les types de couleur

Les couleurs de notre projet

On récupère les couleurs indiquées sur la maquette pour notre barre de navigation : #ABCA97 pour le fond et #99005E pour la police.

header nav {
    height: 4rem;
    width: 100%;
    background-color: #ABCA97;
}

header nav ul li a {
    color: #99005E;
}
Le color on l'a mis directement sur le a, car, sinon, il n'est pas pris en compte comme la couleur par défaut des liens a une priorité importante.

Police de caractères

Conseil : quand on débute, pour se simplifier la tâche, on peut utiliser les polices fournies par Google : site de Google Fonts

La première chose est de cocher le type de langage à "latin" car cela permet d'être sûr d'avoir les caractères accentués. Quand on a trouvé la police qui nous intéresse, on regarde la licence pour savoir si on a le droit d'utiliser la police, et si c'est bon, on clique sur : "Select this style". Le site nous fournit alors les raccourcis pour ajouter la police dans notre projet, avec les link et la valeur de font-family dans notre CSS.

On ajoute alors :

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Londrina+Solid&display=swap" rel="stylesheet">

... entre les balises <head></head> et :

body {
    font-family: 'Londrina Solid', sans-serif;
}

... dans notre le fichier style.css. Je mets la police de caractère au niveau de body pour que tous les items HTML puissent en hériter.

On voit que Google Font nous met, dans le font-family, en plus de la police choisie, une police générique, ici "sans-serif". C'est une bonne pratique de toujours utiliser une police dont on est sûr de la présence par défaut sur l'appareil dans cette liste : serif, sans-serif, monospace, cursive, fantasy, system-ui, emoji, math, fangsong.

Les marges 

Il existe deux types de marge en CSS : margin et padding qui vont permettre d'espacer nos éléments.

margin

Ce type de marge est utilisé pour séparer des éléments entre eux. Celle-ci est toujours exclue de la taille totale d'un élément. En effet, si on met un width à notre élément, la margin ne sera pas comptée dans cette largeur définie.

Elle peut être écrite de différentes manières :

p {
    margin: 10px;
    margin: 10px 15px;
    margin: 10px 15px 20px;
    margin: 10px 15px 20px 25px;
    margin-top: 10px;
    margin-right: 15px;
    margin-bottom: 20px;
    margin-left: 25px;
}

Dans l'ordre d'écriture :

  • Toutes les marges autour de l'élément (haut, droite, bas et gauche) seront définies à 10px ;
  • Haut/bas = 10px, droite/gauche = 15px ;
  • Haut = 10px, droite/gauche = 15px, bas = 20px;
  • Haut = 10px, droite = 15px, bas = 20px, gauche = 25px ;
  • Haut = 10px ;
  • Droite = 15px ;
  • Bas = 20px ;
  • Gauche = 25px.

Lien vers la documentation MDN - Margin

padding

Ce type de marge est une marge interne. Celle-ci permet, par exemple, de mettre de l'espace entre le bord d'une section et le texte qu'elle contient. 

Par défaut, cette marge n'est pas comptée dans la taille (width ou height de l'élément). Pour que ce soit le cas, on ajoute box-sizing: border-box. Si c'est le cas, width et height feront en sorte que la taille du contenu soit la valeur indiquée moins les paddings et moins les borders.
padding peut prendre les mêmes valeurs et écrites de la même manière que margin.

Lien vers la documentation MDN - Padding

Les marges du projet

Si l'on regarde, sur la maquette, les marges que l'on retrouve au niveau de notre nav, on voit que l'icône en haut à gauche a un espace de 16px sur sa gauche et que la liste des liens a une marge à sa droite également de 16px. On pourrait donc mettre, par exemple, une margin à l'img de notre icône, mais si on fait ça, il faudra mettre la même margin à notre liste. Ce qui fait qu'on va mettre deux fois la même valeur et si dans le futur notre marge passe de 16 à 20 on devra le changer deux fois. C'est pourquoi, on va plutôt mettre une marge interne à notre nav et comme ça c'est elle qui gère les deux valeurs en une fois.

header nav {
    height: 4rem;
    width: 100%;
    box-sizing: border-box;
    padding: 5px 1rem;
    background-color: #ABCA97;
}

J'ai également ajouté le box-sizing pour éviter que notre nav ne dépasse de la fenêtre en ajoutant les paddings en plus de sa taille qui est déjà à 100%, mais bien pour qu'elle considère que les paddings sont compris dans le 100%.

Notre padding sera ici de 5px en haut et en bas, et de 1rem (donc 16px sur notre projet) à gauche et à droite.

Position

La propriété CSS position permet de définir comment un élément va se comporter par rapport aux autres.

static

C'est le fonctionnement par défaut ; les autres éléments laissent la place à l'élément pour se mettre dans le fil des éléments. Le positionnement ne peut pas être modifié.

relative

Permet de garder un fonctionnement similaire à static. Les éléments laissent la place à l'élément pour se mettre dans le fil. Ensuite avec les propriétés : top, left, right et bottom, on peut déplacer l'élément ciblé par rapport à son emplacement d'origine. S'il déborde au-dessus d'un voisin, il sera placé en dessous ou au-dessus.

fixed

Fait sortir l'élément du fil des placements = les autres éléments ne lui laisseront plus de place. Puis on placera l'élément ciblé avec les propriétés : top, left, right et bottom qui l'aligneront par rapport à l'écran et il ne sera pas soumis au scroll.

Ce placement est utilisé, par exemple, pour les barres de navigation qui sont toujours en haut de l'écran, même quand on scrolle vers le bas.

Absolute

Fait également sortir l'élément du fil des placements. Avec ce positionnement les propriétés : top, left, right et bottom seront en fonction du premier parent qui aura défini une position autre que static. S'il n'y a aucun parent qui déclare un positionnement, ce sera en fonction de la page. Exemple :

#main_header div {
    position: relative;
}

#main_header div img {
    position: absolute;
}

Comme div est le parent de img et qu'elle définit une position à relative, quand on met l'image en absolute, cette image sera placée en fonction des limites de son parent div.

À noter que dans la position absolute, l'élément sera soumis au scroll.

Sticky

Placement très pratique car il permet d'avoir un positionement différent en fonction du scroll. Avec ce code :

nav {
    position: sticky;
    top: 100px;
}

Notre nav est en static jusqu'à ce que notre page arrive à un scroll à 100px du haut, elle passera alors en fixed. Ce positionnement est utilisé pour les nav qui sont placées à un certain niveau et qui doivent devenir fixed quand on arrive à leur niveau.

Lien vers la documentation MDN - Position

Code final

Cliquez ici pour télécharger le code final

  • Cours
  • Tutoriels
  • Aide
  • À Propos