web-dev-qa-db-fra.com

Comment forcer l'enfant div à 100% de sa taille sans spécifier celle du parent

J'ai un site avec la structure suivante:

<div id="header"></div>

<div id="main">
  <div id="navigation"></div>
  <div id="content"></div>
</div>

<div id="footer"></div>

La navigation est à gauche et le contenu est à droite. Les informations relatives à la div content sont extraites via PHP, elles sont donc différentes à chaque fois.

Comment puis-je redimensionner la navigation verticalement pour que sa hauteur soit la même que celle du contenu, quelle que soit la page chargée?

456
user137726

NOTE: cette réponse est applicable aux navigateurs existants sans prise en charge du standard Flexbox. Pour une approche moderne, voir: https://stackoverflow.com/a/23300532/1155721


Je vous suggère de jeter un oeil sur Colonnes de même hauteur avec CSS entre navigateurs et aucun hack .

Fondamentalement, faire cela avec CSS de manière compatible avec le navigateur n’est pas trivial (mais trivial avec les tableaux), alors trouvez-vous une solution pré-packagée appropriée.

En outre, la réponse varie selon que vous souhaitiez une hauteur de 100% ou une hauteur égale. D'habitude c'est la même hauteur. Si c'est 100% de hauteur, la réponse est légèrement différente.

144
cletus

Pour le parent:

display: flex;

Vous devriez ajouter des préfixes, http://css-tricks.com/using-flexbox/ .

Edit: Comme @Adam Garner l’a noté, align-items: stretch; n'est pas nécessaire. Son utilisation est également pour les parents, pas les enfants. Si vous voulez définir les enfants qui s'étirent, vous utilisez align-self.

.parent {
  height: 150px;
  background: red;
  padding: 10px;
  display:flex;
}

.child {  
  width: 100px;
  background: blue;
}
<div class="parent">
  <div class="child"></div>
</div>

492
Aiphee

C’est un problème frustrant qui est traité en permanence par les concepteurs. L'astuce est que vous devez définir la hauteur à 100% sur BODY et HTML dans votre CSS.

html,body {
    height:100%;
}

Ce code apparemment inutile consiste à définir pour le navigateur ce que signifie 100%. Frustrant, oui, mais c'est le moyen le plus simple.

96
Travis

Je trouve que définir les deux colonnes sur display: table-cell; au lieu de float: left; fonctionne bien.

92
Paul Harvey

Si cela ne vous dérange pas que la navigation div soit découpée dans le cas d'une div de contenu trop courte de façon inattendue, il existe au moins un moyen simple:

#main {
position: relative;
}

#main #navigation {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 10em; /* or whatever */
}

#main #content {
margin: 0;
margin-left: 10em; /* or whatever width you set for #navigation */
}

Sinon, il y a la technique faux-columns .

53
David Thomas
#main {
    overflow: hidden;
}
#navigation, #content {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
}
30
Roman Kuntyi

en utilisant jQuery:

$(function() {
    function unifyHeights() {
        var maxHeight = 0;
        $('#container').children('#navigation, #content').each(function() {
            var height = $(this).outerHeight();
            // alert(height);
            if ( height > maxHeight ) {
                maxHeight = height;
            }
        });
        $('#navigation, #content').css('height', maxHeight);
    }
    unifyHeights();
});
15
flavius

Essayez de faire la marge inférieure à 100%.

margin-bottom: 100%;
11
Tony C
#main {
   display: table;
} 
#navigation, #content {
   display: table-cell;
}

Regardez cet exemple .

10
Sergiu

height : <percent> ne fonctionnera que si vous avez tous les nœuds parents avec le pourcentage de hauteur spécifié avec une hauteur fixe en pixels, ems, etc. au niveau supérieur. De cette façon, la hauteur tombera dans votre élément.

Vous pouvez spécifier 100% à HTML et aux éléments de corps comme @Travis l'a indiqué précédemment pour que la hauteur de la page tombe en cascade dans vos nœuds.

8
Lajos Meszaros

Après de longues recherches et tentatives, rien ne résout mon problème sauf

style = "height:100%;"

sur les enfants div

et pour parent appliquer cette

.parent {
    display: flex;
    flex-direction: column;
}

aussi, j'utilise bootstrap et cela n'a pas corrompu le responsive pour moi.

7
Hakam Fostok

Basé sur la méthode décrite dans cet article article j’ai créé la solution peu dynamique

Html:

<div id="container3">
    <div id="container2">
        <div id="container1">
            <div id="col1">Column 1</div>
            <div id="col2">Column 2</div>
            <div id="col3">Column 3</div>
        </div>
    </div>
</div>

Moins:

/* Changes these variables to adjust your columns */
@col1Width: 60%;
@col2Width: 1%;
@padding: 0%;

/* Misc variable. Do not change */
@col3Width: 100% - @col1Width - @col2Width;

#container3 {
    float: left;
    width: 100%;
    overflow: hidden;
    background-color: red;
    position: relative;

    #container2 {
        float: left;
        width: 100%;
        position: relative;
        background-color: yellow;
        right: @col3Width;

        #container1 {
            float: left;
            width: 100%;
            position: relative;
            right: @col2Width;
            background-color: green;

            #col1 {
                float: left;
                width: @col1Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding;
                overflow: hidden;
            }

            .col2 {
                float: left;
                width: @col2Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 2;
                overflow: hidden;
            }

            #col3 {
                float: left;
                width: @col3Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 4;
                overflow: hidden;
            }
        }
    }
}
6
Dmitry

Dans un projet RWD, le mieux serait d’utiliser jQuery. Pour un petit écran, vous voudrez probablement garder la hauteur automatique car les colonnes col1, col2 et col3 sont empilées l'une sur l'autre.

Toutefois, après un point d'arrêt de requête multimédia, vous souhaitez que les colonnes apparaissent côte à côte avec une hauteur égale pour toutes les colonnes. 

1125 px est uniquement un exemple de point d'arrêt en largeur de fenêtre après lequel vous souhaitez que toutes les colonnes soient définies à la même hauteur.

<div class="wraper">
    <div class="col1">Lorem ipsum dolor sit amet.</div>
    <div class="col2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos laudantium, possimus sed, debitis amet in, explicabo dolor similique eligendi officia numquam eaque quae illo magnam distinctio odio, esse vero aspernatur.</div>
    <div class="col3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem, odio qui praesentium.</div>
</div>

Vous pouvez, bien sûr, définir plus de points d'arrêt si vous en avez besoin. 

<script>
    $(document).ready(function(){
        $(window).on('load resize', function() {
            if (window.innerWidth>= 1125) {
              $('.col1').height($('.wraper').height());
              $('.col2').height($('.wraper').height());
              $('.col3').height($('.wraper').height());
            }
            if (window.innerWidth < 1125) {
              $('.col1').height('auto');
              $('.col2').height('auto');
              $('.col3').height('auto');
            }
        });
    });
</script>
2
DevWL

Je sais que cela fait très longtemps que la question a été posée, mais j'ai trouvé une solution facile et j'ai pensé que quelqu'un pourrait l'utiliser (désolé pour le mauvais anglais). Ici ça va:

CSS

.main, .sidebar {
    float: none;
    padding: 20px;
    vertical-align: top;
}
.container {
    display: table;
}
.main {
    width: 400px;
    background-color: LightSlateGrey;
    display: table-cell;
}
.sidebar {
    width: 200px;
    display: table-cell;
    background-color: Tomato;
}

HTML

<div class="container clearfix">
    <div class="sidebar">
        simple text here
    </div>
    <div class="main">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam congue, tortor in mattis mattis, arcu erat pharetra orci, at vestibulum lorem ante a felis. Integer sit amet est ac elit vulputate lobortis. Vestibulum in ipsum nulla. Aenean erat elit, lacinia sit amet adipiscing quis, aliquet at erat. Vivamus massa sem, cursus vel semper non, dictum vitae mi. Donec sed bibendum ante.
    </div>
</div>

Exemple simple. Notez que vous pouvez vous transformer en réactivité.

2
Paula Fleck

Ajouter display: grid au parent

2
Dziamid

Ma solution:

$(window).resize(function() {
   $('#div_to_occupy_the_rest').height(
        $(window).height() - $('#div_to_occupy_the_rest').offset().top
    );
});
2
Rafael Ruiz Muñoz

Vous utilisez CSS Flexbox

.flex-container {
  display: flex;
  background-color: DodgerBlue;
}

.flex-container > div {
  background-color: #f1f1f1;
  margin: 10px;
  padding: 20px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
</div>

<p>A Flexible Layout must have a parent element with the <em>display</em> property set to <em>flex</em>.</p>

<p>Direct child elements(s) of the flexible container automatically becomes flexible items.</p>

</body>
</html>

1
Ini

J'ai eu le même problème, cela a fonctionné sur la base de la réponse de Hakam Fostok, j'ai créé un petit exemple. Dans certains cas, cela peut fonctionner sans avoir à ajouter display: flex; et flex-direction: column; sur le conteneur parent.

.row {
    margin-top: 20px;
}

.col {
    box-sizing: border-box;
    border: solid 1px #6c757d;
    padding: 10px;
}

.card {
    background-color: #a0a0a0;
    height: 100%;
}

JSFiddle

1
Builo

donner position: absolute; à l'enfant qui a travaillé dans mon cas

1
neoDev

[Se référant à Dmity's Less code dans une autre réponse] Je suppose qu'il s'agit d'une sorte de "pseudo-code"?

D'après ce que j'ai compris, essayez d'utiliser la technique des fausses colonnes qui devrait faire l'affaire.

http://www.alistapart.com/articles/fauxcolumns/

J'espère que cela t'aides :)

1
jluna

Il y a un peu de contradiction dans le titre et le contenu de la question. Le titre parle d'un div parent, mais la question donne l'impression que vous voulez que les divs frères (navigation et contenu) aient la même hauteur.

Voulez-vous (a) que la navigation et le contenu soient à 100% de la hauteur de la principale ou (b) que la navigation et le contenu soient de la même hauteur?

Je suppose que (b) ... si tel est le cas, je ne pense pas que vous puissiez le faire en raison de la structure de votre page actuelle (du moins, pas avec du CSS pur et sans script). Vous devrez probablement faire quelque chose comme:

<main div>
    <content div>
         <navigation div></div>
    </div>
</div>

et définissez la div de contenu de manière à avoir une marge gauche quelle que soit la largeur du volet de navigation. De cette façon, le contenu du contenu se trouve à droite de la navigation et vous pouvez définir la div de navigation sur 100% de la hauteur du contenu.

EDIT: Je le fais tout à fait dans ma tête, mais vous auriez probablement aussi besoin de régler la marge gauche de la div de navigation sur une valeur négative ou de la définir sur gauche absolue pour la repousser à l'extrême gauche. Le problème, c’est qu’il existe de nombreuses façons de résoudre ce problème, mais elles ne seront pas toutes compatibles avec tous les navigateurs.

1
Paul Abbott

Cette astuce fonctionne: Ajouter un dernier élément dans votre section HTML avec un style de clair: les deux;

    <div style="clear:both;"></div>

Tout ce qui précède sera inclus dans la hauteur.

1
user945389
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display:         flex;
 }

De:

http://getbootstrap.com.vn/examples/equal-height-columns/equal-height-columns.css

États bootstrap mais vous n'avez pas besoin de bootstrap pour l'utiliser. Répondre à cette vieille question, comme cela a fonctionné pour moi, et semble assez facile à mettre en œuvre. 

C’est la même réponse que j’ai fournie à cette question Question

0
eaglei22

Comme indiqué précédemment, la flexbox est la plus simple ... 

#main{ display: flex; align-items:center;}

cela alignera tous les éléments enfants sur le centre de l'élément parent.

0
Chandan Purohit

Voici une démonstration démodée basée sur position: absolute du conteneur de contenu et position: relative du conteneur parent.

Démo

En ce qui concerne la manière moderne de le faire - flex box sont les meilleurs.

0
WebBrother