Valentin Dupas

💡 If this is the first course you read from me, please read this small thing : about my courses

Le web des années 2000

Un peu de CSS

Oui, oui, je sais jusqu'ici notre document HTML est moins joli et moins facile à éditer qu'un document Word.

Mais HTML est bien plus puissant parce que c'est un standard ouvert. On peut aussi s'en servir comme une brique d'un système plus grand, et c'est là dessus qu'HTML gagne haut la main. Jusqu'ici on compare les documents par defaut mais tous les sites web sont techniquement des documents HTML et je ne crois pas avoir vu du document Word aussi magnifique que le plus médiocre des sites web.

En utilisant un autre langage avec HTML on peut définir des mises en formes au-delà de la mise en forme par défaut, et ce langage est CSS.

Avant de faire ça, on va enfin écrire notre page web correctement parce que CSS ne fonctionnera pas sans ça.

Partons de cette page HTML

<h1>Salut</h1>

Dans un premier temps il faut savoir qu'HTML vient d'une époque pendant laquelle on regardait la première ligne d'un fichier pour savoir son type donc allons y, spécifions.

<!DOCTYPE html>
<h1>Salut</h1>

Ensuite, le contenu qui est pour l'utilisateur se met dans un tag <body> et ce qui est pour l'ordinateur se met dans le tag <head>, en sachant que les infos pour l'ordinateur servent à traiter les infos pour les utilisateurs on va mettre le <head> avant le <body>

<!DOCTYPE html>
<head></head>
<body>
    <h1>Salut</h1>
</body>

Et pour finir on les rassemble dans un tag <html>

<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <h1>Salut</h1>
    </body>
</html>

Et voila ヾ( ˃ᴗ˂ )◞ 🎉

Bon après on peut le faire plus vite avec un raccourci.

Dans un fichier .html vide appuyez sur ! puis entrer.

Pourquoi le tag <html>?

parce qu'il accepte des attributs, comme la langue, si vous faites une page qui est remplie de chinois que vous mettez un attribut lang="fr" dans le tag html alors certains traducteurs qui se reposent uniquement sur cette information partiront du principe que le contenu est en français.

Vous remarquerez aussi que, maintenant que nos pages sont faites correctement, le LiveServer recharge les pages à notre place quand on sauvegarde dans VSCode.

Ok cool, revenons au CSS. Pour en écrire nous avons 3 possibilités:

  • inline
  • local
  • externe On va surtout travailler avec du CSS local.

CSS local

Le CSS local est assez simple, il suffit de mettre un tag <style> dans le <head> et on peut commencer à écrire notre CSS dedans.

Le css s'écrit comme ceci :

css_rule 2.png

Le sélecteur permet de définir quels éléments de la page sont affectés par la règle. La règle est délimitée par les accolades et contient un ou plusieurs couples propriété : valeur.

Donc sur l'exemple ci-dessus on voit que les <h1> auront maintenant leur couleur en rouge.

Salut, il est pas beau mon h1 comme ça?

Pour finir avec une page comme celle-ci.

<!DOCTYPE html>
<html>
    <head>
        <style>
        h1{
            color: red;
            text-align: center;
        }
        </style>
    </head>
    <body>
        <h1>Salut</h1>
    </body>
</html>

Et j'y ai rajouté text-align: center; pour vous montrer comment :

  1. on centre pour de vrai, le tag <center> est maintenant interdit >:(
  2. on mets plusieurs déclarations dans une même règle

Avant de plonger plus loin dans le CSS et ce que ca peut faire on va finir de voir les différentes manières de l'inclure dans la page.

CSS inline

Celui là j'ai pas vraiment envie de vous le montrer, parce que je ne veux pas que vous l'utilisez. Mais il faut savoir que ça existe.

Ici le CSS s'écrit dans l'attribut style de nos tags HTML comme ceci

<h1 style="color:red; text-align:center;">Salut</h1>

Faut savoir que ça existe mais généralement pas la solution pour plein de raisons. Je sais que vous ne comprendrez pas ces raisons parce qu'il vous manque trop de contexte mais...

  • ça n'applique le style qu'à cet élément
  • la priorité des ces déclaration est super élevée
  • votre HTML deviens une grosse soupe de tag+contenus+styles parce que c'est super commun d'avoir besoin de 5~6 déclarations par élément
  • ça rend un peu plus difficile la manipulation du style des élément avec javascript

... je veux juste que vous reteniez que ça fait beaucoup.

CSS externe

Il est aussi possible d'importer du CSS qui est dans un autre fichier.

Contenu du fichier mes_styles.css :

h1{
    color: blue;
    text-align: center;
}

Contenu du fichier html :

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="mes_styles.css">
    </head>
    <body>
        <h1>Salut</h1>
    </body>
</html>

Qu'est-ce qu'on fait?

Pas dur.

Inline c'est non ❌.

  • Est-ce que c'est du CSS qui est UNIQUMENT pour les éléments de la page en cours?
    • oui -> local
    • non -> externe

Et voila.

Ceci dit, si vous y tenez, vous pouvez tout faire en externe mais on se met à multiplier les fichiers. Bosser avec du CSS local permet de Ctrl+F l'HTML et le CSS en même temps, et la séparation entre commun/spécifique sera perdue ou à refaire autrement.

À partir de maintenant, vous savez où mettre l'HTML et le CSS donc mes exemples seront des fragments de code plutôt que des fichiers complets.

Unités et formats, explication en couleurs

On a vu la déclaration CSS color:red; et j'ai glissé color:blue; dans un exemple, mais comment est-ce qu'on sait quelles couleurs sont disponibles?

En regardant ici : https://developer.mozilla.org/en-US/docs/Web/CSS/named-color

Mais spécifier une couleur via son nom n'est évidemment pas la seule manière. Les propriétés comme color prennent un certain type d'infos, ici c'est les couleurs, mais un type d'infos peut être fourni dans plusieurs formats.

L'un d'entre eux est le format RGB

color: rgb(0, 87, 183);

Ou au format hexadécimal

color: #FFDD00;

... qui sont essentiellement la même chose mais écrits différemment parce que sur les 6 caractères hexadécimaux, les deux premiers représentent la quantité de rouge, le deux du milieu sont pour le vert et les deux derniers pour le bleu.

Par contre HSB est un format différent qu'il est intéressant de connaître

color: hsl(170, 58%, 72%);

H :Représente la teinte (Hue). C'est exprimé en degrés sur la roue des couleurs, 0 degrés étant rouge.

S : Représente la Saturation, exprimé en pourcentage. C'est la "concentration de pigments" dans la couleur, si il y en a peu on tirera sur des couleurs pastels et si il y en a beaucoup on aura des couleurs vives.

L : Représente la Luminosité. Si on continue l'analogie pigments/peinture, c'est la quantité de lumière qui éclaire notre peinture, 50% étant un montant "normal", 100% étant “tellement que ça devient blanc”, 0% étant tellement peu que c'est noir quoi qu'il en soit.

HSL_color_solid_cylinder_saturation_gray.png

HSL est mieux sur pas mal de plans, mais...

on peut faire mieux, si vous voulez vraiment être sérieux d'un point de vue couleurs. C'est au delà de ce cours mais vous devriez jeter un oeil aux formats oklab et oklchet à ce color-picker : https://oklch.com/#70,0.1,144,100

À noter que color change la couleur du texte de l'élément, pour changer la couleur du fond c'est la propriété background-color.

p{
    color: #4E1503;
    background-color: #FFFDA3;
}
<p>texte sépia foncé sur sepia plus neutre</p>

texte sépia foncé sur sepia plus neutre

Exercice

Appliquez du CSS au site des N.Y.A.N.5 pour le mettre en dark mode

Note: vous pouvez appliquer du CSS à tous les elements HTML.

Réponse
body{
    background-color: #16161D;
    color: white;
}

a{
    color: white;
}

Pourquoi dans la réponse de l'exercice précédent j'ai répété color pour les <a>? Parce que ...

Le C de CSS veux dire Cascade

La raison pour laquelle je n'ai pas eu besoin de spécifier la couleur des <h1> et des <p> dans la réponse ci-dessus est parce qu'ils sont dans le <body> et donc le style de <body> va "cascader" sur tous ses enfants SAUF ceux qui ont déjà une couleur de spécifiée, ce qui est les cas des <a> parce qu'ils ont une mise en forme spécifique fournie par les navigateurs, bleu (ou mauve) et soulignés.

Ici la cascade est un désavantage parce qu'on est en train de se battre contre le style par défaut des navigateurs, mais on peut en tirer avantage en fournissant un style englobant et ne spécifier que ceux qui sont "spéciaux".

body{
    background-color: #16161D;
    color: white;
}

em{
    color: red;
    font-weight:bold;
}
<body>
    <p>
        We only need do to be lucky once.
        <br/>
        You need to be lucky <em>every time</em>.
    </p>
</body>

<em> : est l'élément html pour signifier que le contenu est exagéré. Par défaut, il a le même comportement que le tag italique <i>.

À NOTER: <em> sert à appuyer votre écrit, et <i> sert à mettre en italique donc vous ne devriez pas appliquer de CSS à <i> qui fait parfaitement son job tel quel. Si vous voulez plus, utilisez <em>.

Le flux: Bloc et Inline

Pour ce qui est de la mise en page et de la gestion du flux du document, on a vu 2 types d'éléments.

1- Les éléments "inline" (à ne pas confondre avec "Le CSS inline") sont des éléments HTML qui sont prévus pour rester dans la ligne, ils ne sont pas censés casser le flux d'écriture du document. C'est le cas de, <a>, <em>, <u>, et <b> par exemple. Leur présence ne cassera pas le contenu en cours.

<body>
Du contenu super simple avec <i>un élément</i> inline. Tout tient sur une ligne.
</body>

2- À l'inverse les éléments bloc sont prévus pour être leur propre section de contenu donc le navigateur insérera un retour à la ligne avant et après ce genre d'éléments. C'est le cas de <h1>, <hr/>, et <p> par exemple.

Par défaut, les éléments bloc seront aussi larges que leur parents et renverront leur texte à la ligne s' ils trouvent un espace (on souhaite bon courage aux allemands et hollandais 😄 ).

<body>
<p>Chaque</p><p>mot</p><p>son</p><p>paragraphe.</p>
</body>

Challenge

Est ce qu'une image est inline ou bloc?

Si vous ne le savez pas, comment est-ce que vous pourriez le découvrir?

Reponse

En essayant, comme ceci:

<body>
Du contenu super simple avec <img src="https://picsum.photos/id/85/200/300" /> une image. Est-ce que ça casse le flux du texte?
</body>

Polices: la forme et la font

Je hais Google Fonts, ou en tout cas l'usage qu'en font les débutants qui ont uniquement vu un tuto youtube de 5min.

Oui, c'est facile, mais c'est bourre de tracking, je plains leurs utilisateurs et c'est même pas une bonne excuse parce qu'il y a encore plus simple, les polices par défaut.

Pour appliquer une police à un élément c'est via la propriété font-family. Le truc le plus facile du monde est d'utiliser la valeur system-ui.

body{
    font-family: system-ui;
}

system-ui est une valeur spéciale et pas une police, c'est le mot clé pour dire "la police de l'ordinateur sur lequel je suis". Ce qui fait que :

  • on aura un truc au goût du jour, et pas le Times New Roman par défaut.
  • ça chargera tout de suite parce que c'est déjà sur l'ordi, pas besoin de demander un fichier à un serveur
  • et, truc super cool, si l'utilisateur a changé la police par défaut de sa machine (parce qu'il est dyslexique par exemple) eh bien votre site utilisera la font choisie par l'utilisateur.

Sinon, de nos jours, tous les systèmes d'exploitations (windows, linux, freeBSD, etc...) sont fournis avec des polices. Il est donc possible de spécifier des polices sans les importer et le navigateur va les essayer pour chaque caractère, de la première à la dernière, et s'arrêter sur la première qui existe sur le système de l'utilisateur .

Example

font-family: Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif;
Pour chaque caractère??

oui parce que comme ça tu peux additionner une font latine, une font cyrilique et des fonts pour chaque alphabet d’asie basé sur des idéogrammes pour un site qui est multi-langue

Ici, sans-serif est un nom générique au même titre que system-ui et sert donc à dire "bon, si on trouve vraiment rien, on prendra la police sans-serif par défaut de la machine".

Il y a un designer sympa qui a rassemblé plusieurs font-stack en se basant sur les systèmes d'exploitations les plus populaires. C'est globalement là-bas que je vais pêcher mes polices (dans les 10% des cas que je n'arrive pas à couvrir avec les génériques) : https://modernfontstacks.com/.

"Oui mais moi, je connais une petite fonderie sympathique et je voudrais importer mes polices"

Ok, apprenons comment utiliser une font custom comme "Aurebesh AF" par exemple.

D'abord, téléchargeons nos fichiers : https://www.dafont.com/aurebesh-af.font

Puis décompressons et rangeons les comme ceci custom_font_setup.jpg

d'abord importez la font dans votre CSS

@font-face {
    font-family: Aurebesh;
    src: url("/assets/fonts/AurebeshAF/AurebeshAF-CanonTech.otf");
}

et ensuite appliquez la à ce que vous voulez

* {
    font-family: Aurebesh, system-ui;
}

et pensez à mettre une font de "secours" pour couvrir en cas de problèmes, ça ne mange pas de pain.

Et voilà, maintenant vous pouvez publier des tutos sur jawascript 😂

function greetings() {
  console.log("hello world");
  console.log(`and may the force
    be with you`);
}

mais plus important, maintenant vous pouvez sourcer vos fonts n'importe où

  • dafont
  • fontstruct
  • myfonts
  • fontspace
  • awwwards
  • et oui, google fonts, en les telechargeants
  • ... ou même faire les vôtres! vous n'en êtes plus réduits à chercher des sites qui vous donnent des liens pré-hébergés.

Je ne vous ai pas montré comment importer des fonts avec différents niveau de graisses mais avec ce que vous savez je suis sur que vous l'aurez en googlant un coup, sinon, jetez un oeil au fichier css fournis avec inter

Le box model

Le terme "box model" désigne le fait que tous les éléments sont considérées comme des boîtes, y compris les éléments inline.

Chaque boîte a:

  • un contenu
  • du rembourrage (padding)
  • des bordures (border)
  • des marges (margin)

Arrangées comme ceci

margin
border
padding
content

Le padding et le margin sont tous les deux là pour fournir de l'espace a vos boîtes et les faire respirer.

Le padding va insérer de l'espace entre votre contenu et la bordure et donc "compresser" votre contenu. Le margin va introduire de l'espace entre le bord et le reste du document, poussant les autres éléments qui sont autour.

Généralement, quand on veut créer de l'espace négatif dans notre document, on voudra naturellement utiliser margin pour "faire de la place" ceci dit, utiliser des boites un peu trop grandes avec du padding conduit à des résultats plus facile à comprendre, c'est plus dur de retrouver les coupables dans une page ou tout le monde se pousse.

Aussi, retenez le mot gap, on le verra plus tard, mais avec ça et le padding on devrait pouvoir s'en sortir sans (trop) toucher au margin.

Même s' ils sont invisibles, vous pouvez facilement visualiser les padding et margin en utilisant l'outil de sélection des devtools (ouvrables en en appuyant sur la touche F12 ou via clic droit sur la page > inspecter)

Pour donner du padding a un éléments c'est via la propriété padding

padding: 40px;

C'est assez évident, par contre le fait que ce soit un raccourci, aussi appelé "shorthand", l'est moins.

En l'état ça va donner un padding de 40 pixels en haut, en bas, à gauche, à droite (ces soirée là 🎵)

Equivalent à

padding-top: 40px;
padding-bottom: 40px;
padding-left: 40px;
padding-right:40px

Ceci dit, si on veut des valeurs différentes pour chaque cote on peut quand même utiliser la version shorthand.

Son comportement est différent si elle a 1, 2 ou 4 valeurs.

1 valeur : on a le même padding partout

padding: 40px;
  • 2 valeurs :
    • la 1ère valeur est pour le haut et le bas
    • la 2ème valeur est pour la gauche et la droite
padding: 20px 40px;
  • 4 valeurs :
    • 1ère valeur : haut ⬆️
    • 2ème valeur: droite ➡️
    • 3ième valeur: bas ⬇️
    • 4ème valeur: gauche ⬅️ donc sens-horaire (ou "comme pour visser" si ça vous parle plus)
padding: 10px 20px 30px 40px;

Plus vous utilisez des techniques qui vous donnent de la liberté plus vous avez de chances de vous planter sur votre mise en page, je vous recommande de toujours essayer avec une seule valeur d’abord, ce qui sera suffisant dans la plupart des cas, et 2 si vous êtes sur un élément bien plus long que large.

Et 3? ça marche. Pour vous rendre service, il appliquera à gauche la valeur du padding de droite mais faites pas ça...

Comment est-ce que je sais ça? En essayant!

Avec les devtools d'ouverts si vous sélectionnez un élément vous pourrez voir le CSS qui lui est appliqué et aussi ce qui ne marche pas.

working_css 1.png

En voyant ça je me suis rendu compte que ça fonctionnait quand même (je ne m'y attendais pas quand j'ai préparé l'exemple)

Parce que quelque chose qui ne marchera clairement pas serait ceci:

padding: blue;

Nous donnant ceci, remarquez que le CSS en question est gris et barré

broken_CSS.png

Et c'est pas tant important de savoir ce qui ne marche pas, ce qu'il faut savoir c'est comment tester.

Pour les margin ça marche exactement pareil

Par contre pour les bordures c'est un poil plus compliqué

Et vous pouvez utiliser la shorthand en spécifiant entre 1 et 3 de ces types valeurs.

border: 1px solid black;

Autant je vous recommanderai d'utiliser les shorthand pour le padding et le margin parce que c'est super simple une fois qu'on sait que c'est dans le sens horaire, autant pour la bordure faites comme vous sentez.

Dimensions

Avec les couleurs, je vous ai expliqué qu'il pouvait y avoir plusieurs types de valeurs possibles pour une même propriété.

C'est encore plus vrai avec les dimensions. Jusqu'à maintenant on a vu les px qui sont assez intuitifs parce que 40px c'est 40 pixels. Mais il existe d'autres unités qui ont leurs intérêts.

em

Les em sont relatifs à la taille des caractères de l'élément courant. Donc dans un <h1> et dans un <p>, 1em se fera pas la même taille.

Par défaut, le texte d'un <p> fait 16px donc 1em = 16px En revanche, le texte d'un <h1> par défaut fait 32px donc 1em = 32px

C'est pratique si vous voulez que des éléments décoratifs d'un éléments suivent quand le texte grandit/rétrécit.

rem

Les rem sont pareils, sauf qu’au lieu d'être relatif à l'élément, c'est relatif à la taille des caractères à la racine du document. Autrement dit, la taille des caractères par défaut pour tout le corps du texte qui est par défaut 16px donc 1rem = 16px.

ch

Le ch est lui aussi relatif à la taille du texte comme un em sauf qu'il se base sur la largeur d'un caractère plutôt que de sa hauteur. (la largeur d'un 'x' minuscule pour être précis).

Je m'en sert surtout pour contraindre la largeur des éléments qui contiennent du texte pour être entre 45 et 85 caractères par ligne. Les livres sont en général autour de 65 et beaucoup programmes pour formater du code visent 80 (ceci dit il faut se rappeler que dans du code il est fréquent de commencer une ligne par 2~8 espaces).

max-width: 65ch;

%

Le % représente une portion du parent. L'axe dépend de la propriété.

Si j'écris

width: 50%;

alors ma largeur sera égale à la moitié de la largeur du parent.

Par contre si j'écris

height: 50%;

alors ma hauteur sera égale à la moitié de la hauteur du parent.

Spoiler: Ça ne sera pas assez pour faire des interfaces qui s'adaptent à différentes tailles d'écran.

0

La valeur 0 est un cas particulier qui peut se passer d'unité parce que 0px c'est pareil que 0em, 0%, etc...

Challenge

Faites votre propre bouton.

Pour ça vous aurez probablement besoin d'aller apprendre quelques nouvelles propriétés CSS.

Si vous n'avez pas d'idées, essayer de refaire le bouton ci-dessous

Dans cet exemple, les propriétés que l'on a pas vu sont

  • cursor
  • border-radius C’est le moment de s'entraîner à lire la doc en ligne.
Solution
button {
    /*pour retirer le bord par défaut*/
    border: 0;
    
    padding: 1rem 2rem;
    border-radius: 0.5rem;
    
    color: white;
    background-color: grey;
    
    font-family: system-ui;
    font-weight: bold;
    
    cursor: pointer;
}

En regardant la solution, vous noterez que le CSS est découpé en îlots. Chacun séparés par une ligne vide. Ca va vous sembler un peu trop conceptuel pour le moment, mais je regroupe mon css en petit bloc par thèmes dans mes éléments pour faciliter la lecture. Dans cet exemple on a corrigé le style par défaut, “box model”, “couleurs”, “police” et “autre”.

Les classes et les ids

Les classes

C'est bien marrant d'assigner du CSS a des éléments en fonction de leurs type mais qu'est-ce qu'il se passe si j'ai besoin d'avoir des paragraphes qui ont des styles différents?

En css on peut sélectionner via autre chose que le type de tag.

On peut ajouter des classes à nos éléments via l'attribut class comme ceci

<p class="sepia">je suis sépia<p>
<p>pas moi</p>
<p class="sepia">moi si</p>
.sepia{
    color: #4E1503;
    background-color: #FFFDA3;
}

je suis sépia

pas moi

moi si

Notez que ce coup-ci le sélecteur commence par un point . .

sepia{} est pour les éléments de type <sepia> (qui n'existent pas) .sepia{} est pour les éléments class="sepia".

Le but d'une classe est de faire des petits bouts de css réutilisables. Ici on vient de définir ce qu'est le concept "avoir un élément sépia" et maintenant on peut coller ce concept sur tous les éléments que l'on veut.

Mais au-delà d'être réutilisables ils sont aussi composables, un élément html peut avoir plusieurs classes. Il suffit de les séparer par un espace.

<p class="sepia">Je suis sépia</p>
<p class="sepia fancy">et moi suis bien plus</p>
.sepia{
    color: #4E1503;
    background-color: #FFFDA3;
}

.fancy{
    font-family: Didot, 'Bodoni MT', 'Noto Serif Display', 'URW Palladio L', P052, Sylfaen, serif;
    font-style: oblique;
}

Je suis sépia

et moi je suis bien plus

Les ids

Le but d'une classe est d'être réutilisable et composable.

Si vous voulez appliquer un style précis à un élément précis, les identifiants sont prévus pour ça.

<p id="description">Mon contact à Washington dit qu’on n’a pas affaire à un élève mais qu’on a affaire au professeur.</p>
#description{
    font-family: 'Nimbus Mono PS', 'Courier New', monospace;`
    font-weight: bold;
}

Mon contact à Washington dit qu’on n’a pas affaire à un élève mais qu’on a affaire au professeur.

Notez qu'en css ce coup si on démarre le sélecteur par un croisillon # alors qu'on le démarrait par un point . pour les classes.

Il est possible d'utiliser le même id pour plusieurs éléments ... mais ... faites pas ça.

Pourquoi faire une distinction entre classe et id?

Pour nous, et ceux qui nous reliront. Si je travaille correctement et que j'utilise une classe <p class="description"> alors mon paragraphe est UNE description. Par contre avec un identifiant <p id="description"> je communique que ce paragraphe est LA description de la page.

class_is_class.jpg