web-dev-qa-db-fra.com

Largeur fluide avec DIVs équidistantes

J'ai un conteneur de largeur de fluide DIV.

Dans ce cadre, j'ai 4 DIVs toutes 300px x 250px ...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

Ce que je veux, c’est que la case 1 soit flottée à gauche, la case 4 à flottant à droite et que les cases 2 et 3 soient espacées de manière égale. Je souhaite que l’espacement soit fluide, de sorte que le navigateur est réduit, l’espace le devient également.

enter image description here

321
Lee Price

Voir: http://jsfiddle.net/thirtydot/EDp8R/

  • Cela fonctionne dans IE6 + et tous les navigateurs modernes!
  • J'ai réduit de moitié les dimensions demandées pour faciliter le travail.
  • text-align: justify combiné avec .stretch est ce qui gère le positionnement.
  • display:inline-block; *display:inline; zoom:1 corrige inline-block pour IE6/7, voir ici .
  • font-size: 0; line-height: 0 corrige un problème mineur dans IE6.
#container {
  border: 2px dashed #444;
  height: 125px;
  text-align: justify;
  -ms-text-justify: distribute-all-lines;
  text-justify: distribute-all-lines;
  /* just for demo */
  min-width: 612px;
}

.box1,
.box2,
.box3,
.box4 {
  width: 150px;
  height: 125px;
  vertical-align: top;
  display: inline-block;
  *display: inline;
  zoom: 1
}

.stretch {
  width: 100%;
  display: inline-block;
  font-size: 0;
  line-height: 0
}

.box1,
.box3 {
  background: #ccc
}

.box2,
.box4 {
  background: #0ff
}
<div id="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
  <span class="stretch"></span>
</div>

Le supplément span (.stretch) peut être remplacé par :after.

Ceci fonctionne toujours dans les mêmes navigateurs que la solution ci-dessus. :after ne fonctionne pas dans IE6/7, mais ils utilisent distribute-all-lines de toute façon, donc cela n'a pas d'importance.

Voir: http://jsfiddle.net/thirtydot/EDp8R/3/

Il y a un inconvénient mineur à :after: pour que la dernière ligne fonctionne parfaitement dans Safari, vous devez faire attention aux espaces dans le code HTML.

Plus précisément, cela ne fonctionne pas:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div>
</div>

Et cela fait:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div></div>

Vous pouvez l’utiliser pour n’importe quel nombre arbitraire d’enfants divs sans ajouter de classe boxN à chaque classe en modifiant

.box1, .box2, .box3, .box4 { ...

à

#container > div { ...

Ceci sélectionne tout div qui est le premier enfant du #container div, et aucun autre en dessous. Pour généraliser les couleurs d'arrière-plan, vous pouvez utiliser le sélecteur d'ordre n CSS , bien qu'il ne soit pris en charge que par IE9 + et d'autres navigateurs modernes:

.box1, .box3 { ...

devient:

#container > div:nth-child(odd) { ...

Voir ici pour un exemple avec jsfiddle.

435
thirtydot

Le moyen le plus simple de procéder consiste maintenant à utiliser une boîte flexible:

http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Le CSS est alors simplement:

#container {
    display: flex;
    justify-content: space-between;
}

démo: http://jsfiddle.net/QPrk3/

Cependant , ceci n'est actuellement supporté que par les navigateurs relativement récents ( http://caniuse.com/flexbox ). De plus, la spécification pour la disposition flexbox a été modifiée à quelques reprises. Il est donc possible de couvrir davantage de navigateurs en incluant une ancienne syntaxe:

http://css-tricks.com/old-flexbox-and-new-flexbox/

http://css-tricks.com/using-flexbox/

133
Ben Jackson

Si css3 est une option, vous pouvez utiliser la fonction css calc().

Cas 1: Justifier des cases sur une seule ligne ( FIDDLE )

Le balisage est simple - un groupe de div avec un élément conteneur.

CSS ressemble à ceci:

div
{
    height: 100px;
    float: left;
    background:pink;
    width: 50px;
    margin-right: calc((100% - 300px) / 5 - 1px); 
}
div:last-child
{
    margin-right:0;
}

- 1px pour corriger un bogue IE9 + calc/arrondi - voir ici =

Cas 2: boîtes de justification sur plusieurs lignes ( FIDDLE )

Ici, en plus de la fonction calc(), media queries sont nécessaires.

L'idée de base est de configurer une requête multimédia pour chaque état #columns, où j'utilise ensuite calc () pour calculer la marge droite sur chacun des éléments (à l'exception de ceux de la dernière colonne).

Cela ressemble à beaucoup de travail, mais si vous utilisez LESS ou SASS, cela peut être fait assez facilement

(Cela peut toujours être fait avec des fichiers CSS normaux, mais vous devrez ensuite faire tous les calculs manuellement, puis si vous modifiez la largeur de la boîte, vous devrez tout ré-analyser)

Ci-dessous, un exemple utilisant LESS: (Vous pouvez copier/coller ce code ici pour jouer avec, code que j'ai utilisé pour générer le violon mentionné ci-dessus])

@min-margin: 15px;
@div-width: 150px;

@3divs: (@div-width * 3);
@4divs: (@div-width * 4);
@5divs: (@div-width * 5);
@6divs: (@div-width * 6);
@7divs: (@div-width * 7);

@3divs-width: (@3divs + @min-margin * 2);
@4divs-width: (@4divs + @min-margin * 3);
@5divs-width: (@5divs + @min-margin * 4);
@6divs-width: (@6divs + @min-margin * 5);
@7divs-width: (@7divs + @min-margin * 6);


*{margin:0;padding:0;}

.container
{
    overflow: auto;
    display: block;
    min-width: @3divs-width;
}
.container > div
{
    margin-bottom: 20px;
    width: @div-width;
    height: 100px;
    background: blue;
    float:left;
    color: #fff;
    text-align: center;
}

@media (max-width: @3divs-width) {
    .container > div {  
        margin-right: @min-margin;
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @3divs-width) and (max-width: @4divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @4divs-width) and (max-width: @5divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
    }
    .container > div:nth-child(4n) {  
        margin-right: 0;
    }
}

@media (min-width: @5divs-width) and (max-width: @6divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
    }
    .container > div:nth-child(5n) {  
        margin-right: 0;
    }
}

@media (min-width: @6divs-width){
    .container > div {  
        margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
    }
    .container > div:nth-child(6n) {  
        margin-right: 0;
    }
}

Donc, fondamentalement, vous devez d’abord choisir une largeur de boîte et une marge minimale que vous voulez entre les boîtes.

Avec cela, vous pouvez calculer l’espace dont vous avez besoin pour chaque état.

Ensuite, utilisez calc () pour calculer la marge de droite et nth-child pour supprimer la marge de droite des cases de la dernière colonne.

Le avantage de cette réponse par rapport à la réponse acceptée qui utilise text-align:justify est que, lorsque vous avez plusieurs lignes de cases - les cases de la La dernière ligne ne reçoit pas de mot "par exemple", par exemple: s'il reste 2 cases sur la dernière ligne - je ne veux pas que la première case soit à gauche et la suivante à droite - mais plutôt que les cases se suivent dans l'ordre.

Concernant le support du navigateur : Cela fonctionnera sous IE9 +, Firefox, Chrome, Safari6.0 + voir --- ( ici pour plus de détails) Cependant, j'ai remarqué que sur IE9 +, il y avait un petit problème entre les états de requête multimédia. [Si quelqu'un sait comment résoudre ce problème, j'aimerais vraiment savoir :)] <- FIXE ICI

20
Danield

D'autres publications ont mentionné flexbox , mais si plusieurs rangées d'éléments sont nécessaires , la propriété space-between de flexbox échoue (voir la fin du post)

À ce jour, la seule solution propre à cet égard est la

module de disposition en grille CSS ( démonstration de Codepen )

Fondamentalement, le code pertinent nécessaire se résume à ceci:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fit, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: space-between; /* (4) */
  align-content: flex-start; /* (5) */
}

1) Transformer l'élément conteneur en conteneur grille

2) Définissez la grille avec un nombre de colonnes 'auto' - si nécessaire. Ceci est fait pour les mises en page réactives. La largeur de chaque colonne sera de 120px. (Notez l'utilisation de auto-fit (comme associé à auto-fill)) qui (pour une disposition à une ligne) réduit les pistes vides à 0 - permettant aux éléments de se développer pour occuper l'espace restant. cette démo pour voir de quoi je parle)).

3) Définissez les espaces/gouttières pour les lignes et les colonnes de la grille - ici, puisque vous souhaitez une disposition "espace-entre", l'écart sera en fait un espace minimum car il grandira au besoin.

4) et 5) - Similaire à la flexbox.

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  grid-gap: 1rem;
  justify-content: space-between;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

démo de Codepen (redimensionner pour voir l'effet)


Prise en charge du navigateur - Caniuse

Actuellement pris en charge par Chrome (Blink), Firefox, Safari et Edge! ... avec le soutien partiel de IE (voir ce post par Rachel Andrew)


NB:

La propriété space-between de Flexbox fonctionne très bien pour une rangée d'éléments, mais lorsqu'elle est appliquée à un conteneur flex qui encapsule ses éléments avec flex-wrap: wrap) - échoue car vous n'avez aucun contrôle sur l'alignement de la dernière ligne. des articles; la dernière ligne sera toujours toujours justifiée (généralement pas ce que vous voulez)

Démontrer:

--- ( Codepen (Redimensionner pour voir de quoi je parle)


Lectures complémentaires sur les grilles CSS:

11
Danield

Cela a fonctionné pour moi avec 5 images de différentes tailles.

  1. Créer un conteneur div
  2. Une liste non ordonnée pour les images
  3. Sur css le non ordonné doit être affiché verticalement et sans puces
  4. Justifier le contenu de container div

Cela fonctionne à cause de justification-contenu: espace-entre, et c'est sur une liste, affichée horizontalement.

Sur CSS

 #container {
            display: flex;
            justify-content: space-between;
 }
    #container ul li{ display:inline; list-style-type:none;
}

Sur html

<div id="container"> 
  <ul>  
        <li><img src="box1.png"><li>
        <li><img src="box2.png"><li>
        <li><img src="box3.png"><li>
        <li><img src="box4.png"><li>
        <li><img src="box5.png"><li>
    </ul>
</div>
2

Si vous connaissez le nombre d'éléments par "rangée" et la largeur du conteneur, vous pouvez utiliser un sélecteur pour ajouter une marge aux éléments dont vous avez besoin pour créer un aspect justifié.

J'avais des rangées de trois div que je voulais justifiées alors utilisé le:

.tile:nth-child(3n+2) { margin: 0 10px }

cela permet à la division centrale de chaque rangée d'avoir une marge qui force la 1ère et la 3ème division sur les bords extérieurs du conteneur

Aussi idéal pour d'autres choses comme les couleurs de fond des bordures, etc.

1
Dave Robertson

dans jQuery, vous pouvez cibler directement le parent.

CECI IS UTILE SI VOUS NE SAVEZ PAS EXACTEMENT COMBIEN D'ENFANTS SERONT AJOUTÉS DYNAMIQUEMENT OU SI VOUS NE POUVEZ PAS CONNAÎTRE LEUR NOMBRE.

var tWidth=0;

$('.children').each(function(i,e){
tWidth += $(e).width();

///Example: If the Children have a padding-left of 10px;..
//You could do instead:
tWidth += ($(e).width()+10);

})
$('#parent').css('width',tWidth);

Ceci laissera la parent grandir horizontalement car les children sont beng ajoutés.

NOTE: Ceci suppose que les '.children' ont un width et Height Set

J'espère que ça t'as aidé.

1
ErickBest