Demonstration de flex-grow, flex-shrink, flex-basis

Chaque bloc ci-dessous montre un cas concret, avec une mise en page flex differente. Tu peux redimensionner la fenetre pour faire apparaitre le comportement de croissance et de retrecissement.

1. Barre de navigation

Le menu central utilise flex-grow: 1 pour remplir tout l'espace disponible.

Logo a gauche et bouton a droite gardent leur taille, le menu au centre s'etire ou se compresse.
Demonstration flex-grow, flex-shrink, flex-basis

Demonstration de flex-grow, flex-shrink, flex-basis

Chaque bloc ci-dessous montre un cas concret, avec une mise en page flex differente. Tu peux redimensionner la fenetre pour faire apparaitre le comportement de croissance et de retrecissement.

1. Barre de navigation

Le menu central utilise flex-grow: 1 pour remplir tout l'espace disponible.

Logo a gauche et bouton a droite gardent leur taille, le menu au centre s'etire ou se compresse.
Demonstration flex-grow, flex-shrink, flex-basis

Demonstration de flex-grow, flex-shrink, flex-basis

Chaque bloc ci-dessous montre un cas concret, avec une mise en page flex differente. Tu peux redimensionner la fenetre pour faire apparaitre le comportement de croissance et de retrecissement.

1. Barre de navigation

Le menu central utilise flex-grow: 1 pour remplir tout l'espace disponible.

Logo a gauche et bouton a droite gardent leur taille, le menu au centre s'etire ou se compresse.
<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="UTF-8" />
    <title>Demonstration flex-grow, flex-shrink, flex-basis</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <h1>
      Demonstration de <code>flex-grow</code>, <code>flex-shrink</code>,
      <code>flex-basis</code>
    </h1>
    <p>
      Chaque bloc ci-dessous montre un cas concret, avec une mise en page flex
      differente. Tu peux redimensionner la fenetre pour faire apparaitre le
      comportement de croissance et de retrecissement.
    </p>

    <!-- 1. Barre de navigation -->
    <section class="demo">
      <h2 class="demo-title">1. Barre de navigation</h2>
      <p class="demo-subtitle">
        Le menu central utilise <code>flex-grow: 1</code> pour remplir tout
        l'espace disponible.
      </p>
      <div class="demo-desc">
        Logo a gauche et bouton a droite gardent leur taille, le menu au centre
        s'etire ou se compresse.
      </div>

      <div class="preview">
        <nav class="nav">
          <div class="nav-logo">Logo</div>
          <div class="nav-menu">
            Accueil - Services - Portfolio - Contact - Plus de liens...
          </div>
          <button class="nav-cta">Contact</button>
        </nav>
      </div>
    </section>

    <!-- 2. Trois cards avec ratio 2:1:1 -->
    <section class="demo">
      <h2 class="demo-title">2. Trois cartes avec largeur proportionnelle</h2>
      <p class="demo-subtitle">
        La premiere carte a <code>flex-grow: 2</code>, les deux autres
        <code>flex-grow: 1</code>.
      </p>
      <div class="demo-desc">
        Total de croissance = 2 + 1 + 1 = 4 parts. La premiere carte occupe la
        moitie de la ligne.
      </div>

      <div class="preview">
        <div class="cards">
          <div class="card card-1">Card 1<br />(flex-grow: 2)</div>
          <div class="card card-2">Card 2<br />(flex-grow: 1)</div>
          <div class="card card-3">Card 3<br />(flex-grow: 1)</div>
        </div>
      </div>
    </section>

    <!-- 3. Layout sidebar + contenu -->
    <section class="demo">
      <h2 class="demo-title">3. Layout sidebar + contenu</h2>
      <p class="demo-subtitle">
        Comparaison entre <code>flex-basis</code> et <code>width</code> pour
        definir une largeur fixe.
      </p>
      <div class="demo-desc">
        Les deux approches fonctionnent de maniere similaire ici, mais
        <code>flex-basis</code> est specifique a Flexbox et sera prise en compte
        avant <code>width</code>. <code>width</code> est une propriete CSS
        generale qui fonctionne partout.
      </div>

      <div class="preview">
        <p class="comparison-label">Avec flex-basis: 250px :</p>
        <div class="layout">
          <aside class="sidebar">
            Sidebar (flex-basis)<br /><br />
            Lien 1<br />
            Lien 2<br />
            Lien 3
          </aside>
          <main class="content">
            <strong>Contenu principal</strong><br /><br />
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis
            omnis harum commodi ratione consequatur, inventore doloremque
            molestiae exercitationem.
          </main>
        </div>

        <p class="comparison-label">Avec width: 250px :</p>
        <div class="layout-width">
          <aside class="sidebar-width">
            Sidebar (width)<br /><br />
            Lien 1<br />
            Lien 2<br />
            Lien 3
          </aside>
          <main class="content-width">
            <strong>Contenu principal</strong><br /><br />
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis
            omnis harum commodi ratione consequatur, inventore doloremque
            molestiae exercitationem.
          </main>
        </div>
      </div>
    </section>

    <!-- 4. Grille responsive -->
    <section class="demo">
      <h2 class="demo-title">4. Grille responsive sans media queries</h2>
      <p class="demo-subtitle">
        Comparaison entre <code>flex-basis</code> et <code>width</code> pour une
        grille responsive.
      </p>
      <div class="demo-desc">
        <code>flex-basis</code> definit la taille de depart AVANT que
        flex-grow/shrink agissent. <code>width</code> avec
        <code>flex-basis: auto</code> peut donner des resultats differents car
        la taille de base depend du contenu.
      </div>

      <div class="preview">
        <p class="comparison-label">Avec flex-basis: 250px :</p>
        <div class="grid">
          <div class="item">Card 1</div>
          <div class="item">Card 2</div>
          <div class="item">Card 3</div>
          <div class="item">Card 4</div>
          <div class="item">Card 5</div>
          <div class="item">Card 6</div>
        </div>

        <p class="comparison-label">Avec width: 250px :</p>
        <div class="grid-width">
          <div class="item-width">Card 1</div>
          <div class="item-width">Card 2</div>
          <div class="item-width">Card 3</div>
          <div class="item-width">Card 4</div>
          <div class="item-width">Card 5</div>
          <div class="item-width">Card 6</div>
        </div>
      </div>
    </section>

    <!-- 5. Empecher le bouton de se faire ecraser -->
    <section class="demo">
      <h2 class="demo-title">
        5. Bouton protege grace a <code>flex-shrink: 0</code>
      </h2>
      <p class="demo-subtitle">
        Le texte peut se compresser, le bouton garde sa taille.
      </p>
      <div class="demo-desc">
        Le texte a <code>flex-shrink: 1</code>. Le bouton a
        <code>flex-shrink: 0</code> et refuse de devenir minuscule.
      </div>

      <div class="preview">
        <div class="row">
          <div class="row-text">
            Tres long texte d'explication : Lorem ipsum dolor sit amet,
            consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
            labore et dolore magna aliqua.
          </div>
          <button class="row-button">Acheter maintenant</button>
        </div>
      </div>
    </section>

    <!-- 6. flex-basis comme taille de depart -->
    <section class="demo">
      <h2 class="demo-title">6. flex-basis comme taille de depart</h2>
      <p class="demo-subtitle">
        Trois blocs avec bases differentes: 150px, 250px, 100px.
      </p>
      <div class="demo-desc">
        Tous peuvent grandir et retrecir, mais leur largeur initiale est definie
        par <code>flex-basis</code>.
      </div>

      <div class="preview">
        <div class="line">
          <div class="box box-a">A<br />(base: 150px)</div>
          <div class="box box-b">B<br />(base: 250px)</div>
          <div class="box box-c">C<br />(base: 100px)</div>
        </div>
      </div>
    </section>
  </body>
</html>

CSS

/* --------------------------------------------------
   1. Barre de navigation (nav, menu qui prend l'espace)
-------------------------------------------------- */
.nav {
  display: flex;
  padding: 1rem;
  border: 1px solid #ccc;
  gap: 1rem;
  background: #fff;
}

/* Logo : taille naturelle, ne grandit pas, ne retrecit pas */
.nav-logo {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: auto;
  font-weight: bold;
}

/* Menu : remplit l'espace disponible */
.nav-menu {
  flex-grow: 1; /* absorbe tout l'espace libre */
  flex-shrink: 1; /* peut retrecir si peu de place */
  flex-basis: auto;
  border: 1px dashed #999;
  padding: 0.5rem;
}

/* Bouton : taille naturelle, fixe */
.nav-cta {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: auto;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  border: 1px solid #555;
  background: #eee;
  cursor: pointer;
}

/* --------------------------------------------------
   2. Trois cards (la 1ere deux fois plus large)
-------------------------------------------------- */
.cards {
  display: flex;
  gap: 1rem;
}

.card {
  border: 1px solid #ccc;
  padding: 1rem;
  background: #fff;
}

/* Card 1 : 2 parts de croissance */
.card-1 {
  flex-grow: 2; /* 2 parts */
  flex-shrink: 1;
  flex-basis: 0; /* on part de 0, tout via flex-grow */
  background: #f9f5ff;
}

/* Card 2 & 3 : 1 part chacune */
.card-2,
.card-3 {
  flex-grow: 1; /* 1 part chacune */
  flex-shrink: 1;
  flex-basis: 0;
  background: #f5fbff;
}

/* --------------------------------------------------
   3. Layout sidebar + contenu
-------------------------------------------------- */
.layout {
  display: flex;
  min-height: 150px;
  border: 1px solid #ccc;
  background: #fff;
}

/* Sidebar fixe avec flex-basis */
.sidebar {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: 250px; /* largeur fixe */
  background: #f5f5f5;
  padding: 1rem;
  border-right: 1px solid #ddd;
}

/* Contenu qui prend le reste */
.content {
  flex-grow: 1; /* recupere tout l'espace restant */
  flex-shrink: 1; /* peut retrecir si vraiment necessaire */
  flex-basis: auto;
  padding: 1rem;
}

/* Version avec width au lieu de flex-basis */
.layout-width {
  display: flex;
  min-height: 150px;
  border: 1px solid #ccc;
  background: #fff;
}

.sidebar-width {
  flex-grow: 0;
  flex-shrink: 0;
  width: 250px; /* width au lieu de flex-basis */
  background: #fff3e0;
  padding: 1rem;
  border-right: 1px solid #ddd;
}

.content-width {
  flex-grow: 1;
  flex-shrink: 1;
  padding: 1rem;
}

/* --------------------------------------------------
   4. Grille responsive sans media queries
-------------------------------------------------- */
.grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.grid .item {
  flex-grow: 1; /* peut grandir */
  flex-shrink: 1; /* peut retrecir */
  flex-basis: 250px; /* largeur de base souhaitee */
  border: 1px solid #ccc;
  padding: 1rem;
  background: #fff;
  text-align: center;
}

/* Version avec width - NE FONCTIONNE PAS pareil */
.grid-width {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.grid-width .item-width {
  flex-grow: 1;
  flex-shrink: 1;
  width: 250px; /* width au lieu de flex-basis */
  /* flex-basis: auto par defaut */
  border: 1px solid #ccc;
  padding: 1rem;
  background: #fff3e0;
  text-align: center;
}

/* --------------------------------------------------
   5. Empecher le bouton de se faire ecraser
-------------------------------------------------- */
.row {
  display: flex;
  border: 1px solid #ccc;
  padding: 1rem;
  gap: 1rem;
  background: #fff;
}

.row-text {
  flex-grow: 1; /* prend l'espace disponible */
  flex-shrink: 1; /* peut se compresser */
  flex-basis: auto;
}

.row-button {
  flex-grow: 0; /* ne prend pas d'espace en plus */
  flex-shrink: 0; /* ne retrecit pas */
  flex-basis: auto; /* garde sa largeur minimale */
  white-space: nowrap;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  border: 1px solid #555;
  background: #eee;
  cursor: pointer;
}

/* --------------------------------------------------
   6. flex-basis comme taille de depart differente
-------------------------------------------------- */
.line {
  display: flex;
  gap: 1rem;
}

.box {
  border: 1px solid #ccc;
  padding: 1rem;
  background: #fff;
  text-align: center;
}

.box-a {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 150px; /* base de 150px */
  background: #ffeef0;
}

.box-b {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 250px; /* base de 250px */
  background: #e7fff0;
}

.box-c {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 100px; /* base de 100px */
  background: #eef3ff;
}

/* --------------------------------------------------
   Styles globaux de la page
-------------------------------------------------- */

body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
    sans-serif;
  margin: 0;
  padding: 2rem;
  line-height: 1.5;
  background: #f3f3f3;
}

.demo {
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 1.5rem;
  margin-bottom: 2rem;
}

.demo + .demo {
  margin-top: 0;
}

.demo-desc {
  margin-bottom: 1rem;
  color: #555;
}

.demo-title {
  margin-bottom: 0.25rem;
}

.demo-subtitle {
  margin-top: 0;
  font-size: 0.9rem;
  color: #888;
}

.preview {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 4px;
  background: #fafafa;
  border: 1px dashed #ccc;
}

.comparison-label {
  font-weight: bold;
  margin: 1rem 0 0.5rem 0;
  color: #666;
  font-size: 0.85rem;
}

.comparison-label:first-of-type {
  margin-top: 0;
}