web-dev-qa-db-fra.com

Permettre à un élément de la grille de défiler avec un en-tête et une barre latérale fixes

J'ai une disposition de grille avec deux colonnes et deux lignes. Une navigation gauche collante, un en-tête collant et un contenu qui vivra dans le coin inférieur droit de la grille.

Ce que j'ai maintenant est presque là, mais j'aimerais que le .content div pour utiliser le défilement lorsque le contenu dépasse de l'écran. Je pensais pouvoir utiliser simplement overflow: auto, mais cela ne fonctionne pas. Est-ce que j'ai près?

body {
  margin: 0;
  overflow: hidden;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" "nav content";
}

.nav {
  grid-area: nav;
  background-color: blue;
}

.header {
  grid-area: header;
  background-color: grey;
}

.content {
  grid-area: content;
  height: 1000px; // This is dynamic
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>

violon JS

14
seanyesmunt

Pour overflow: auto pour fonctionner (c'est-à-dire pour que les barres de défilement soient affichées), les navigateurs ont besoin d'un déclencheur. Ce déclencheur est généralement une limitation de hauteur/largeur qui force une condition de débordement, qui lance les barres de défilement.

Les conditions de déclenchement varient selon les navigateurs. Ils varient également selon les technologies CSS, telles que les dispositions flex, grid et block.

Dans ce cas particulier, il existe plusieurs emplacements logiques pour établir une condition de débordement, mais aucun ne fonctionne.

  1. Vous pouvez cibler l'élément de grille, comme vous l'avez essayé:

    .content {
       height: 1000px
       overflow: auto;
    }
    

    Mais ça ne marche pas. Aucune barre de défilement n'apparaît sur l'élément fluide.

body {
  margin: 0;
  /* overflow: hidden; */
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" 
                       "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  grid-area: content;
  height: 1000px;
  overflow: auto;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>
  1. Vous pouvez cibler la ligne elle-même, comme je l'ai testé:

    .page {
       display: grid;
       grid-template-rows: 55px 1000px;
    }
    
    .content {
       overflow: auto;
    }
    

    Mais cela ne fonctionne pas non plus. Toujours pas de barre de défilement sur l'élément fluide.

body {
  margin: 0;
  /* overflow: hidden; */
}

.page {
  display: grid;
  grid-template-rows: 55px 1000px;
  grid-template-columns: 20vh auto;
  grid-template-areas:
    "nav header"
    "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  overflow: auto;
  grid-area: content;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>
  1. J'ai donc ciblé un enfant de l'élément de grille. Ding DING Ding! Ça a marché.

    Pas besoin de positionnement fixe. Pas besoin de positionnement collant. Cela fonctionne sur tous les navigateurs prenant en charge la disposition de grille.

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px calc(100vh - 55px);  /* height limitation on second row */
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" 
                       "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  grid-area: content;
  background-color: red;
  overflow: auto;                          /* overflow condition on parent */
}

article {
  height: 1000px;                          /* height set on child; triggers scroll */
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <article><!-- new section for content -->
      <h1>title</h1>
    </article>
  </div>
  <div>

démo jsFiddle

10
Michael_B

La prise en charge du navigateur n'est pas à 100%, mais qu'en est-il de l'utilisation réelle du collage au lieu du positionnement fixe? (maintenant testé dans Chrome) Vous n'aurez pas à gérer les marges codées en dur.

L'un des problèmes auxquels vous devrez toujours faire face, que faire lorsque le contenu de votre barre latérale (.nav > div) Est supérieur à votre fenêtre d'affichage.

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 3.5rem auto;
  grid-template-areas: "nav header" "nav content";
}

.nav {
  grid-area: nav;
  background-color: blue;
}

.nav > div {
  position: sticky;
  top: 0;
}

.header {
  grid-area: header;
  background-color: grey;
  position: sticky;
  top: 0;
  min-height: 3.5rem;
}

.content {
  grid-area: content;
  min-height: 1000px;
  background-color: red;
}
<div class="page">
  <div class="nav">
    <div>Side nav</div>
  </div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
<div>
4
René

J'ai inclus le journal des modifications pour voir où le code doit être modifié afin de comprendre. L'extrait de code complet est également disponible ci-dessous. J'espère que c'est ce que vous attendez.

Journal des modifications

*Retirer body { overflow: hidden; }

*Changement .page { grid-template-columns: 3.5rem auto; }

*Ajoutée

.nav { position: fixed;
      top: 0;
      bottom:0;}

*Ajoutée

.header {  position: fixed;
      margin-left: 3.5rem;
      width: 100%;
      height: 3.5rem; }

Code complet

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 3.5rem auto;
  grid-template-areas:
    "nav header"
    "nav content";
}

.nav {
  position: fixed;
  top: 0;
  bottom:0;
  grid-area: nav;
  background-color: blue;

}

.header {
  grid-area: header;
  background-color: grey;
  position: fixed;
  margin-left: 3.5rem;
  width: 100%;
  height: 3.5rem;
}

.content {
  grid-area: content;
  height: 1000px;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
<div>
2
Lakindu Gunasekara