web-dev-qa-db-fra.com

Comment faire une colonne fixe en CSS en utilisant CSS Grid Layout?

J'ai créé un site simple avec un div #container parent de deux divs: #left et #right, en utilisant Grid Layout :

Est-il possible de fixer la colonne de gauche? J'aimerais que le texte de gauche persiste sur sa position et que le texte de droite puisse défiler comme il est maintenant. Ajouter position: fixed à #left interrompt la présentation.

Je suis conscient que cette question a déjà été résolue, mais j'apprécierais un moyen de la faire fonctionner avec la disposition de la grille.

Merci.

body {
  margin: 0 0 0 0;
}

#container {
  display: grid;
  grid-template-columns: 50% 50%;
}

.section {
  padding: 5% 5% 5% 5%;
}

#left {
  background-color: aquamarine;
}

#right {
  background-color: beige;
}
<div id="container">
  <div id="left" class="section">
    <p>This should not scroll</p>
  </div>
  <div id="right" class="section">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet consectetur purus nec volutpat. Donec vel libero nec est commodo facilisis vel et nisl. Praesent porta sed eros eu porta. Cras dolor nulla, ullamcorper et tincidunt quis, porta ut
      tellus. Maecenas cursus libero sed accumsan luctus. Integer sed consequat ante. Morbi sit amet lectus tempor elit tempor cursus ut sed enim. Donec placerat bibendum volutpat.
    </p>
    <p>
      Nunc sit amet eleifend sapien, sed tincidunt neque. Donec id sapien et nunc scelerisque iaculis dignissim nec mauris. Fusce at pretium nulla. Maecenas vel rutrum tellus, a viverra nunc. Aenean at arcu vitae dui faucibus dapibus. Vivamus hendrerit blandit
      mollis. Aenean sit amet lectus a metus faucibus condimentum. Proin vel eros ut elit pharetra lacinia vitae eu orci. Etiam massa massa, aliquam at pulvinar ut, porttitor eu mauris. Ut in iaculis sapien.
    </p>
    <p>
      In vitae rhoncus arcu. Maecenas elementum nunc quis magna finibus, vitae imperdiet diam pulvinar. Phasellus sit amet nibh eu massa facilisis luctus. Nulla ullamcorper sodales ante id vestibulum. Fusce felis nisi, lacinia sit amet mauris vel, euismod suscipit
      neque. Mauris quis libero eget enim facilisis pharetra. Fusce non ligula auctor nunc pretium dignissim eget eget turpis. Nam ultricies dolor ac libero maximus vestibulum. Mauris et tortor vitae nisi ultrices vestibulum ac id mauris. Proin interdum
      dapibus sollicitudin. Phasellus ultricies vulputate sem id hendrerit. Cras eget posuere nunc, in placerat velit. Pellentesque sed ante at elit ornare efficitur. Donec sed condimentum nisl. Curabitur dapibus leo id ligula dignissim pharetra.
    </p>
  </div>
</div>

10
MeLlamoPablo

Tu as écrit:

Est-il possible de fixer la colonne de gauche?

J'apprécierais un moyen de le faire fonctionner avec la disposition de grille.

Si vous voulez que l'élément reste un élément de la grille, la réponse est "non".

Une fois qu'un élément a position: absolute ou position: fixed ( qui est une forme de positionnement absolu, avec référence à la fenêtre d'affichage ), il revêt de nouvelles caractéristiques:

  • l'élément est supprimé du flux de documents
  • l'élément est supprimé du contexte de mise en forme grid
  • l'élément n'est plus un élément de grille

De la spécification:

10. Absolute Positionnement

Un enfant d'un conteneur de grille positionné de manière absolue est hors du flux et n'est pas un élément de la grille et n'affecte donc pas le placement d'autres éléments ou le dimensionnement de la grille.

Ainsi, un élément de grille ne fonctionne pas bien avec le positionnement absolu.

Cependant, vous n'aurez aucun problème à appliquer position: fixed à un conteneur de grille.

Pensez à gérer vos éléments #left et #right séparément. #left peut être un conteneur de grille à position fixe. #right peut être un autre conteneur de grille et rester en flux.


De plus, vous avez également indiqué à vos éléments de grille un remplissage à base de pourcentage:

.section {
    padding: 5% 5% 5% 5%;
}

Lorsque vous appliquez margin et padding à des éléments de la grille (et des éléments flexibles), il est préférable d'éviter les unités en pourcentage. Les navigateurs peuvent calculer les valeurs différemment.

11
Michael_B

Vous pouvez y parvenir en ajoutant ces règles CSS à votre identifiant #left:

position: sticky; // See link
top: 0; //to make it stick to the top of the screen
height: 100vh; // make the height equal to 100 view height

Lien pour position collante: Position collante avec rien mais CSS

sticky est une nouvelle valeur pour la propriété position, ajoutée à la spécification CSS3 Layout Module. Il agit de la même manière que le positionnement relatif, en ce sens qu’il ne supprime rien du flux de documents. En d'autres termes, un élément collant n'a aucun effet sur la position des éléments adjacents et ne réduit pas son élément parent.

J'espère que ça vous aide

EDIT (corrige le comportement instable)

Afin d'éviter que la partie gauche ne saute à la fin de la page, ajoutez simplement la règle CSS suivante à votre identifiant #left:

box-sizing: border-box;

Voir l'extrait de code mis à jour:

body {
    margin: 0 0 0 0;
}

#container {
    display: grid;
    grid-template-columns: 50% 50%;
}

.section {
    padding: 5% 5% 5% 5%;
}

#left {
    background-color: aquamarine;
    position: sticky;
    top: 0;
    height: 100vh;
    box-sizing: border-box;
}

#right {
    background-color: beige;
}
  
<div id="container">
    <div id="left" class="section">
        <p>This should not scroll</p>
    </div>
    <div id="right" class="section">
        <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet consectetur purus nec volutpat. Donec vel libero nec est commodo facilisis vel et nisl. Praesent porta sed eros eu porta. Cras dolor nulla, ullamcorper et tincidunt quis, porta ut tellus. Maecenas cursus libero sed accumsan luctus. Integer sed consequat ante. Morbi sit amet lectus tempor elit tempor cursus ut sed enim. Donec placerat bibendum volutpat.
        </p>
        <p>
            Nunc sit amet eleifend sapien, sed tincidunt neque. Donec id sapien et nunc scelerisque iaculis dignissim nec mauris. Fusce at pretium nulla. Maecenas vel rutrum tellus, a viverra nunc. Aenean at arcu vitae dui faucibus dapibus. Vivamus hendrerit blandit mollis. Aenean sit amet lectus a metus faucibus condimentum. Proin vel eros ut elit pharetra lacinia vitae eu orci. Etiam massa massa, aliquam at pulvinar ut, porttitor eu mauris. Ut in iaculis sapien.
        </p>
        <p>
            In vitae rhoncus arcu. Maecenas elementum nunc quis magna finibus, vitae imperdiet diam pulvinar. Phasellus sit amet nibh eu massa facilisis luctus. Nulla ullamcorper sodales ante id vestibulum. Fusce felis nisi, lacinia sit amet mauris vel, euismod suscipit neque. Mauris quis libero eget enim facilisis pharetra. Fusce non ligula auctor nunc pretium dignissim eget eget turpis. Nam ultricies dolor ac libero maximus vestibulum. Mauris et tortor vitae nisi ultrices vestibulum ac id mauris. Proin interdum dapibus sollicitudin. Phasellus ultricies vulputate sem id hendrerit. Cras eget posuere nunc, in placerat velit. Pellentesque sed ante at elit ornare efficitur. Donec sed condimentum nisl. Curabitur dapibus leo id ligula dignissim pharetra.
        </p>
    </div>
</div>

22
kevin b.

Ajoutez une div de plus dans le panneau de droite pour lequel vous voulez faire défiler le panneau, donnez max-height et overflow: auto; de sorte que le panneau de gauche reste collé et que son contenu défile.

body {
    margin: 0 0 0 0;
}

#container {
    display: grid;
    grid-template-columns: 50% 50%;
}

.section {
    padding: 5% 5% 5% 5%;
}

#left {
    background-color: aquamarine;
}

#right {
    background-color: beige;
}
.scroll-div {
    max-height: 300px;
    overflow: auto;
}
<div id="container">
    <div id="left" class="section">
        <p>This should not scroll</p>
    </div>
    <div id="right" class="section">
        <div class="scroll-div">
        <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet consectetur purus nec volutpat. Donec vel libero nec est commodo facilisis vel et nisl. Praesent porta sed eros eu porta. Cras dolor nulla, ullamcorper et tincidunt quis, porta ut tellus. Maecenas cursus libero sed accumsan luctus. Integer sed consequat ante. Morbi sit amet lectus tempor elit tempor cursus ut sed enim. Donec placerat bibendum volutpat.
        </p>
        <p>
            Nunc sit amet eleifend sapien, sed tincidunt neque. Donec id sapien et nunc scelerisque iaculis dignissim nec mauris. Fusce at pretium nulla. Maecenas vel rutrum tellus, a viverra nunc. Aenean at arcu vitae dui faucibus dapibus. Vivamus hendrerit blandit mollis. Aenean sit amet lectus a metus faucibus condimentum. Proin vel eros ut elit pharetra lacinia vitae eu orci. Etiam massa massa, aliquam at pulvinar ut, porttitor eu mauris. Ut in iaculis sapien.
        </p>
        <p>
            In vitae rhoncus arcu. Maecenas elementum nunc quis magna finibus, vitae imperdiet diam pulvinar. Phasellus sit amet nibh eu massa facilisis luctus. Nulla ullamcorper sodales ante id vestibulum. Fusce felis nisi, lacinia sit amet mauris vel, euismod suscipit neque. Mauris quis libero eget enim facilisis pharetra. Fusce non ligula auctor nunc pretium dignissim eget eget turpis. Nam ultricies dolor ac libero maximus vestibulum. Mauris et tortor vitae nisi ultrices vestibulum ac id mauris. Proin interdum dapibus sollicitudin. Phasellus ultricies vulputate sem id hendrerit. Cras eget posuere nunc, in placerat velit. Pellentesque sed ante at elit ornare efficitur. Donec sed condimentum nisl. Curabitur dapibus leo id ligula dignissim pharetra.
        </p>
    </div>
    </div>
</div>

0
Venu Madhav

Vous pouvez faire quelque chose comme ça

voici le violon

voici le code

body {
    margin: 0 0 0 0;
}

#container {
    display: grid;

}

.section {
    padding: 5% 5% 5% 5%;
}

#left {
    background-color: aquamarine;
    height: 100%;
    position: fixed;
    width: 50%
}

#right {
    background-color: beige;
    overflow: scroll;
    width: 50%;
    right: 0;
    position: absolute;
}
0
Shingai Munyuki

J'ai eu un peu le même problème. J'avais besoin d'un sidenav fixe (col 1) avec un contenu défilable (col 2). Voici comment j'ai résolu le problème (notez que j'utilise styled-composant, mais vous pouvez sûrement le faire avec des fichiers CSS normaux, sass, less, etc.

<Grid>
  <SideNav>
    <Sider>
  </SideNav>
  <Content />
<Grid>

Maintenant, la propriété css pour chacun de ces composants stylés:

const Grid = styled.div`
  position: relative;
  display: grid;
  height: 100%;
  grid-template-columns: auto 1fr;
  grid-template-areas: 'sidenav content';
`

const Sidenav = styled.div`
  position: relative;
  grid-area: sidenav;
`
const Content = styled.div`
  position: relative;
  grid-area: content;
  width: 100%;
`

const Sider = styled.aside`
  position: fixed;
  height: 100vh;
`

Cela ressemble à ceci, mais un peu plus complexe de mon côté puisque j'ai aussi un en-tête et un pied de page dans ma grille, et le sidenav est pliable. Mais je pense que cela pourrait fonctionner pour vous.

0
Alexandre Cadieux

essaye ça: 

body {
    margin: 0 0 0 0;
}

#container {
    display: grid;
    grid-template-columns: 50% 50%;
}

.section {
    padding: 5% 5% 5% 5%;
}

#left {
    background-color: aquamarine;

    p {
      position: fixed;
    }
}

#right {
    background-color: beige;
}

https://jsfiddle.net/km5gdrcm/3/

0
Özlem