web-dev-qa-db-fra.com

Flexbox n'emballe pas le redimensionnement du navigateur

J'essaie de redimensionner ma flexbox sur les appareils mobiles et la taille de la fenêtre.

Pour ma vie, je ne sais pas pourquoi cela ne fonctionne pas. La boîte souple doit être redimensionnée et renvoyée à la ligne suivante à mesure que le navigateur se réduit.

Démo

here

CSS/HTML

#flex-container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: left;
  width: 1000px;
  height: 400px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  background-color: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
  overflow: hidden;
}

#left-zone {
  background: #fff;
  height: 75%;
  flex-grow: 0;
  display: flex;
  width: 350px;
  align-items: center;
  justify-content: left;
  min-width: 0;
}

#left-zone .list {
  display: flex;
  list-style: none;
  align-content: stretch;
  flex-direction: column;
  /* flex-grow: 1; */
  flex: 1 1 calc(33.33% - 20px);
  margin: 0;
  padding: 0;
}

.item input {
  display: none;
}

label {
  display: block;
  opacity: 0.5;
  height: 50px;
  text-align: center;
  line-height: 50px;
}

label:hover {
  opacity: 0.75;
  cursor: pointer;
}

/* content slides in on the right side of the flexbox */
.content {
  position: absolute;
  left: 350px;
  top: -400px;
  width: 650px;
  height: 400px;
  -webkit-animation-duration: 0.75s;
  animation-duration: 0.75s;
  -webkit-animation-name: slideout;
  animation-name: slideout;
  -webkit-animation-timing-function: ease-out;
  animation-timing-function: ease-out;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

/* p tag content in the right side of the flexbox */
.content p {
  max-width: 50%;
  text-align: center;
}

#middle-border {
  background-color: #eee;
  height: 75%;
  flex-grow: 1;
  max-width: 2px;
  z-index: 0;
}

/* Right side of flexbox where the content slides in */
#right-zone {
  background-color: #ff000070;
  height: 100%;
  flex-grow: 3;
}




/* ==========Styles only related to the animation slidein: IGNORE============*/
@-webkit-keyframes slidein {
  0% {
    top: -400px;
    opacity: 0;
  }
  100% {
    opacity: 1;
    top: 0;
  }
}
@keyframes slidein {
  0% {
    top: -400px;
    opacity: 0;
  }
  100% {
    opacity: 1;
    top: 0;
  }
}
@-webkit-keyframes slideout {
  0% {
    top: 0;
    opacity: 1;
  }
  100% {
    top: -400px;
    opacity: 0;
  }
}
@keyframes slideout {
  0% {
    top: 0;
    opacity: 1;
  }
  100% {
    top: -400px;
    opacity: 0;
  }
}
input:checked ~ .content {
  -webkit-animation-duration: 0.75s;
  animation-duration: 0.75s;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-timing-function: cubic-bezier(0.455, 0.03, 0.515, 0.955);
  animation-timing-function: cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
body {
  background: #eee;
  font-family: Tahoma;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <meta charset="utf-8">
  <title>Flex Test</title>
</head>
<body>
  <div id="flex-container">
    <div id="left-zone">
      <ul class="list">
        <li class="item">
          <input type="radio" id="radio_strawberries" name="basic_carousel" checked="checked" />
          <label class="label_strawberry" for="radio_strawberries">strawberry</label>
          <div class="content content_strawberry">
            <h1>strawberry</h1>
            <p>The garden strawberry... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_banana" name="basic_carousel"/>
          <label class="label_banana" for="radio_banana">banana</label>
          <div class="content content_banana">
            <h1>banana</h1>
            <p>A banana... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_Apple" name="basic_carousel"/>
          <label class="label_Apple" for="radio_Apple">Apple</label>
          <div class="content content_Apple">
            <h1>Apple</h1>
            <p>The Apple... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_orange" name="basic_carousel"/>
          <label class="label_orange" for="radio_orange">orange</label>
          <div class="content content_orange">
            <h1>orange</h1>
            <p>The orange... blah blah</p>
          </div>
        </li>
      </ul>
    </div>
    <div id="middle-border"></div>
    <div id="right-zone"></div>
  </div>
</body>

</html>

Je voudrais que le côté droit se termine sous le côté gauche à mesure que la résolution de la fenêtre du navigateur diminue, mais je n'arrive pas à comprendre. 

Le contenu situé dans la partie droite de la flexbox est masqué et glisse simplement depuis le haut à l'aide d'images clés CSS. Je suppose que cela pourrait être un problème car la division de contenu sur le côté droit de la flexbox est essentiellement vide

CodePen

apprécier toute aide

7
jpisty

Michael_B explique très bien le problème ici. 

En plus de sa réponse, je dirais seulement que vous travaillez également avec un .content absolu, votre flexbox n'est donc pas une flexbox "normale".

BTW, en utilisant votre HTML, j'ai essayé de le rendre responsable. L'astuce consiste à supprimer toute votre largeur fixe.

Le bootstrap est un moyen possible, mais si vous avez déjà commencé votre travail, vous pouvez le terminer en utilisant uniquement les propriétés CSS et aucun javascript (comme vous le faites). C'est ce que je pense.

J'ai essayé de ne pas changer votre code HTML. J'ai supprimé uniquement <div id="middle-border"></div> car vous pouvez créer une bordure droite dans votre #left-zone .list à l'aide de la propriété box-sizing ... et de la bordure droite, naturellement;)

Dans votre CSS, j'ai changé votre animation avec une opacité plus simple et une transition de traduction (vous devez aller du point A au point B sans autre animation, une transition suffit donc, je pense). Mais bon, ce n’est pas une erreur d’utiliser une animation, je pense que c’est plus simple d’utiliser une transition pour ce travail.

Une autre idée importante consiste à utiliser un CSS qui offre une meilleure cohérence entre les navigateurs dans le style par défaut des éléments HTML. Pour ce faire, j'ai utilisé "normalize.css": https://necolas.github.io/normalize.css/ )

Ceci est le code, espérons que cela aide:

 body {
    background: #eee;
    font-family: Tahoma;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }


  #flex-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    width: 100%; /* no fixed width */
 
    min-height: 400px; /*add min-height for 1 column layout */
    height: 100vh;
    max-width: 1000px;
    
    margin: auto;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
    overflow: hidden;

    flex-direction: column;
    position: relative;
  }

  #left-zone {
    height: 50%;
    flex: 0 0 auto;
    display: flex;
    width: 100%;

  }

  #left-zone .list {
    display: flex;
    list-style: none;
    align-content: stretch;
    flex-direction: column;
    flex: 1 1 auto;
    margin: auto;
    padding: 0;
    box-sizing: border-box;
    
  }

  .item input {
    display: none;
  }

  label {
    display: block;
    opacity: 0.5;
    height: 50px;
    text-align: center;
    line-height: 50px;

    position: relative;
  }

  label:hover {
    opacity: 0.75;
    cursor: pointer;
  }

  /* content slides in on the right side of the flexbox */
  .content {
    position: absolute;
    right: 0;
    bottom: 0;
    opacity: 0;
    transform: translateY(100%);

    height: 50%;
    width: 100%;
    
    transition: 0.5s ease-out;

    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    pointer-events: none;
  }

  /* p tag content in the right side of the flexbox */

  .content p {
    max-width: 50%;
    text-align: center;
  }

  /* Right side of flexbox where the content slides in */
  #right-zone {
    background-color: #ff8f8f;
    width: 100%;
    flex: 1 0 auto;
    height: 50%;
  }

  input:checked ~ .content {
    transform: translateY(0%);
    opacity: 1;
  }

  @media (min-width:480px){
    #flex-container {
      flex-direction: row;
      min-height: auto;
      height: 400px;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }

    #left-zone .list {
      border-right: 2px solid #cccccc;
    }

    .content {
        width: 65%; /* no fixed width */
        height: 100%;
        pointer-events: auto;
        transform: translateY(-100%);
    }

    #left-zone {
        width: 35%; /* no fixed width */
    }

    #right-zone {
      height: 100%;
      width: 65%; /* no fixed width */
    }
  }
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css" rel="stylesheet">
<div id="flex-container">
    <div id="left-zone">
      <ul class="list">
        <li class="item">
          <input type="radio" id="radio_strawberries" name="basic_carousel" checked="checked" />
          <label class="label_strawberry" for="radio_strawberries">strawberry</label>
          <div class="content content_strawberry">
              <h1>strawberry</h1>
              <p>The garden strawberry... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_banana" name="basic_carousel"/>
          <label class="label_banana" for="radio_banana">banana</label>
          <div class="content content_banana">
            <h1>banana</h1>
            <p>A banana... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_Apple" name="basic_carousel"/>
          <label class="label_Apple" for="radio_Apple">Apple</label>
          <div class="content content_Apple">
            <h1>Apple</h1>
            <p>The Apple... blah blah</p>
          </div>
        </li>
        <li class="item">
          <input type="radio" id="radio_orange" name="basic_carousel"/>
          <label class="label_orange" for="radio_orange">orange</label>
          <div class="content content_orange">
            <h1>orange</h1>
            <p>The orange... blah blah</p>
          </div>
        </li>
      </ul>
    </div>
    <div id="right-zone"></div>
  </div>

3
ReSedano

Après un certain temps de travail, j’ai l’approche suivante (responsive) en utilisant Bootstrap 4 et Animate.css plugin en remplacement de vos animations. J'espère que ça vous plait!

$(document).ready(function()
{
    $("input[type='radio']").click(function()
    {
        $("#right-zone .animated").addClass("d-none");
        var target = $(this).attr("target-div");
        $("." + target).toggleClass("d-none");
    });
});
#flex-container {
    min-height: 50vh;
    margin-top: 25vh;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}

/* On XS screen devices, use all the available height */

@media(max-width:576px)
{
    #flex-container {
        min-height: 100vh;
        margin-top: 0vh;
    }
}

#right-zone {
    background-color: rgba(255,0,0,0.6);
}

.item input {
    display: none;
}

label {
    opacity: 0.5;
    height: 50px;
    line-height: 50px;
}

label:hover {
    opacity: 0.75;
    cursor: pointer;
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"/>

<div class="container-fluid">
<div class="row w-75 mx-auto" id="flex-container">

  <div class="col-sm-4 bg-light" id="left-zone">
  <div class="d-flex h-100 align-items-center justify-content-center">
  <div class="items-container text-center">

    <div class="item">
      <input type="radio" id="radio_strawberries" target-div="content_strawberry"/>
      <label class="label_strawberry" for="radio_strawberries">strawberry</label>
    </div>

    <div class="item">
      <input type="radio" id="radio_banana" target-div="content_banana"/>
      <label class="label_banana" for="radio_banana">banana</label>
    </div>

    <div class="item">
      <input type="radio" id="radio_Apple" target-div="content_Apple"/>
      <label class="label_Apple" for="radio_Apple">Apple</label>
    </div>

    <div class="item">
      <input type="radio" id="radio_orange" target-div="content_orange"/>
      <label class="label_orange" for="radio_orange">orange</label>
    </div>

  </div>
  </div>
  </div>
  
  <div class="col-sm-8" id="right-zone">
  <div class="d-flex h-100 align-items-center justify-content-center text-center">

    <div class="content_strawberry animated fadeInDown">
      <h1>strawberry</h1>
      <p>The garden strawberry... blah blah</p>
    </div>

    <div class="content_banana d-none animated fadeInDown">
      <h1>banana</h1>
      <p>A banana... blah blah</p>
    </div>

    <div class="content_Apple d-none animated fadeInDown">
      <h1>Apple</h1>
      <p>The Apple... blah blah</p>
    </div>

    <div class="content_orange d-none animated fadeInDown">
      <h1>orange</h1>
      <p>The orange... blah blah</p>
    </div>

  </div>
  </div>

</div>
</div>

2
Shidersz

Les articles flexibles sont emballés dans leurs conteneurs. Cela semble évident, mais c'est le concept clé à comprendre ici.

Si les éléments flex se trouvaient dans un conteneur dont la largeur était liée à la largeur de la fenêtre - il s'agirait généralement d'un conteneur prenant le width: 100% de l'élément body -, les éléments flex se lieraient par rapport à la largeur de la fenêtre. Une fenêtre de redimensionnement aurait un impact direct sur le conteneur Flex, ce qui aurait un impact direct sur les éléments Flex.

Cependant, dans votre cas, le conteneur flex est pas lié à la largeur de la fenêtre. Il a une largeur différente:

#flex-container {
  display: flex;
  flex-wrap: wrap;
  width: 1000px;
}

Dans ce cas, les éléments flexibles sont disposés par rapport au grand espace de 1000 pixels, pas à l’espace de la fenêtre. Étant donné que les éléments et la fenêtre d'affichage n'ont aucune association, ils n'ont aucune raison de faire quoi que ce soit lorsque la fenêtre d'affichage est redimensionnée.

2
Michael_B

En effet, vous attribuez la propriété flex-wrap au mauvais élément . L'ensemble de #left-zone est l'un des enfants de l'élément #flex-container. Vous devez modifier l'ordre de placement des divs pour que la liste soit dans un seul div et que la section content soit un autre div. Ensuite, le contenu sera bouclé.

0
Quasar