Empiler les divisions de bas en haut

139

Lors de l'ajout de divs à un divavec une hauteur fixe, les div enfants apparaîtront de haut en bas, collés à la bordure supérieure.

┌─────────────────────────┐
 Child Div 1             
 Child Div 2             
                         
                         
                         
└─────────────────────────┘

J'essaie maintenant de les afficher de bas en haut comme ceci (en me collant à la bordure inférieure):

┌─────────────────────────┐
                         
                         
                         
 Child Div 1             
 Child Div 2             
└─────────────────────────┘
┌─────────────────────────┐
                         
                         
 Child Div 1             
 Child Div 2             
 Child Div 3             
└─────────────────────────┘
┌───────────────────────┬─┐
 Child Div 2           │▲│
 Child Div 3            
 Child Div 4            
 Child Div 5           │█│
 Child Div 6           │▼│
└───────────────────────┴─┘

Et ainsi de suite ... J'espère que vous comprenez ce que je veux dire.

Est-ce simplement faisable avec CSS (quelque chose comme vertical-align: bottom)? Ou dois-je pirater quelque chose avec JavaScript?

Wulf
la source

Réponses:

46

Toutes les réponses manquent le point de la barre de défilement de votre question. Et c'est difficile. Si vous n'en avez besoin que pour les navigateurs modernes et IE 8+, vous pouvez utiliser le positionnement de table vertical-align:bottomet max-height. Voir MDN pour la compatibilité spécifique du navigateur.

Démo (alignement vertical)

.wrapper {
  display: table-cell;
  vertical-align: bottom;
  height: 200px;
}
.content {
  max-height: 200px;
  overflow: auto;
}

html

<div class="wrapper">
  <div class="content">
     <div>row 1</div>
     <div>row 2</div>
     <div>row 3</div>  
  </div>
</div>  

A part ça, je pense que ce n'est pas possible avec CSS uniquement. Vous pouvez faire adhérer les éléments au fond de leur conteneur avec position:absolute, mais cela les sortira du flux. En conséquence, ils ne s'étireront pas et ne feront pas défiler le conteneur.

Démo (position absolue)

.wrapper {
  position: relative;
  height: 200px;
}
.content {
  position: absolute;
  bottom: 0;
  width: 100%;
}
gblazex
la source
et overflow-y:autopour le conteneur
venimus
@venimus - Cela afficherait une barre de défilement désactivée, car la hauteur du conteneur n'est pas affectée par un position:absoluteenfant.
gblazex
Eh
J'ai mis à jour la réponse. Vous pouvez contourner le problème de la barre de défilement dans les navigateurs modernes (IE 7+).
gblazex
1
Merci pour votre réponse, l'emballage fait bien le travail.
Wulf
38

Une réponse plus moderne à cela serait d'utiliser flexbox.

Comme de nombreuses autres fonctionnalités modernes, elles ne fonctionneront pas dans les navigateurs hérités , donc à moins que vous ne soyez prêt à abandonner la prise en charge des navigateurs de l'ère IE8-9, vous devrez rechercher une autre méthode.

Voici comment procéder:

.parent {
  display: flex;
  justify-content: flex-end;
  flex-direction: column;
}

.child {
  /* whatever */
}

Et c'est tout ce dont vous avez besoin. Pour en savoir plus flexbox, voir MDN .

Voici un exemple de ceci avec un style de base: http://codepen.io/Mest/pen/Gnbfk

Nils Kaspersson
la source
Super réponse, merci beaucoup! Je n'ai pas encore entendu parler de flexbox, ça semble vraiment intéressant!
Wulf du
4
Cela inverse l'ordre mais ne les tire pas vers le bas du parent.
Edward Anderson
@nilbus voudriez-vous élaborer? Mes tests précédents et même l'exemple ci-joint semblent très certainement tirer le bas vers le bas de l'élément parent.
Nils Kaspersson
Il semble que je me trompe. Peut-être qu'il y a un style conflictuel qui l'empêchait de fonctionner pour moi. Merci!
Edward Anderson
J'ai trouvé dans l'exemple de code, il y a .parent {position: fixed;} qui fait que cela fonctionne. De plus, le défilement dans la démo ne fonctionne pas sur Chome, vous en avez besoin: .parant {-webkit-flex: 1 1 auto; débordement-y: auto; min-height: 0px;} et supprimer la position fixe
Ng Sek Long
1

Nous pouvons simplement utiliser la transformation CSS pour archiver cela.

J'ai créé un codepen pour cela. https://codepen.io/king-dev/pen/PoPgXEg

.root {
  transform: scaleY(-1);
}
.root > div {
  transform: scaleY(-1);
}

L'idée est de retourner la racine d'abord horizontalement, puis de retourner à nouveau les div enfants directs.

REMARQUE: la méthode ci-dessus inverse également l'ordre des divs. Si vous voulez simplement les placer pour commencer par le bas, vous pouvez faire ce qui suit.

.root {
  display: flex;
  flex-direction: column;
  height: 100px;
  overflow-y: auto;
}
.root > div:first-child {
  margin-top: auto;
}
Dan Robert
la source
0

Keepin 'it oldskool ...

Je voulais faire la même chose dans un #header div alors j'ai créé un div vide appelé #headspaceet l' ai placé au sommet de la pile (à l'intérieur de #header):

<div id="header">
    <div id="headspace"></div>
    <div id="one">some content</div>
    <div id="two">other content</div>
    <div id="three">more content</div>
</div> <!-- header -->

Ensuite, j'ai utilisé un pourcentage , pour la hauteur du #headspace div invisible , pour pousser les autres vers le bas. Il est facile d'utiliser les outils de développement / inspecteur du navigateur pour que cela soit parfait.

#header {
    width: 100%;
    height: 10rem;
    overflow: auto;
}

#headspace {
    width: 100%;
    height: 42%;    /* Experiment with Inspect (Element) tool */
}

#one, #two, #three {
    /* Insert appropriate dimensions for others... */
}
veganaiZe
la source
Cela ne fonctionnera que si vous avez un contenu fixe. si vous avez du contenu dynamique et que vous ne savez pas qui de nombreux divs seront rendus, cela ne fonctionnera pas.
Sajid Ali
C'était juste une petite solution que j'avais utilisée. Il n'y avait aucune mention spécifique de la nécessité d'un contenu dynamique - pour autant que je sache, la page est complètement actualisée chaque fois qu'un divest ajouté. Je mets donc ceci ici au cas où quelqu'un voudrait réellement une solution plus statique. En d'autres termes: je pense qu'un vote nul serait plus approprié qu'un vote négatif.
veganaiZe
Merci d'avoir pris le temps et de fournir une réponse avec un contenu statique. Je respecte ça. La question montre clairement le contenu dynamique, Child Div #où les div enfants augmentent et, lorsqu'ils sont augmentés d'une certaine hauteur, un défilement devrait être affiché. donc cette réponse ne fournit pas de solution à la question réelle.
Sajid Ali
0

je veux que cela fonctionne avec bootstarp comme une application de discussion où les messages circulent de bas en haut

après avoir lu des trucs, j'ai trouvé ça

J'ai un div externe assumer la classe .outerDiv puis UI, list

.outerDiv {
    height: 361px;
    position: relative;
}
ui.msg-content{
    width: 100%;
    bottom: 0;
    position: absolute;
    max-height: 98%;
    overflow-y: auto;
}

entrez la description de l'image ici

entrez la description de l'image ici

kuldeep chopra
la source
-5
<div style="height: 500px;">
    <div style="height: 20px; position: absolute; bottom: 120px;">Child Div 1</div>
    <div style="height: 20px; position: absolute; bottom: 100px;">Child Div 2</div>
    <div style="height: 20px; position: absolute; bottom: 80px;">Child Div 3</div>
    <div style="height: 20px; position: absolute; bottom: 60px;">Child Div 4</div>
    <div style="height: 20px; position: absolute; bottom: 40px;">Child Div 5</div>
</div>
Matt Healy
la source