10 votes

Pourquoi flex donne-t-il à l'élément hr une largeur de 0 ?

Lorsque j'essaie de mettre un élément hr à l'intérieur d'un conteneur avec display: flex, il disparaît. (Si je supprime display: flex, il réapparaît, donc je suis sûr que c'est la cause.)

J'ai lu sur un article de blog que flex fait en sorte que le hr ait une largeur de zéro, ce que j'ai confirmé en lui donnant une largeur de 100 % (le faisant réapparaître), mais aucune explication n'a été donnée.

Par curiosité (j'ai simplement mis le hr en dehors du conteneur flex pour résoudre le problème), pourquoi cela se produit-il ? Est-ce que l'utilisation de flexbox fera également disparaître d'autres éléments aléatoires ?

Je ne pense pas qu'autre chose dans mon code en soit la cause, mais voici mon code complet au cas où :

* {
  /* Fait en sorte que la largeur et la hauteur incluent le padding, la bordure */
  box-sizing: border-box;
}

body {
  font-family: "Quicksand", sans-serif;
  margin: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  color: #2d3c49;
  text-transform: uppercase;
}

h1 {
  font-weight: 200;
  /* Les navigateurs affichent généralement h1 comme 2em */
  font-size: 2.6em;
  margin-bottom: 0;
}

/* Ajoute un peu d'espace au-dessus du sous-titre (définir la marge basse de h1 à 0) */

header h4 {
  margin-top: 7px;
}

/* Contenu en haut */

header {
  display: flex;
  max-width: 1000px;
  margin: 0 auto;
  margin-top: 1em;
  /* Centre verticalement le logo  */
  align-items: center;
}

/* Logo img */

.logo {
  height: 90px;
  width: auto;
  margin-right: auto;
}

/* Seul le sous-titre n'est pas aligné tout à fait à droite ; cela le fixe. À FAIRE : comprendre pourquoi cela ne s'applique pas au texte de h1 */

.header-text {
  display: flex;
  justify-content: flex-end;
}

hr {
  background-color: #7d97ad;
  max-width: 1000px;
  margin-bottom: 1em;
  border: none;
  height: 3px;
}

.main-image {
  max-width: 1000px;
  height: auto;
}

/* S'applique au contenu dans l'élément 

    Natalie Cardot
    Développeur web Front-End

    Travaux en vedette

      Projet n° 1
      Lorem ipsum dolor sit amet, consectetur adipiscing elit.

      Projet n° 2
      Lorem ipsum dolor sit amet, consectetur adipiscing elit.

      Projet n° 3
      Lorem ipsum dolor sit amet, consectetur adipiscing elit.

  Créé par moi

9voto

Michael_B Points 15556

El hr a des styles par défaut définis par le navigateur. Par exemple, voici ce que fait Chrome :

enter image description here

Dans un conteneur flexible, auto Les marges consomment tout l'espace libre dans la direction de la marge.

Alors -webkit-margin-start: auto (en LTR, l'équivalent de margin-left: auto ) et -webkit-margin-end: auto (en LTR, l'équivalent de margin-right: auto ), consomme tout l'espace libre à gauche et à droite de l'élément hr en le compressant en width: 0 (puisqu'il n'y a pas de contenu à l'intérieur).

Vous pouvez remplacer ces auto les marges avec width: 100% . Mais il est probablement plus efficace de remplacer simplement margin: auto con margin: 0 .

Mais même alors, dans ce cas, une fois que vous avez enlevé le auto les marges, align-items: center de la part des parents.

enter image description here

Cette option remplace l'option par défaut align-items: stretch et fait la même chose que la gauche/droite auto des marges. Encore une fois, le hr est compressé en width: 0 .

Donc, faites ces deux ajustements à votre hr règle :

hr {
  margin: 0;
  align-self: stretch;
}

* {
  /* Makes width and height include padding, border */
  box-sizing: border-box;
}

body {
  font-family: "Quicksand", sans-serif;
  margin: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  color: #2d3c49;
  text-transform: uppercase;
}

h1 {
  font-weight: 200;
  /* Browsers typically display h1 as 2em */
  font-size: 2.6em;
  margin-bottom: 0;
}

/* Adds a bit of space above subtitle (set h1 bottom margin to 0) */

header h4 {
  margin-top: 7px;
}

/* Top content */

header {
  display: flex;
  max-width: 1000px;
  margin: 0 auto;
  margin-top: 1em;
  /* Vertically centers logo  */
  align-items: center;
}

/* logo img */

.logo {
  height: 90px;
  width: auto;
  margin-right: auto;
}

/* Only subtitle isn't aligned all the way to the right; this fixes it. TODO: figure out why doesn't apply to h1 text */

.header-text {
  display: flex;
  justify-content: flex-end;
}

hr {
  background-color: #7d97ad;
  max-width: 1000px;
  /* margin-bottom: 1em; */
  border: none;
  height: 3px;
  margin: 0 0 1em 0;    /* NEW */
  align-self: stretch;  /* NEW */
}

.main-image {
  max-width: 1000px;
  height: auto;
}

/* Applies to content within <main> element (excludes header, footer) */

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  max-width: 1000px;
  margin: 0 auto;
}

/* Applies to project section (including header text) */

.container-projects {
  display: flex;
  /* Parent container needs this for flex-item to take full width in row */
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: space-between;
  margin: 2em 0;
}

.portfolio-header {
  /* Puts header in its own row without removing from container with row flex direction (setting parent container to wrap also required) */
  width: 100%;
  text-align: left;
  color: #7d97ad;
}

/* Div containing single project's title, image, text */

/* TODO: add declarations */

.project {
  width: 300px;
  height: auto;
}

.project p,
h3 {
  text-align: center;
}

/* Images cropped with 3:2 ratio, scaled resolution down to 600 x 400 */

.project-image {
  width: 300px;
  height: auto;
}

footer {
  text-align: center;
  margin-top: 1em;
  background-color: #ccc;
  color: white;
  padding: 2em;
  font-size: 1.1em;
}

/* Remove default 1em margin-top */

footer p {
  margin-top: 0;
}

/* Applies to Font Awesome social icons */

.fab {
  margin: 0 0.5em;
  color: white;
}

/* Changes social icon color to dark grey on hover */

.fab:hover {
  color: #2d3c49;
}

/* Media queries (breakpoints correspond to Bootstrap breakpoints). 1rem = 16px */

/* Small devices (landscape phones) */

@media screen and (max-width: 767px) {
  h1 {
    font-size: 2em;
  }
  h2 {
    font-size: 1.5em;
  }
  h3 {
    font-size: 1.3em;
  }
  h4 {
    font-size: 1.1em;
  }
  /* Doesn't seem to be doing anything TODO: find out why   */
  .portfolio-header {
    margin-bottom: 1em;
  }
  /* TODO: make slightly wider  */
  .container-projects {
    margin: 1.5em 0 0 0;
  }
  header {
    margin: 0 1em 0 0;
  }
  header,
  .container,
  footer {
    max-width: 100%;
  }
  /* Must specify max-width for img even though parent .container has the same declaration because max-width isn't inherited */
  .container img {
    max-width: 100%;
  }
  .project {
    /* Centers projects (aligned left otherwise) */
    margin: 0 auto;
  }
  /* Aligns portfolio header text flush left of portfolio rows */
  .portfolio-header {
    width: 300px;
    margin: 10px auto;
  }
  .logo {
    height: 50px;
    width: auto;
  }
}

/* Tablets */

@media screen and (max-width: 991px) {
  h1 {
    font-size: 1.7rem;
  }
}

/* Small laptops */

@media screen and (max-width: 1199px) {
  h1 {
    font-size: 2rem;
  }
}

<header>
  <img src="https://image.ibb.co/jVeP4S/udacity_logo.png" alt="Udacity logo" class="logo">
  <!-- Header is set to display: flex, and it only works on direct children. Without the div, its default row alignment puts header text side by side, but inside a div, it works on the div as a block and since header text items are no longer direct children, it has no effect on them -->
  <div>
    <h1>Natalie Cardot</h1>
    <h4 class="header-text">Front-End Web Developer</h4>
  </div>
</header>
<!-- TODO: put inside main? But makes it disappear -->

<main class="container">
  <hr>
  <img src="https://image.ibb.co/cTcuM7/using_laptop_large.jpg" alt="Woman using laptop at home during the day" class="main-image">
  <section class="container-projects">
    <h2 class="portfolio-header">Featured Work</h2>
    <div class="project">
      <img class="project-image" src="https://image.ibb.co/hv4c8n/santorini_small.jpg" alt="View from island of Santorini on a sunny day">
      <h3>Project No. 1</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
    <div class="project">
      <img class="project-image" src="https://image.ibb.co/c9sKM7/coast_small.jpg" alt="Distant view of a rugged island with a sailboat nearby">
      <h3>Project No. 2</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
    <div class="project">
      <img class="project-image" src="https://image.ibb.co/eO9oES/mediterranean_small.jpg" alt="Bird's eye view of a rocky beach with clear turquoise waters">
      <h3>Project No. 3</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
  </section>
  <!-- End of container-project -->
</main>
<footer>
  <p>Created by me</p>
  <!-- "fab" prefix new in Font Awesome version 5 (released 3/18) -->
  <a href="https://github.com/nataliecardot" target="_blank"><i class="fab fa-github fa-lg"></i></a>
  <a href="https://codepen.io/nataliecardot/"><i class="fab fa-codepen fa-lg"></i></a>
  <a href="https://twitter.com/nataliecardot/"><i class="fab fa-twitter fa-lg"></i></a>
  <a href="https://www.linkedin.com/in/natalie-cardot/" target="_blank"><i class="fab fa-linkedin-in fa-lg"></i></a>
</footer>

Notez que flex auto ont la priorité sur les propriétés d'alignement des mots clés (comme les marges justify-content y align-items ). Si un auto est définie, elle s'applique en premier, consommant tout l'espace libre sur la ligne. align-items passe la seconde, mais il n'y a plus d'espace libre, donc il ne peut rien faire.

C'est pourquoi, dans le code ci-dessus, align-items ne fait rien jusqu'à ce que le auto les marges sont supprimées.

8.1. S'aligner sur auto marges

Avant l'alignement par justify-content y align-self tout l'espace libre positif est distribué à auto marges dans cette dimension.

Si l'espace libre est distribué à auto les marges, l'alignement propriétés d'alignement n'auront aucun effet dans cette dimension car les marges auront volé tout l'espace libre restant après la flexion.

Plus de détails sur flex auto les marges :

0 votes

J'ai eu un problème similaire. Lorsque vous placez un hr dans un conteneur flex avec une direction de colonne définie, la hauteur sera de 0 même en appliquant margin: 0. La solution que j'ai trouvée est qu'au lieu de définir la height, il faut définir la min-height pour le hr. Je devrais également mentionner que le hr a une couleur de fond définie (gradient) et que sa bordure est nulle.

6voto

Craig Scott Points 814

Flex casse la marge-left: auto et la marge-right: auto de la balise HR. Essayez d'ajouter ceci à votre CSS.

hr {margin-left:0;margin-right:0}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X