Comment implémenter cette mise en page réactive à l'aide de flexbox
P粉733166744
P粉733166744 2024-02-26 19:29:01
0
2
411

Je crée une application React qui affiche un nombre xy de cartes et un seul widget dans un conteneur Flex. Toutes les cartes ont la même largeur et hauteur, mais la hauteur du widget est égale à 卡片高度 * 2 + row-gap. La largeur du conteneur change en fonction de la largeur de la fenêtre d'affichage et doit ressembler visuellement à 2 ou 3 colonnes avec des cartes respectivement. Pour plus de clarté, j'ai fourni une image maquette de la mise en page requise, avec les widgets représentés en bleu.

Peu importe ce que j'essaie, je n'arrive pas à afficher les widgets dans la bonne position sans changer la hauteur de la ligne en fonction de sa taille, laissant une "ligne vide" où 1 ou 2 cartes supplémentaires doivent être rendues, comme indiqué ci-dessous. .

Ma solution actuelle implique Javascript et, en fonction de la largeur de la fenêtre d'affichage, je charge 2 ou 4 cartes dans un petit conteneur Flex séparé, qui est rendu comme le premier enfant du conteneur Flex principal. Cette solution de contournement fonctionne très bien visuellement, mais rend mon code plus complexe car je dois couvrir de nombreuses situations différentes pour qu'il fonctionne correctement. J'aimerais atteindre le même objectif en utilisant CSS/flexbox, mais je suis encore un débutant et je n'ai jamais fait une mise en page comme celle-ci auparavant et je n'ai évidemment aucune idée de comment le faire. Le widget ne peut pas 绝对定位 car cela interromprait la fonctionnalité de défilement de ses éléments enfants.

Je fournis des mesures HTML et CSS de test dans des proportions correctes au cas où cela aiderait.

.container {
  margin: 50px 300px;
  display: flex;
  flex-wrap: wrap;
  row-gap: 20px;
  column-gap: 20px;
  min-width: 320px; /* Width for 2 columns */
  max-width: 490px; /* Width for 3 columns */
  border: 3px solid rgb(0, 22, 117);
}

.card {
  width: 150px;
  height: 100px;
  background-color: bisque;
}

.widget {
  height: 220px; /* card height * 2 + row-gap */
  width: 150px;
  background-color: rgb(134, 204, 245);
}
<div class="container">
  <div class="widget"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
</div>

<!-- Original jsx
<div className='container'>
  <div className='widget'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
</div>
-->

Je veux vraiment apprendre à créer des mises en page comme celle-ci dans Flexbox, non seulement pour mon projet actuel, mais aussi pour élargir mes connaissances et ma compréhension. Si vous avez des idées sur la façon de résoudre ce problème, aidez-moi. Merci d'avance :)

P粉733166744
P粉733166744

répondre à tous(2)
P粉391677921

Cela peut être fait en utilisant une disposition en grille, aucun JavaScript requis, voici un exemple :

.container {
  margin: 50px 300px;
  display: grid;
  /* auto calculate columns, minimun cell width is 140px */  
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  
  /* height of each cell */
  grid-auto-rows: 100px;
  
  grid-auto-flow: row dense;
  gap: 20px;
  min-width: 320px;
  max-width: 490px;
  border: 3px solid rgb(0, 22, 117);
}

.card {
  background-color: bisque;
}

.widget {
  background-color: rgb(134, 204, 245);
  /* widget, span for 2 rows */
  grid-row: auto / span 2;
  
  /* set the widget to the right most column */
  grid-column-end: -1;
}
<div class="container">
  <div class="widget"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
</div>

<!-- Original jsx
<div className='container'>
  <div className='widget'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
</div>
-->

Comme @ralph.m l'a mentionné. Vous pouvez toujours le faire en ajoutant grid-column-end: -1; 设置为 .widget

,在最右侧的列上设置 .widget >
P粉321584263

La mise en page Flexbox ne peut pas faire cela, elle ne crée pas de grille 2D, vous devez utiliser la mise en page Gridbox. , afin que les éléments puissent s'étendre sur des lignes et des colonnes sans laisser d'espace.

Voici un exemple :

.grid {
/* give some space gutters */
  margin: 1em auto;
  padding:1em;
  gap: 1em;
 /* build a grid */
  display: grid; 
  grid-auto-flow: row dense;/* fill any holes that could show up */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* auto calculate size of the grid */
  grid-auto-rows: 75px; /* give an height row for the demo */
  max-width: 80%;/* whatever */
  border: solid;/* see my boundaries */
}

.card {
  background-color: salmon;
}

.bigger {
  background-color: lightblue;
  grid-row: 1/ span 2;/* keep me on first row and lay over 2 rows */
  grid-column-end: -1; /* keep me on the last column no matter how many */
}
<div class="grid">
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="bigger">I can be anywhere in the flow but I'll show on top end</div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>  
</div>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal