如何使用 CSS 网格布局在 CSS 中制作固定列?

How to make a fixed column in CSS using CSS Grid Layout?

我用 #container div 创建了一个简单的站点,它是两个 div 的父级:#left#right,通过使用Grid Layout:

请问有什么方法可以固定左边的列吗?我希望左边的文本保留在其位置上,而右边的文本可以像现在一样滚动。将 position: fixed 添加到 #left 会破坏布局。

我知道这个问题已经解决了,但我希望有一种方法可以让它与网格布局一起工作。

谢谢。

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>

您可以通过将这些 CSS 规则添加到您的 ID 来实现此目的#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

Link 粘性位置:Sticky position with nothing but CSS

sticky is a new value for the position property, added as part of CSS3 Layout Module Spec. It acts similarly to relative positioning, in that it doesn’t remove anything from the document flow. In other words, a sticky element has no effect on the position of adjacent elements and doesn't collapse its parent element.

希望对你有帮助

编辑(修复跳跃行为)

为了避免左边部分跳到页面末尾,只需在您的id中添加以下CSS规则#left:

box-sizing: border-box;

查看更新后的代码片段:

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>

你可以这样做

这里是fiddle

这是代码

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;
}

试试这个:

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/

在右侧面板中再添加一个 div,您要为哪个面板滚动,给出一些 max-heightoverflow: auto;,这样左侧面板将保持不变,右侧面板内容将滚动。

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>

您写道:

Is there any way to make the left column fixed?

I'd appreciate a way to make it work with the grid layout.

如果您希望元素保留为网格项,那么答案是 "no"。

一旦元素具有 position: absoluteposition: fixed (which is a form of absolute positioning, with reference to the viewport),它就会具有新的特征:

来自规范:

10. Absolute Positioning

An absolutely-positioned child of a grid container is out-of-flow and not a grid item, and so does not affect the placement of other items or the sizing of the grid.

所以 网格项 不能很好地使用绝对定位。

但是,将 position: fixed 应用于 网格容器.

不会有问题

考虑单独管理 #left#right 元素。 #left 可以是固定位置的网格容器。 #right 可以是另一个网格容器并保持流入。


另外,顺便说一句,您已经为网格项目提供了基于百分比的填充:

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

marginpadding 应用于网格项目(和弹性项目)时,最好远离百分比单位。浏览器可能会以不同方式计算值。

我遇到了一些同样的问题。我需要一个带有可滚动内容(第 2 列)的固定 sidenav(第 1 列)。这是我解决问题的方法(请注意,我使用样式化组件,但您当然可以使用常规 css、sass、less 或其他任何方式来解决):

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

现在 css 属性 每个样式组件:

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;
`

它看起来像这样,但在我这边有点复杂,因为我的网格中也有页眉和页脚,而且 sidenav 是可折叠的。但我认为这对你有用。

你不能让左边有粘性,但你可以让里面的所有内容都有粘性。为此,您应该制作粘性包装器元素并将所有内容放入其中,如下所示:

HTML:

<div class="grid">

    <div class="left">
       <div class="sticky_wrapper">Content</div>
    </div>

    <div class="right">
        Content
    </div>

</div>

CSS:

.grid { display: grid; grid-template-columns: 50% 50%; }
.left { background-color: aquamarine; }
.right { background-color: beige; }
.sticky_wrapper { position: sticky; top: 0; }

所以粘性包装中的所有内容都不会滚动。

我今天偶然发现了这个并通过添加使其工作:

#left {
  position: sticky;
  left: 0;
}