web-dev-qa-db-fra.com

Faire défiler une partie du contenu dans le conteneur à positions fixes

J'ai un position: fixed div dans une mise en page, sous forme de barre latérale. On m'a demandé de laisser une partie de son contenu rester en haut (en interne), et le reste de faire défiler s'il déborde au bas de la div.

J'ai jeté un œil à cette réponse , mais la solution présentée ne fonctionne pas avec les conteneurs position: fixed ou position: absolute, ce qui est pénible.

J'ai fait une démonstration JSFiddle de mon problème ici . La grande quantité de texte doit idéalement défiler au lieu de déborder dans le bas de la page. La hauteur de l'en-tête peut varier en fonction du contenu et peut être animée.

body {
    background: #eee;
    font-family: sans-serif;
}

div.sidebar {
    padding: 10px;
    border: 1px solid #ccc;
    background: #fff;
    position: fixed;
    top: 10px;
    left: 10px;
    bottom: 10px;
    width: 280px;
}
div#fixed {
    background: #76a7dc;
    padding-bottom: 10px;
    color: #fff;
}

div#scrollable {
    overlow-y: scroll;
}
<div class="sidebar">
    <div id="fixed">
        Fixed content here, can be of varying height using jQuery $.animate()        
    </div>

    <div id="scrollable">
        Scrolling content<br><br>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </div>
</div>

Sans un en-tête fixe, je peux simplement ajouter overflow-y: scroll à div.sidebar et je peux facilement faire défiler tout son contenu s'il déborde du bas du conteneur. Cependant, je rencontre des problèmes avec un en-tête à hauteur variable fixe en haut de la barre latérale et un contenu sous ce parchemin s'il est trop long pour tenir dans le conteneur. 

div.sidebarmust restez position: fixed, et j'aimerais beaucoup pouvoir le faire sans aucun piratage, ainsi que le rendre aussi multi-navigateur que possible. J'ai essayé diverses choses, mais aucune d'entre elles ne fonctionne, et je ne sais pas trop quoi essayer d'ici.

Comment puis-je faire défiler un div à l'intérieur d'un conteneur position: fixed uniquement dans la direction Y lorsque son contenu déborde du div qui le contient, avec un en-tête fixe de hauteur variable et indéterminée? J'aimerais beaucoup rester à l'écart de JS, mais si je dois l'utiliser, je le ferai.

54
Bojangles

Cela semble fonctionner si vous utilisez

div#scrollable {
    overflow-y: scroll;
    height: 100%;
}

et ajoutez padding-bottom: 60px à div.sidebar

Par exemple: http://jsfiddle.net/AKL35/6/

Cependant, je ne sais pas pourquoi il doit s'agir de 60px.

De plus, vous avez manqué la variable f de overflow-y: scroll; 

82
FrogInABox

Ce qui a fonctionné pour moi:

div#scrollable {
    overflow-y: scroll;
    max-height: 100vh;
}
1
Julien

J'ai changé de div avec une position absolue, et tout fonctionne pour moi

div.sidebar {
    overflow: hidden;
    background-color: green;
    padding: 5px;
    position: fixed;
    right: 20px;
    width: 40%;
    top: 30px;
    padding: 20px;
    bottom: 30%;
}
div#fixed {
    background: #76a7dc;
    color: #fff;
    height: 30px;
}

div#scrollable {
    overflow-y: scroll;
    background: lightblue;

    position: absolute;
    top:55px; 
    left:20px;
    right:20px;
    bottom:10px;
}

DEMO avec deux div défilables

1
Dmitri Algazin

En fait, c’est une meilleure façon de le faire. Si height: 100% est utilisé, le contenu disparaît de la frontière, mais lorsqu'il est 95%, tout est en ordre:

div#scrollable {
    overflow-y: scroll;
    height: 95%;
}
0
Vasil