CSS

Formateur: Fabio Ginja

{ }

Introduction au CSS

Le CSS (Cascading Style Sheets ou feuilles de style en cascade) est un langage utilisé pour décrire la présentation d'un document écrit en HTML ou en XML.

Le CSS décrit la façon dont les éléments doivent être affichés à l'écran, sur du papier, en vocalisation, ou sur d'autres supports.

On est aujourd'hui à la troisième version (CSS3) qui est toujours en développement.

Syntaxe

h1 {

        color: blue;

        font-size: 24px

}

Sélecteur

Propriétés

Valeurs

Règle css

Déclaration

Où écrire le CSS

1. Dans l'attribut style (inline-style):

2. Dans la balise style à l'intérieur de la balise head:

3. Dans un fichier css séparé (le plus optimal et utilisé):

<main style="background: lightblue;">Lorem ipsum.</main>
<head>
  <style>
  main {
    background: lightblue;
  }
  </style>
</head>
/* style.css */
main {
  background: lightblue;
}
<head>
  <link rel="stylesheet" href="style.css">
</head>

Importer d'autres styles

On peut également importer d'autre fichier css ou d'autres polices:

https://fonts.google.com/

<!-- index.html -->
<head>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat&display=swap">
  <link rel="stylesheet" href="style.css">
</head>
/* style.css */
main {
  background: lightblue;
  font-family: 'Montserrat', sans-serif;
}

Si on ne précise pas de police en particulier, celle du navigateur sera prise par défaut.

Sélécteurs

Sélecteurs simples

Sélecteur de type:

Sélecteur d'attribut:

Sélecteur universel:

Sélecteur de classe:

Sélecteur d'id:

p {
  color: red;
}
* {
  color: red;
}
[href="https://url.com"] {
  color: blue;
}
.small {
  font-size: 10px;
}
#unique {
  background: lightblue;
}
<a href="www.url.com">Lien</a>
<p class="small">Lorem</a>
<p id="unique">Ipsum</a>

Combinateurs

Combinateur de voisin direct:

/* Ne cible que les spans situé directement après un paragraphe */
p + span {
  color: red;
}
<body>
  <p>First paragraph</p>
  <span>First span</span>
  <span>Second span</span>
  <p>Second otherparagraph</p>
  <span>Third span</span>
</body>

Sélecteur de voisins généraux:

/* Parmi tous les éléments <p>, cibler tous éléments <span> qui les suivent. */
p ~ span {
  color: red;
}
<body>
  <p>First paragraph</p>
  <span>First span</span>
  <span>Second span</span>
  <p>Second otherparagraph</p>
  <span>Third span</span>
</body>

Combinateurs

Sélecteur d'enfants:

/* Ne cible que les spans qui sont enfants direct d'un paragraphe */
p > span {
  color: red;
}
<body>
  <p>
    First paragraph
    <span>First span</span>
    <div>
      <span>Second span</span>
    </div>
  </p>
  <p>Second otherparagraph</p>
  <span>Third span</span>
</body>

Sélecteur de descendants:

/* Ne cible que les spans qui sont enfants d'un paragraphe */
p span {
  color: red;
}

Pseudo-{sélecteur}

Sélecteur de pseudo-classe:

/* ne cible <a> que lorsqu'il est activé, par exemple quand on clique dessus */
a:active {color: red;}

Sélecteur de pseudo-élément:

/* Sélectionne la première lettre d'un élément <p> */
p::first-letter {
  color: red;
  font-size: 130%;
}
/* ne cible <a> que lorsqu'il est survolé */
a:hover {color: blue;}
/* ne cible <input> que lorsque l'utilisateur est dans la zone de saisie */
input:focus {color: blue;}
/* Ajoute une flèche après les liens */
a::after {content: "→";}
/* Cible le premier élément <p> d'un type donné parmi ses éléments voisins */
p:first-of-type {color: red;}

Héritage

p {
  color: green;
}

Lorsqu'aucune valeur n'est spécifiée pour une propriété héritée sur un élément, l'élément récupère la valeur calculée de cette propriété appliquée à son élément parent.

<p>Ce paragraphe contient du <em>texte mis en emphase text</em>.</p>

Spécificité

p {color: red;}
p {color: green;}

Si deux règles d'égales importance sont spécifiée, alors c'est la dernière déclaré qui l'emporte:

<p>Ce paragraphe sera <em>en vert</em>.</p>

La règle la plus spécifique l'emporte en cas de conflit:

em {color: red;}
p {color: green;}
<p>Ce paragraphe sera en vert, <em>mais ce passage sera rouge</em>.</p>

Valeur de chaque spécificité:

  • Les inline-styles valent 1000
  • Les IDs valent 100
  • Les classes, attributs et pseudo-classes valent 10
  • Les éléments valent 1

Exercices

Le modèle de boîtes

Le modèle de boîtes

Tout les éléments html ont une boîte autour d'eux. Il existe deux types d'éléments: inline et block

Inline vs Block

Block:

  • Prend toute la largeur disponible (100% du parent)
  • Peut avoir une propriété width et height
  • L'élement est le seul présent sur sa ligne
  • Padding, margin vont "pousser" les autres éléments

Inline:

  • Ne prend que la largeur dont il a besoin
  • Peut avoir une propriété width et height
  • L'élement est le seul présent sur sa ligne
  • Padding, margin vont "pousser" les autres éléments

Inline-block est une combinaison des deux

Customiser cette boîte

On peut définir la margin, padding, ou border comme suit:

p {
  margin: 10px;
  padding: 5px;
  border: 1px solid blue;
}
div {
  margin-top: 10px;
  padding-right: 5px;
  padding-left: 5px;
  border-bottom: 1px solid blue;
}

Le nombre de valeur précisé aux propriétés margin, padding, et border aura un impact sur le résultat:

p {
  margin: 10px 11px 12px 13px; 
  /* Les marges seront appliqués dans le sens horaire */
  /* 10px en haut, 11px à droite, 12px en bas, 13px à gauche */
}
p {
  margin: 10px 11px 12px;
  /* 3 valeurs: 10px en haut, 11px à droite et à gauche, 12px en bas */
  padding: 13px 14px;
  /* 2 valeurs: 13px en haut et en bas, 14px à gauche et à droite */
}

Box-sizing

Le box-sizing est pas défaut à content-box, ce qui peut causer des problèmes inattendus...

main {
  box-sizing: content-box;
  width: 100%;
  padding: 32px;
}
main {
  box-sizing: border-box; /*Solution*/
  width: 100%;
  padding: 32px;
}

Fusions de marges

Si deux éléments, ayant tout deux des marges, se suivent, alors la marge appliqué entre ses deux éléments sera la plus grande des deux marges (et non l'addition des deux). On appelle cet effet la fusion des marges.

p {
  margin: 10px;
}
<body>
  <!-- 10px de marge en haut -->
  <p>First paragraph</p>
  <!-- seulement 10px entre eux -->
  <p>Second otherparagraph</p>
  <!-- 10px en bas -->
</body>

Textes, Couleurs et Unités

Couleurs

On peut définir les couleurs de plusieurs façon:

p {
  color: white;
  color: #ff0000; /* Hexadécimal - Rouge */
  color: #ffffff80; /* Hexadécimal, avec opacité */
  color: #0f0; /* Héxadécimal raccourcie - Vert */
  color: #ffff; /* Héxadécimal raccourcie avec opacité */
  color: rgb(255, 255, 255); /* Rouge, Vert, Bleu */
  color: rgba(255, 255, 255, .5); /* Rouge, Vert, Bleu, opacité */
  color: hsl(90, 100, 100); /* degrès, saturation, luminance */
  color: hsla(90, 100, 100, .5); /* avec opacité */
}

Synthèse additive

Unités

Pour espacer nos éléments ou donner des tailles, on a accès à plusieurs unités de mesure:

html {
  font-size: 10px; /* Ou font-size: 62.5%; */
}

div {
  font-size: 12px;
}

div > p {
  width: 100%; /* Pourcentage du parent - Seulement utilisable pour les largeurs*/
  height: 20vh; /* view height (ou vw pour view width) - 20% de la hauteur de la fenètre */
  font-size: 1.1em; /* Attention, la taille dépend ici du parent - 1.1 * 12(px) = 13.2(px)*/
  padding: 1.1rem; /* Root em - la taille dépend de la racine du document - 1.1 * 10(px) = 11(px) */
}

Textes

Quelques propriétés relatives à la polices et aux textes:

p {
  font-size: 1rem; /* Taille de la police */
  font-weight: 400; /* Grosseur de la police */
  font-style: italic; /* Style de la police */
  font-family: Helvetica, sans-rerif; /* Police */
  line-height: 1.4; /* Recommandé entre 1.2 et 1.6 */
  letter-spacing: .2px; /* Espace entre les lettres */
  text-align: justify; /* Où aligner le texte */
  text-align-last: center; /* Où aligner la dernière ligne */
  text-transform: uppercase; /* Transformer le texte en majuscules */
  text-indent: 3rem; /* Indenter la première ligne */
  overflow-wrap: break-word; /* Comment "casser" un mot sest plus grand que le conteneur*/
  text-decoration: underline; /* Comment "décorer" le texte */
}

Positionnement

Position

La propriété position définit la façon dont un élément est positionné dans un document.

nav {
  position: relative;
  position: absolute;
  position: fixed;
  position: sticky;
}

Un élément positionné de façon static conservera son "flow". Il sera placé directement à la suite de l’élément précédent:

La position par défaut d'un élément est la position static.

Les autres valeurs sont:

Position absolute

Si un élément est positionné en absolute, il aura accès à 4 autres propriétés: top, left, right, bottom

.yellow {
  position: absolute;
  top: 10px;
  left: 10px;
}

Ici, notre élément en jaune va se positionner à 10px du haut et de la gauche par rapport à notre body. La position absolute sort notre élément du flow.

Position absolute

Si en revanche, son conteneur parent était placé en position relative, le résultat serait différent:

.yellow {
  position: absolute;
  top: 10px;
  left: 10px;
}

.white-container {
  position: relative;
}

Ici, notre élément en jaune va se positionner à 10px du haut et de la gauche par rapport à notre conteneur blanc.

Position relative

La position relative permet de décaler un élément par rapport à sa position initiale:

.yellow {
  position: relative;
  top: 50px;
  left: 50px;
}

Ici, notre élément en jaune va se positionner à 50px du haut et de la gauche par rapport à sa position initiale. Le flow est conservé.

Position fixed

La position fixed permet de fixer un élément à une position donnée par rapport au body.

.yellow {
  position: fixed;
  top: 10px;
  right: 10px;
  left: 10px;
}

Ici, notre élément en jaune va se positionner à 10px du haut, de la gauche et de la droite par rapport au body. L'élément est sorti de son flow.

Position sticky

La position sticky permet de fixer un élément à une position donnée par rapport au body lorsque atteint la position donnée:

.yellow {
  position: sticky;
  top: 100px;
}

Ici, notre élément être fixe lorsqu'il sera à 100px du haut par rapport au body. Le flow est conservé.

z-index

Si deux éléments se superposent, on peut définir lequel devrait être au-dessus de l'autre. Si deux éléments ont la position absolute, celui qui sera au-dessus sera, par défaut, le dernier déclaré dans l'html.

.yellow {
  position: relative;
  top: 20px;
  left: 50px;
}

.red:nth-of-type(2) {
  z-index: 2;
}

Float

Float

"La propriété float indique qu'un élément doit être retiré du flux normal et doit être placé sur le côté droit ou sur le côté gauche de son conteneur." MDN

/* none (par défaut), left, right, inline-start, inline-end */
img {
  float: left;
}

Initialement, cette propriété ne devait être utilisée que pour placer des images, pourtant, elle a été très largement utilisée pour permettre le placement des éléments (ex Bootstrap 3).

Float et petit problèmes

La propriété float peut créer des soucis. Un élément inline qui prend cette propriété deviendra block, on peut avoir affaire à un "débordement" de float qui faudra nettoyer avec la propriété clear sur l'élément suivant:

/* both, left, right */
p {
  clear: both;
}

L'élément étant également sorti de son flux, s'il est le seul enfant de son parent, alors le parent se verra diminuer de sa taille et ainsi visuellement disparaître.

Aujourd'hui, évitez de l'utiliser autrement que pour son objectif originel.

Flexbox

Display

"La propriété display définit le type d'affichage utilisée pour le rendu d'un élément et la disposition utilisée pour ses éléments fils"MDN

/* liste non exhaustive */
main {
  display: inline;
  display: block;
  display: inline-block;
  display: table;
  display: flex;
  display: inline-flex;
  display: grid;
}

Flexbox - flex-direction

Le display flex nous permet d'aligner notre contenu dans une dimension donnée. On pourra donc aligner notre contenu soit en ligne, soit en colonne:

div {
  display: flex;
  flex-direction: row | row-reverse | column | column-reverse;
}

Flexbox - flex-wrap

flex-wrap: permet ou non le passage à la ligne des éléments enfants.

div {
  display: flex;
  flex-wrap: nowrap | wrap |  wrap-reverse;
}

nowrap

wrap

wrap-reverse

Flexbox - flex-flow

La propriété flex-flow est un combinaison des propriétés flex-direction et flex-wrap:

div {
  display: flex;
  flex-flow: column wrap;
}
element {
  display: flex;
  flex-flow: 'flex-direction' || 'flex-wrap';
}

Flexbox - justify-content

La propriété justify-content nous permet de décider comment justifier les éléments selon l'axe principal.

L'axe principal dépend de flex-direction:

  • horizontal si la valeur est row
  • vertical si la valeur est column
element {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start | flex-end | center | space-between |
  space-around | space-evenly;
}

Attention:
Certaines propriétés/valeurs ne sont pas supportés par tout les navigateurs. Pour vérifier la compatibilité, utiliser le site CanIUse.com : https://caniuse.com/#search=space-evenly

Flexbox - justify-content

flex-start

flex-end

center

space-between

space-around

space-evenly

Flexbox - align-items

La propriété align-items nous aide à aligner le contenu selon l'axe secondaire*.

element {
  display: flex;
  align-items: stretch | flex-start |
    flex-end | center | baseline;
}

*L'axe secondaire sera la perpendiculaire à l'axe principal.

Flexbox - align-content

La propriété align-content fonctionne de façon similaire à justify-content mais agit sur l'axe secondaire et lorsque flex-wrap à une valeur de wrap:

element {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start | flex-end |
    center | space-between | space-around |
    space-evenly | stretch;
}

Flexbox - order

La propriété order s'applique à l'élément enfant. Elle permet de modifier l'ordre d'apparition dans son conteneur en display flex.

parent {
  display: flex;
}

parent element:nth-child(3) {
  order: 1;
}

La valeur prise est un entier (positif ou négatif). Par défaut, les éléments ont une valeur de 0.

flex-grow - flex-shrink

Ces deux propriétés déterminent comment les éléments vont se répartir l'espace non-occupé (avec flex-grow) ou comment ceux-ci vont céder de l'espace (avec flex-shrink) si le conteneur est trop petit.

parent {display: flex;}
parent element:nth-child(1) {flex-grow: 1; flex-shrink: 2;}
parent element:nth-child(2) {flex-grow: 2; flex-shrink: 3;}

La valeur prise est un entier positif. 0 par défaut pour flex-grow, 1 pour flex-shrink.

Dans notre exemple, si l'on a de l'espace disponible, alors pour 3 pixels disponibles, 1 pixel va être attribué au premier élément et 2 au second.

S'il n'y a pas assez d'espace disponible, 2 pixels seront retirés au premier élément et 3 au second.

flex-basis - flex

La propriété flex-basis définit la taille de base de l'élément avant que l'espace disponible de soit réparti:

 /* La valeur par défaut de flex-basis est auto */
parent element:nth-child(1) {
  flex-basis: 2rem;
}

La propriété flex est une combinaison de flex-grow, flex-shrink et flex-basis:

parent element:first-child {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
}
parent element:first-child {
  flex: 0 1 auto; /* valeurs par défaut */
}

align-self

La propriété align-self fonctionne comme align-items mais agit sur l'élément sur lequel elle est appliqué (alors que align-items agit sur tout les enfants du parent):

 /* La valeur par défaut de align-self est auto ou celle définie par le parent */
parent element:nth-child(1) {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

Dans notre exemple, le premier élément est en flex-start, le deuxième en flex-end, le troisième en center, et le dernier en stretch.

Flexbox - Sources

Deux excellentes sources de documentation sont disponibles ici:

  1. MDN
  2. CSS-Tricks

Exercices

Transform & Transition

Transform

La propriété transform permet d'appliquer des transformation à un élément html. Les transformations les plus utilisés sont les suivantes:

/* liste non exhaustive */
img {
  transform: translate(12px, 50%);
  transform: translateX(2em);
  transform: translateY(3in);
  transform: translateZ(2px);
  transform: translate3d(12px, 50%, 3em);

  transform: scale(2, 0.5);
  transform: scaleX(2);
  transform: scaleY(0.5);
  transform: scaleZ(0.3);
  transform: scale3d(2.5, 1.2, 0.3);

  transform: skew(30deg, 20deg);
  transform: skewX(30deg);
  transform: skewY(1.07rad);

  transform: rotate(0.5turn);
  transform: rotateX(10deg);
}

Transition

La propriété transition permet d'appliquer une transition à une transformation plutôt qu'un changement "brutal". Voici un exemple de transition:

img {
  transform: rotate(30deg);
  transition: rotate 2s ease-in 1s;
  transition: 'nom de la propriété?' 'durée' 'effet?' 'retard?';
  transition: <transition-property> | <transition-duration> |
    <transition-timing-function> | <transition-delay>;
}

Dans cet exemple, on appliquera la rotation après 1 seconde, l'animation va durer 2 secondes, et aura un effet d'accélération.

@keyframes

Keyframes est une autre façon d'animer notre css.

img {
  animation-duration: 2s;
  animation-name: identifier;
}

@keyframes identifier {
  0% { top: 0; left: 0; }
  30% { top: 50px; }
  68%, 72% { left: 50px; }
  100% { top: 100px; left: 100%; }
}

On peut également faire appel à la propriété raccourcie animation. On peut voir la documentation détaillé sur le site de mozilla:

Media Queries & responsive

Media queries

Les media queries permettent de spécifier des règles css selon le type d'écran utilisé, son orientation, sa hauteur ou largeur, ce qui nous permettra de faire ainsi une page qui s'adapte à tout les écrans:

main, aside {
  width: 100%
}

@media all and (min-width: 768px) and (max-width: 1280px) {
  main {width: 80%;}
  aside: {20%;}
}

@media all and (min-width: 1281px) {
  main {width: 70%;}
  aside: {30%;}
}

Variables CSS

Définition et utilisation

Lorsqu'au sein d'un même document css, on a une répétition d'une valeur qui est appliqué à différentes propriétés (comme par exemple une couleur qui est réutilisée tout le long du site), on peut la stocker au sein d'une variable.
Cela permet de changer de couleur en un seul endroit pour avoir un effet immédiat sur l’entièreté du site.

:root /* équivalent à html */ {
  --main-color: lightgreen; /* déclaration */
  --main-padding: 10px;
}

element {color: var(--main-color); /* utilisation - renverra lightgreen */}

other_element {
  color: var(--main-color);
  padding: calc(var(--main-padding) * .5) /* calcul possible */
}

@media all and (max-width: 780px) {--main-color: lightblue;} /* re-définition */

Reset - Normalize

Reset

Par défaut, des styles sont appliqués aux éléments html par les navigateurs, ce qui conduit à apprendre "par coeur" les propriétés de nos éléments afin de les supprimer au besoin.

Par exemple, les marges des titres, le style des puces des listes, etc.

On peut télécharger un fichier reset.css afin de réinitialiser les styles de nos éléments html et partir d'une "page blanche" pour définir nos styles css.

Normalize

Le normalize permet quant à lui d'uniformiser les styles par défaut entre navigateurs (car des différences peuvent exister d'un navigateur à l'autre)

C'est une façon de s'assurer que notre visuel sera identique, quelque soit le navigateur utilisé par le client.

Prefixes

Lorsqu'une nouvelle propriété est créée en css, tout les navigateurs ne l'intègrent pas au même rythme, ni de la même façon. Avant qu'il n'y ait une uniformisation, il y a souvent des préfixes à ajouter à notre css pour gérer le comportement dans certains navigateurs:

-moz-: Mozilla Firefox

-ms-: Microsoft

-webkit-: Webkit (Chrome, Safari)

Des outils existent pour le faire pour nous:

element {
    display: -ms-grid;
    display: grid;
}

CSS Grid

CSS Novembre 2019

By Fabio Ginja

CSS Novembre 2019

Slides de formation

  • 323