Travaux Pratiques — Technologies et Développement Web

Exercice 1 : Sélecteurs et spécificité

1.1 Sélecteurs

<nav class="main-nav">
  <ul>
    <li><a href="/" class="active">Accueil</a></li>
    <li><a href="/about">À propos</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>
<main>
  <article class="post featured"> ... </article>
  <article class="post"> ... </article>
</main>

Q1 — Tous les liens dans la navigation :

.main-nav a

Q2 — Uniquement le lien actif :

.main-nav a.active

Q3 — L'article avec la classe featured :

.post.featured

Q4 — Le premier paragraphe de chaque article :

article p:first-of-type

Q5 — Les éléments <li> pairs :

li:nth-child(even)

1.2 Spécificité

Q1 — Spécificité croissante :

  1. p → (0,0,1)
  2. .text → (0,1,0)
  3. p.text → (0,1,1)
  4. #main → (1,0,0)
  5. #main .text p → (1,1,1)

Q2 — Même spécificité, laquelle gagne ?

La règle déclarée en dernier dans la feuille de style l'emporte (ordre de cascade).

Q3 — Pourquoi éviter !important ?

!important court-circuite la cascade et rend le code difficile à maintenir. Il ne peut être écrasé que par un autre !important, ce qui crée une escalade incontrôlable.

Exercice 2 : Box Model

2.1 Comprendre le Box Model

.box {
    width: 300px;
    padding: 20px;
    border: 5px solid #333;
    margin: 15px;
}

Q1 — Largeur totale avec content-box :

300 + (20×2) + (5×2) = 350px

Q2 — Largeur totale avec border-box :

300px — padding et bordure sont inclus dans la largeur déclarée.

Q3 — Reset universel :

*, *::before, *::after {
    box-sizing: border-box;
}

2.2 Centrer un élément

/* Horizontal uniquement */
.box {
    width: 600px;
    margin: 0 auto;
}

/* Horizontal + vertical */
body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}
.box {
    width: 600px;
}

Exercice 3 : Flexbox

3.1 Barre de navigation

.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 24px;
    background: #333;
}
.nav-links {
    display: flex;
    list-style: none;
    gap: 20px;
    margin: 0; padding: 0;
}
.nav-links a { color: #fff; text-decoration: none; }

Résultat :

3.2 Cartes de même hauteur

.cards {
    display: flex;
    gap: 20px;
}
.card {
    display: flex;
    flex-direction: column;
    flex: 1;
    border: 1px solid #ddd;
    padding: 16px;
    border-radius: 4px;
}
.card-link {
    margin-top: auto; /* pousse le bouton vers le bas */
    display: inline-block;
    padding: 8px 16px;
    background: #2563eb;
    color: #fff;
    text-decoration: none;
    border-radius: 4px;
    text-align: center;
}

Résultat :

Carte 1

Contenu court.

En savoir plus

Carte 2

Contenu beaucoup plus long pour tester l'alignement vertical des boutons.

En savoir plus

Carte 3

Contenu moyen.

En savoir plus

Exercice 4 : CSS Grid

4.1 Grille de cartes responsive

.grid-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
}

Résultat :

Carte 1
Carte 2
Carte 3
Carte 4
Carte 5
Carte 6

4.2 Layout complet avec Grid Areas

.page-layout {
    display: grid;
    grid-template-areas:
        "header  header"
        "sidebar main"
        "footer  footer";
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto 1fr auto;
    min-height: 100vh;
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Résultat :

Header
Sidebar
Contenu principal

Exercice 5 : Responsive Design

5.1 Mobile First

/* Base mobile */
.container { width: 100%; padding: 15px; }
.nav-menu  { display: flex; flex-direction: column; gap: 5px; }
.content   { display: block; }
.sidebar   { display: none; }

/* Tablette — à partir de 768px */
@media (min-width: 768px) {
    .container { max-width: 768px; margin: 0 auto; }
    .nav-menu  { flex-direction: row; gap: 20px; }
    .content   { display: flex; gap: 20px; }
    .sidebar   { display: block; width: 220px; flex-shrink: 0; }
}

/* Desktop — à partir de 1024px */
@media (min-width: 1024px) {
    .container { max-width: 1200px; }
    .sidebar   { width: 280px; }
}

Exercice 6 : Variables CSS et thèmes

6.1 Système de couleurs

:root {
    --color-bg:      #ffffff;
    --color-text:    #222222;
    --color-primary: #2563eb;
    --color-surface: #f5f5f5;
    --color-border:  #e0e0e0;
}

[data-theme="dark"] {
    --color-bg:      #1a1a1a;
    --color-text:    #eeeeee;
    --color-primary: #60a5fa;
    --color-surface: #2a2a2a;
    --color-border:  #444444;
}

body {
    background-color: var(--color-bg);
    color: var(--color-text);
}

Résultat (cliquez pour changer de thème) :

Texte principal — couleur primaire

Ceci est une carte utilisant --color-surface et --color-border.

Exercice 7 : Transitions et animations

7.1 Bouton animé

.btn {
    padding: 10px 24px;
    background: #2563eb;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.2s ease,
                box-shadow 0.2s ease,
                transform 0.2s ease;
}
.btn:hover {
    background: #1d4ed8;
    box-shadow: 0 6px 16px rgba(37, 99, 235, 0.4);
    transform: translateY(-2px);
}
.btn:active {
    transform: translateY(0);
    box-shadow: none;
}

Résultat (survolez le bouton) :

7.2 Animation de chargement

.spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #e0e0e0;
    border-top-color: #2563eb;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

Résultat :


Exercice 8 : Quiz de révision

1. Quel sélecteur a la spécificité la plus haute ?

Un sélecteur ID (#) vaut (1,0,0), ce qui surpasse n'importe quelle combinaison de classes.

2. Avec box-sizing: border-box, width: 200px et padding: 20px, la largeur totale est :

Avec border-box, le padding est absorbé à l'intérieur de la largeur déclarée. La largeur reste 200px.

3. Pour centrer avec Flexbox dans les deux axes :

justify-content centre sur l'axe principal (horizontal), align-items sur l'axe croisé (vertical). Les deux sont nécessaires.

4. La valeur 1fr en CSS Grid signifie :

fr (fraction unit) divise l'espace libre proportionnellement. Par exemple 1fr 2fr donne 1/3 et 2/3.

5. L'approche "Mobile First" utilise :

On écrit les styles de base pour mobile, puis on utilise @media (min-width: ...) pour enrichir la mise en page sur les grands écrans.