Html 如何使用 CSS 网格布局在 CSS 中创建固定列?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43999732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:40:01  来源:igfitidea点击:

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

htmlcssgrid-layoutcss-grid

提问by MeLlamoPablo

I've made a simple site with a #containerdiv that is parent to two divs: #leftand #right, by using Grid Layout:

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

Is there any way to make the left column fixed? I'd like the left text to persist on its position, and the right text to be scrollable as it is now. Adding position: fixedto #leftbreaks the layout.

有什么办法可以使左列固定吗?我希望左边的文本保持在它的位置,右边的文本可以像现在一样滚动。添加position: fixed#left打破布局。

I'm aware that this question has been already solved, but I'd appreciate a way to make it work with the grid layout.

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

Thanks.

谢谢。

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>

采纳答案by Michael Benjamin

You wrote:

你写了:

Is there any way to make the left column fixed?

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

有什么办法可以使左列固定吗?

我很感激有一种方法可以让它与网格布局一起工作。

If you want the element to remain a grid item, then the answer is "no".

如果您希望元素保持网格项,那么答案是“否”。

Once an element has position: absoluteor position: fixed(which is a form of absolute positioning, with reference to the viewport), it takes on new characteristics:

一旦元素具有position: absoluteposition: fixed这是一种绝对定位的形式,参考视口),它就会具有新的特征:

  • the element is removed from the document flow
  • the element is removed from the grid formatting context
  • the element is no longer a grid item

From the spec:

从规范:

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.

10.绝对定位

网格容器的绝对定位子项是流出的,而不是网格项,因此不会影响其他项的放置或网格的大小。

So a grid itemdoesn't work well with absolute positioning.

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

However, you won't have a problem applying position: fixedto a grid container.

但是,应用position: fixed网格容器不会有问题。

Consider managing your #leftand #rightelements separately. #leftcan be a fixed-position grid container. #rightcan be another grid container and remain in-flow.

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



Also, as an aside, you've given your grid items percentage-based padding:

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

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

When applying marginand paddingto grid items (and flex items), it's best to stay away from percentage units. Browsers may compute the values differently.

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

回答by kevin b.

You can achieve this by adding these CSS rules to your id #left:

您可以通过将这些 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 for sticky position: Sticky position with nothing but CSS

粘性位置的链接:除了 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.

Sticky 是 position 属性的新值,作为 CSS3 布局模块规范的一部分添加。它的作用类似于相对定位,因为它不会从文档流中删除任何内容。换句话说,粘性元素对相邻元素的位置没有影响,也不会折叠其父元素。

Hope it helps you

希望对你有帮助

EDIT (fix jumpy behaviour)

编辑(修复跳跃行为)

In order to avoid the left part to jump up at the end of the page, just add the following CSS rule to your id #left:

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

box-sizing: border-box;

See updated code snippet:

查看更新的代码片段:

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>

回答by Lenin-Kerrigan

You can't make left be sticky, but you can make all content in it be sticky. For this you should make sticky wrapper element and place all content in it like so:

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

HTML:

HTML:

<div class="grid">

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

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

</div>

CSS:

CSS:

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

So all content in the sticky wrapper will not scrool.

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

回答by Shingai Munyuki

You can do something like this

你可以做这样的事情

here is the fiddle

这是小提琴

here is the 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;
}

回答by ?zlem

try this:

尝试这个:

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/

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

回答by Venu Madhav

Add one more div in right panel which panel you want to scroll for that give some max-heightand overflow: auto;so left panel will be stick and right panel content will scroll.

在右侧面板中再添加一个 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>

回答by Alexandre Cadieux

I had a bit of the same problem. I needed a fixed sidenav (col 1) with scrollable content (col 2). Here's how I solved the problem (note that I use styled-component, but you can surely do it with regular css, sass, less, or whatever):

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

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

Now the css property for each of those styled-components:

现在每个样式组件的 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;
`

It looks like this, but a bit more complex on my side since I also have a header and footer in my grid, and the sidenav is collapsable. But I think this could work for you.

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