Comment positionner mon div au fond de son container?

741

Étant donné le code HTML suivant:

<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

Je voudrais #copyrightrester au fond de #container.

Puis-je y parvenir sans utiliser le positionnement absolu? Si la propriété float prend en charge une valeur de «bas», cela semble faire l'affaire, mais malheureusement, ce n'est pas le cas.

Dónal
la source
211
Cette situation est l'une des raisons pour lesquelles les tableaux de disposition n'ont pas encore disparu. Faire cela avec une table est très simple et fonctionne partout. Faire cela en CSS est hilarante et la prise en charge multi-navigateurs est assez moyenne. Sans parler du fait qu'il est impossible de se rappeler comment le faire correctement.
Tomalak
Je ne comprends pas la question. Pourquoi avez-vous besoin d'utiliser un positionnement absolu? Le conteneur a-t-il une hauteur définie, quel que soit le contenu qu'il contient?
HartleySan

Réponses:

924

Probablement pas.

Attribuez position:relativeà #container, puis position:absolute; bottom:0;à #copyright.


#container {
    position: relative;
}
#copyright {
    position: absolute;
    bottom: 0;
}
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

Utilisateur
la source
11
Si position: relative sur votre conteneur rompt votre conception, n'oubliez pas que vous pouvez simplement inclure un div wrapper à l'intérieur du conteneur avec 100% de hauteur, et ajouter à la place position: relative à cela.
Jack Shepherd
et si c'est pour répéter des éléments, qui seraient autrement positionnés les uns sur les autres?
CRice
6
Un élément positionné de façon absolue cherche son parent le plus proche qui est une position absolue ou relative afin de déterminer sa position. Si tout échoue, il recourt au corps (fenêtre). D'où la nécessité pour le parent d'être relatif.
user17753
1
ajouter une marge en bas à #container pour empêcher le droit d'auteur sur le contenu de la page
Doc Kodam
1
L'approche Flexbox ci-dessous est bien meilleure.
woohoo
345

En fait, la réponse acceptée par @User ne fonctionnera que si la fenêtre est grande et le contenu court. Mais si le contenu est grand et que la fenêtre est courte, les informations de copyright seront placées sur le contenu de la page, puis en faisant défiler vers le bas pour voir le contenu, vous obtiendrez un avis de copyright flottant. Cela rend cette solution inutile pour la plupart des pages (comme cette page, en fait).

La façon la plus courante de procéder est l'approche du "pied de page collant CSS", ou une variation légèrement plus mince. Cette approche fonctionne très bien - SI vous avez un pied de page à hauteur fixe.

Si vous avez besoin d'un pied de page à hauteur variable qui apparaîtra en bas de la fenêtre si le contenu est trop court, et en bas du contenu si la fenêtre est trop courte, que faites-vous?

Avalez votre fierté et utilisez une table.

Par exemple:

* {
    padding: 0;
    margin: 0;
}

html, body {
    height: 100%;
}

#container {
    height: 100%;
    border-collapse: collapse;
}
<!DOCTYPE html>
<html>
<body>
    <table id="container">
        <tr>
            <td valign="top">
                <div id="main">Lorem ipsum, etc.</div>
            </td>
        </tr>
        <tr>
            <td valign="bottom">
                <div id="footer">Copyright some evil company...</div>
            </td>
        </tr>
    </table>
</body>
</html>

Essaye le. Cela fonctionnera pour n'importe quelle taille de fenêtre, pour n'importe quelle quantité de contenu, pour n'importe quel pied de page de taille, sur chaque navigateur ... même IE6.

Si vous pensez à l'idée d'utiliser une table pour la mise en page, prenez une seconde pour vous demander pourquoi. CSS était censé nous faciliter la vie - et il l'a fait, dans l'ensemble - mais le fait est que même après toutes ces années, c'est toujours un gâchis cassé et contre-intuitif. Il ne peut pas résoudre tous les problèmes. C'est incomplet.

Les tableaux ne sont pas cool, mais au moins pour l'instant, ils sont parfois le meilleur moyen de résoudre un problème de conception.

Rick Reilly
la source
80
Semble être la meilleure réponse pour moi. De plus, vous pouvez toujours utiliser des "tables css" (affichage: table [-row / -cell]) au lieu des tables html. Cela fournit la même mise en page sans la sémantique.
chiccodoro
1
Si vous avez un script PHP / autre script qui génère votre page, vous pouvez dupliquer votre pied de page, en en utilisant un comme "espaceur" caché et un positionné absolument. Le pied de page d'espacement garantit que peu importe la quantité de contenu que vous avez dans votre pied de page, il ne montera pas sur la page.
Tyzoid
20
Pour ceux qui lisent ces commentaires: cela n'a rien à voir avec la «fierté» ou le fait d'être «cool». L'utilisation de tableaux pour la mise en page est pragmatique encore plus pénible, en particulier pour de grandes quantités de contenu. Faire en sorte de ne pas manquer un td et passer au crible tant de balises non pertinentes lors de l'ajout de contenu est un enfer. C'est une cause de douleur car nous créons des documents HTML et pas seulement des mises en page, et si la plupart du contenu de notre document n'est pas des données tabulaires, alors pourquoi le mettons-nous dans des tableaux? Si nous n'aimons pas utiliser les technologies Web telles qu'elles étaient conçues, pourquoi les utiliser? Utilisez des applications de bureau / mobiles pour publier du contenu à la place
gabe
1
@chiccodoro J'ai implémenté un équivalent sans table qui est étonnamment minimal, consultez ma réponse ci
Hashbrown
59
L'orgueil n'est pas pertinent. Les tableaux ne doivent pas être utilisés pour la mise en page, pour des raisons d'accessibilité. Si vous avez déjà utilisé un lecteur d'écran, vous saurez pourquoi les tableaux doivent être utilisés uniquement pour les données tabulaires. Utilisez les tables css comme les états @chiccodoro.
Matt Fellows
172

L'approche flexbox!

Dans les navigateurs pris en charge , vous pouvez utiliser les éléments suivants:

Exemple ici

.parent {
  display: flex;
  flex-direction: column;
}
.child {
  margin-top: auto;
}


La solution ci-dessus est probablement plus flexible, cependant, voici une solution alternative:

Exemple ici

.parent {
  display: flex;
}
.child {
  align-self: flex-end;
}


En guise de remarque, vous souhaiterez peut-être ajouter des préfixes de fournisseur pour une assistance supplémentaire.

Josh Crozier
la source
3
qu'en est-il column-reversedu parent, vous n'avez donc pas besoin d'ajouter quoi que ce soit à l'enfant?
Max Waterman
1
Cela devrait probablement être la réponse acceptée - pas de piratage, pas de positionnement absolu, le débordement fonctionne correctement en cas de besoin (c'était pour moi).
Adverbly
114

Oui, vous pouvez le faire sans absolutepositionnement et sans utiliser de tables (qui vis avec du balisage et autres).

DEMO
Ceci est testé pour fonctionner sur IE> 7, chrome, FF & est une chose vraiment facile à ajouter à votre disposition existante.

<div id="container">
    Some content you don't want affected by the "bottom floating" div
    <div>supports not just text</div>

    <div class="foot">
        Some other content you want kept to the bottom
        <div>this is in a div</div>
    </div>
</div>
#container {
    height:100%;
    border-collapse:collapse;
    display : table;
}

.foot {
    display : table-row;
    vertical-align : bottom;
    height : 1px;
}

Il fait effectivement ce qui float:bottomserait, même en tenant compte du problème signalé dans la réponse de @Rick Reilly!

Hashbrown
la source
1
Agréable! Juste une note, IIRC vous avez besoin de l' <!DOCTYPE>ensemble pour que cela fonctionne sur IE (<= 8 au moins); ces anciennes versions ne prennent display:table-XXXen charge que le mode "standard". Mais le mode standard cassera également un grand nombre de pages conçues pour, disons, IE6.
David
3
Vous pouvez également utiliser flexbox - stackoverflow.com/questions/526035/…
Josh Crozier
2
J'ai trouvé plus de chance avec .foot{display: table-footer-group}. Je ne l' ai pas besoin vertical-align, heightou border-collapse.
Jacob Valenta
Est-ce que cela fonctionnerait si #containerseulement contenu #footet sans autre contenu?
Solace
il semble qu'il aurait au moins besoin d'un espace insécable, @Solace
Hashbrown
20

C'est une vieille question, mais c'est une approche unique qui peut aider dans plusieurs cas.

CSS pur, sans positionnement absolu, sans fixation de hauteur, Cross-Browser (IE9 +)

découvrez que Working Fiddle

Parce que le flux normal est «de haut en bas», nous ne pouvons pas simplement demander au #copyrightdiv de se tenir au fond de ses parents sans absolument se positionner,#copyright div reste au sommet de son parent, il sera très simple - car c'est la voie d'écoulement normale.

Nous allons donc utiliser cela à notre avantage. nous allons changer l'ordre des divs dans le HTML, maintenant le#copyright div est en haut, et le contenu le suit tout de suite. nous faisons également étirer le contenu div complètement (en utilisant des pseudo-éléments et des techniques de compensation)

maintenant, il suffit de retourner cet ordre dans la vue. cela peut être fait facilement avec la transformation CSS.

Nous faisons tourner le conteneur de 180 degrés, et maintenant: up-is-down. (et nous inversons le contenu pour qu'il redevienne normal)

Si nous voulons avoir une barre de contrôle dans la zone de contenu, nous devons appliquer un peu plus de magie CSS. comme on peut le voir ici [dans cet exemple, le contenu est en dessous d'un en-tête - mais c'est la même idée]

* {
  margin: 0;
  padding: 0;
}

html,
body,
#Container {
  height: 100%;
  color: white;
}

#Container:before {
  content: '';
  height: 100%;
  float: left;
}

#Copyright {
  background-color: green;
}

#Stretch {
  background-color: blue;
}

#Stretch:after {
  content: '';
  display: block;
  clear: both;
}

#Container,
#Container>div {
  -moz-transform: rotateX(180deg);
  -ms-transform: rotateX(180deg);
  -o-transform: rotate(180deg);
  -webkit-transform: rotateX(180deg);
  transform: rotateX(180deg);
}
<div id="Container">
  <div id="Copyright">
    Copyright Foo web designs
  </div>
  <div id="Stretch">
    <!-- Other elements here -->
    <div>Element 1</div>
    <div>Element 2</div>
  </div>
</div>

avrahamcool
la source
2
S'il vous plaît non, regardez à quel point le rendu est horrible i.stack.imgur.com/ZP9Hw.png
grg
7

Créez un autre conteneur divpour les éléments ci-dessus #copyright. Juste au-dessus du droit d'auteur, ajoutez un nouveau div: <div style="clear:both;"></div> cela forcera le pied de page à être sous tout le reste, tout comme dans le cas de l'utilisation du positionnement relatif ( bottom:0px;).

Rápli András
la source
7

Essaye ça;

<div id="container">
  <div style="height: 100%; border:1px solid #ff0000;">
  <!-- Other elements here -->
  </div>
</div>
<div id="copyright" style="position:relative;border:1px solid #00ff00;top:-25px">
   Copyright Foo web designs
</div>

Gary Green
la source
1
@Feelsbadman Veuillez ne pas changer le code des autres personnes dans des réponses comme ça. Si vous aviez l'intention de séparer simplement le CSS du HTML, veuillez noter que vous avez par inadvertance changé le code en quelque chose d'autre, ce qui pourrait invalider la réponse et certainement changer l'intention de l'affiche.
TylerH
6

Bien qu'aucune des réponses fournies ici ne semble s'appliquer ou fonctionner dans mon cas particulier, je suis tombé sur cet article qui fournit cette solution intéressante:

#container {
  display: table;
}

#copyright {
  display: table-footer-group;
}

Je le trouve très utile pour appliquer un design réactif pour l'affichage mobile sans avoir à réorganiser tout le code html d'un site Web, en définissant body comme un tableau.

Notez que seul le premier table-footer-groupou table-header-groupsera rendu comme tel: s'il y en a plusieurs, les autres seront rendus comme table-row-group.

Skippy le Grand Gourou
la source
6

Grille CSS

Étant donné que l'utilisation de CSS Grid est en augmentation, je voudrais suggérer align-self à l'élément qui se trouve à l'intérieur d'un conteneur de grille.

align-selfpeut contenir l' une des valeurs: end, self-end, flex-endpour l'exemple suivant.

#parent {
  display: grid;
}

#child1 {
  align-self: end;
}

/* Extra Styling for Snippet */

#parent {
  height: 150px;
  background: #5548B0;
  color: #fff;
  padding: 10px;
  font-family: sans-serif;
}

#child1 {
  height: 50px;
  width: 50px;
  background: #6A67CE;
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
}
<div id="parent">
  <!-- Other elements here -->
  <div id="child1">
    1
  </div>

</div>

Manoj Kumar
la source
5

Vous pouvez en effet alignla boîte à la bottomsans utiliser position:absolutesi vous connaissez la heightde l' #containerutilisation de la fonction d' alignement de texte deinline-block éléments.

Ici, vous pouvez le voir en action.

Voici le code:

#container {
    /* So the #container most have a fixed height */
    height: 300px;
    line-height: 300px;
    background:Red;
}

#container > * {
    /* Restore Line height to Normal */
    line-height: 1.2em;
}

#copyright {
    display:inline-block;
    vertical-align:bottom;
    width:100%; /* Let it be a block */
    background:green;
}
jacmkno
la source
5

Utilisation de la propriété translateY et top

Définissez simplement l'élément enfant sur la position: relative et déplacez-le en haut: 100% (c'est la hauteur de 100% du parent) et restez en bas du parent par transform: translateY (-100%) (c'est -100% de la hauteur de l'enfant).

Avantages

  • vous ne prenez pas l'élément du flux de page
  • c'est dynamique

Mais toujours une solution :(

.copyright{
   position: relative;
   top: 100%;
   transform: translateY(-100%);
}

N'oubliez pas les préfixes de l'ancien navigateur.

Samuell
la source
4

Lien CodePen ici .

html, body {
    width: 100%;
    height: 100%;
}

.overlay {
    min-height: 100%;
    position: relative;
}

.container {
    width: 900px;
    position: relative;
    padding-bottom: 50px;
}

.height {
    width: 900px;
    height: 50px;
}

.footer {
    width: 900px;
    height: 50px;
    position: absolute;
    bottom: 0;
}
<div class="overlay">
    <div class="container">
        <div class="height">
            content
        </div>
    </div>

    <div class="footer">
        footer
    </div>
</div>

azizarslan
la source
3

Si vous voulez qu'il "colle" au fond, quelle que soit la hauteur du récipient, alors le positionnement absolu est la voie à suivre. Bien sûr, si l'élément copyright est le dernier dans le conteneur, il sera toujours en bas de toute façon.

Pouvez-vous développer votre question? Expliquez exactement ce que vous essayez de faire (et pourquoi vous ne voulez pas utiliser le positionnement absolu)?

Jack Sleight
la source
2

De plus, s'il y a des conditions d'utilisation de position:absolute;ou position:relative;, vous pouvez toujours essayer padding parent div ou mettre a margin-top:x;. Pas une très bonne méthode dans la plupart des cas, mais elle peut être utile dans certains cas.

Écho fantôme
la source
1

Peut-être que cela aide quelqu'un: vous pouvez toujours placer le div à l'extérieur de l'autre div, puis le pousser vers le haut en utilisant une marge négative:

<div id="container" style="background-color: #ccc; padding-bottom: 30px;">
  Hello!
</div>
<div id="copyright" style="margin-top: -20px;">
  Copyright Foo web designs
</div>
DesignConsult
la source
1

 #container{width:100%; float:left; position:relative;}
#copyright{position:absolute; bottom:0px; left:0px; background:#F00; width:100%;}
#container{background:gray; height:100px;}
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

Anmol Ratan Mohla
la source
1

Je ne veux pas utiliser "position: absolue" pour le pied de page collant en bas. Ensuite, vous pouvez procéder de cette façon:

 html,
        body {
            height: 100%;
            margin: 0;
        }
        .wrapper {
            min-height: 100%;
            /* Equal to height of footer */
            /* But also accounting for potential margin-bottom of last child */
            margin-bottom: -50px;
        }
        .footer{
            background: #000;
            text-align: center;
            color: #fff;
        }
        .footer,
        .push {
            height: 50px;
        }
<html>
<body>
    <!--HTML Code-->
    <div class="wrapper">
        <div class="content">content</div>
        <div class="push"></div>
    </div>
    <footer class="footer">test</footer>
</body>
</html>

nilesh pawar
la source
Salut nilesh; cette solution est déjà fournie dans plusieurs réponses. Assurez-vous de lire toutes les réponses existantes à une question avant d'en fournir une nouvelle, pour vous assurer qu'il n'y a pas de duplication de contenu!
TylerH
1

Si vous ne connaissez pas la hauteur du bloc enfant:

#parent {
    background:green;
    width:200px;
    height:200px;
    display:table-cell;
    vertical-align:bottom;
}
.child {
    background:red;
    vertical-align:bottom;
}
<div id="parent">
    <div class="child">child
    </div> 
</div>

http://jsbin.com/ULUXIFon/3/edit

Si vous connaissez la hauteur du bloc enfant, ajoutez le bloc enfant, puis ajoutez padding-top / margin-top:

#parent {
    background:green;
    width:200px;
    height:130px;
    padding-top:70px;
}
.child {
    background:red;
    vertical-align:
    bottom;
    height:130px;
}
<div id="parent">
    <div class="child">child
    </div> 
</div>  

zloctb
la source
0

Tout simplement parce que cela n'a pas été mentionné du tout, ce qui fonctionne généralement bien dans des situations comme la vôtre:

Placer le copyright-div après le container-div

Vous n'auriez qu'à formater le div des droits d'auteur d'une manière similaire à l'autre conteneur (même largeur globale, centrage, etc.), et tout va bien.

CSS:

#container, #copyright {
    width: 1000px;
    margin:0 auto;
}

HTML:

<div id="container">
    <!-- Other elements here -->
</div>

<div id="copyright">
    Copyright Foo web designs
</div>

La seule fois où cela pourrait ne pas être idéal, c'est lorsque votre conteneur-div est déclaré avec height:100%, et l'utilisateur devrait faire défiler vers le bas pour voir le droit d'auteur. Mais même vous pouvez toujours contourner (par exemple margin-top:-20px- lorsque la hauteur de votre élément de copyright est de 20 pixels).

  • Pas de positionnement absolu
  • Aucune disposition de table
  • Pas de CSS fou, qui semble différent dans tous les autres navigateurs (enfin IE au moins, vous savez)
  • Formatage simple et clair

À part: je sais que le PO a demandé une solution qui "... colle au fond de la division" conteneur "..." , et pas quelque chose en dessous, mais allez, les gens recherchent de bonnes solutions ici, et cela est une!

lévite
la source
Dans le cas d'OP, cette solution n'est bonne que si #copyright est à hauteur fixe (alors vous pouvez définir margin-top: -{element height}.
Gajus
@Gajus: Ce n'est pas un positionnement absolu ni fixe. Cela fait exactement ce que l'OP veut (peu importe la hauteur du droit d'auteur), à la seule exception que le div du droit d'auteur n'est pas DANS le premier conteneur. L'OP a demandé que les droits d'auteur restent au bas du conteneur, pas sur la page !!
Lévite
Désolé, je ne veux pas dire si le conteneur # container est à hauteur fixe.
Gajus
Sauf erreur de ma part, le véritable problème que OP essaie de résoudre est le bas de l'élément lorsque la hauteur de l'élément est dictée par un autre élément, par exemple avec des commentaires jsbin.com/acoVevI/3 . Ici, vous ne pouvez pas simplement mettre le bouton à l'extérieur du conteneur . Pour illustrer davantage le problème, voir jsbin.com/acoVevI/4 .
Gajus
L'OP a déclaré: "Je voudrais que #copyright reste au bas de #container.", Donc ce n'est pas totalement clair à la question. De plus, c'est un exemple valable pour tout cas où il devrait simplement "coller au bas de #container". Cette solution doit être utile, a une approche propre et fonctionne bien pour de nombreuses mises en page. Par exemple, n'importe quelle page avec un contenu défilant, comme stackoverflow.com ;-)
Levite
0

Voici une approche visant à faire flotter un élément de hauteur et de largeur connues (au moins approximativement) vers la droite et de rester en bas, tout en se comportant comme un élément en ligne avec les autres éléments. Il est concentré en bas à droite car vous pouvez le placer facilement dans n'importe quel autre coin grâce à d'autres méthodes.

J'avais besoin de créer une barre de navigation qui aurait les liens réels en bas à droite et des éléments frères et sœurs aléatoires, tout en m'assurant que la barre elle-même s'étirait correctement, sans perturber la mise en page. J'ai utilisé un élément "shadow" pour occuper l'espace des liens de la barre de navigation et l'ai ajouté à la fin des nœuds enfants du conteneur.


<!DOCTYPE html>
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
  <span id="copyright-s">filler</span>
</div>

<style>
  #copyright {
    display:inline-block;
    position:absolute;
    bottom:0;
    right:0;
  }
  #copyright-s {
    float:right;
    visibility:hidden;
    width:20em; /* ~ #copyright.style.width */
    height:3em; /* ~ #copyright.style.height */
  }
</style>
Zyox
la source
0

Il n'y a rien appelé float:bottomen CSS. La meilleure façon est d'utiliser le positionnement dans de tels cas:

position:absolute;
bottom:0;
Touhid Rahman
la source
Veuillez expliquer votre réponse.
Mohit Raj Purohit
0

Pour ceux qui n'ont qu'un seul enfant dans le conteneur, vous pouvez utiliser l' approche table-cellet vertical-alignqui a fonctionné de manière fiable pour positionner une seule div au bas de son parent.

Notez que l'utilisation des table-footer-groupautres réponses mentionnées interrompra le calcul de la hauteur du parent table.

#container {
    display: table;
    width: 100%;
    height: 200px;
}
#item {
    display: table-cell;
    vertical-align: bottom;
}
<div id="container">
    <div id="item">Single bottom item</div>
</div>

Hai Zhang
la source
0

Selon: w3schools.com

Un élément avec position: absolu; est positionné par rapport à l'ancêtre positionné le plus proche (au lieu d'être positionné par rapport à la fenêtre, comme fixe).

Vous devez donc positionner l'élément parent avec quelque chose de relatif ou absolu, etc. et positionner l'élément souhaité en absolu et le dernier en bas à 0.

Jonas Freire
la source
Ceci est déjà mentionné dans la réponse acceptée (entre autres).
TylerH
-1

Div of style, position:absolute;bottom:5px;width:100%;fonctionne, mais il a fallu plus de défilement.

window.onscroll = function() {
    var v = document.getElementById("copyright");
    v.style.position = "fixed";
    v.style.bottom = "5px";
}
nicejay
la source