未通过位置:绝对触发溢出

问题描述 投票:2回答:2

在此布局中,我将CSS网格与position: absolute结合使用,以显示覆盖在地图顶部的项目列表。我的问题是overflow-x: auto未被触发,导致仅显示前几个项目。

通过将列表的grid-auto-columnsminmax(auto, 1fr)更改为minmax(0, 1fr),我确实获得了一个滚动条,但是项目相互重叠。

代码笔:https://codepen.io/tgel0/pen/ZEbKZvb

.wrapper{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  height: 100vh;
  width: 100vw;
  grid-template-areas:
  "side side main main"
  "side side main main"
}

.side {
  grid-area: side;
  display: grid;
  grid-template-columns: 1fr;
  padding: 20px;
  color: #fff;
  background-color: green;
}


.main {
  grid-area: main;
  display: grid;
  background-color: gray;
  grid-template-columns: 1px 1fr 1px;
  gap: 20px;
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
}

.main > * {
  grid-column: 1 / -1;
}

.map {
  background-image: url("https://lh3.googleusercontent.com/-bQzIWFMAYus/WXy3WDcphBI/AAAAAAAAAMs/unOi6HiEoi4VWaM0WiP5q32q9zDbIhUvwCLcBGAs/s1600/7-29-2017%2B11-14-59%2BAM.jpg");
  height: 100%;
  overflow: auto;
}

.container-for-items {
  display: grid;
  grid-template-columns: 10px;
  grid-template-rows: 1fr;  
  grid-auto-columns: minmax(0, 1fr); /* minmax(auto, 1fr); */
  grid-auto-flow: column;
  grid-gap: 20px;
  padding: 20px;
  z-index: 99;
  position: absolute;
  bottom: 20px;
  overflow-x: auto;
}

container-for-items:before,
.container-for-items:after {
  content: '';
  width: 10px;
}

.item {
  display: grid; 
  background-color: white;
  border: 2px solid blue;
  padding: 25px;
  width: 300px;
  height: 150px;
}
<div class="wrapper">
  <div class="side">Don't scroll</div>
  <div class="main">
    <div class="map"></div>
    <ul class="container-for-items">
      <li class="item">This is item 1</li>
      <li class="item">This is item 2</li>
      <li class="item">This is item 3</li>
      <li class="item">This is item 4</li>
      <li class="item">This is item 5</li>
      <li class="item">This is item 6</li>
      <li class="item">This is item 7</li>
      <li class="item">This is item 8</li>
      <li class="item">This is item 9</li>
      <li class="item">This is item 10</li>
      <li class="item">This is item 11</li>
    </ul>    
  </div>  
</div>
html css css-grid
2个回答
2
投票

这种布局有很多工作–嵌套的网格,绝对位置,背景图像以及很多看似不必要的代码-因此算法可能会发生冲突(例如,我在Chrome / FF和Edge上不断获得不同的渲染)。

我认为最简单的解决方案是删除所有不必要的代码,绝对定位图像(而不是容器),并简化网格结构。

无需在HTML中进行任何更改。

.wrapper{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  height: 100vh;
  /* width: 100vw; */
  grid-template-areas:
  "side side main main"
  "side side main main"
}

.side {
  grid-area: side;
  display: grid;
  /* grid-template-columns: 1fr; */
  padding: 20px;
  color: #fff;
  background-color: green;
}

.main {
  grid-area: main;
  display: grid;
  background-color: gray;
  /* grid-template-columns: 1px 1fr 1px; */
  gap: 20px;
  position: relative;
  /* overflow-y: auto; */
  /* overflow-x: hidden; */
}

/* .main > * {
  grid-column: 1 / -1;
} */

.map {
  background-image: url("https://lh3.googleusercontent.com/-bQzIWFMAYus/WXy3WDcphBI/AAAAAAAAAMs/unOi6HiEoi4VWaM0WiP5q32q9zDbIhUvwCLcBGAs/s1600/7-29-2017%2B11-14-59%2BAM.jpg");
  height: 100vh; /* adjustment */
  width: 100%; /* new */
  position: absolute; /* new */
  /* overflow: auto; */
}

.container-for-items {
  display: grid;
  /* grid-template-columns: 10px; */
  grid-template-rows: 150px; /* adjustment; from grid items */  
  grid-auto-columns: 300px; /*  adjustment; from grid items */
  /* grid-auto-flow: column; */
  grid-gap: 20px;
  padding: 20px;
  z-index: 99;
  /* position: absolute; */
  /* bottom: 20px; */
  align-self: end; /* new */
  overflow-x: auto;
  position: relative; /* for Edge */
}

/* reverse collapsing margin at container end */
/* https://stackoverflow.com/q/38993170/3597276 */
/* .container-for-items:before (unnecessary; remove) */
.container-for-items:after {
  content: '';
  width: 10px;
  grid-row: 1;
}

.item {
  grid-row: 1; /* new */
  display: grid; 
  background-color: white;
  border: 2px solid blue;
  padding: 25px;
  /* width: 300px;  */ /* move to grid-template-columns */
  /* height: 150px; */ /* move to grid-template-rows */
}

/* new */
body {
  margin: 0;
}

* {
  box-sizing: border-box;
}
<div class="wrapper">
  <div class="side">Don't scroll</div>
  <div class="main">
    <div class="map"></div>
    <ul class="container-for-items">
      <li class="item">This is item 1</li>
      <li class="item">This is item 2</li>
      <li class="item">This is item 3</li>
      <li class="item">This is item 4</li>
      <li class="item">This is item 5</li>
      <li class="item">This is item 6</li>
      <li class="item">This is item 7</li>
      <li class="item">This is item 8</li>
      <li class="item">This is item 9</li>
      <li class="item">This is item 10</li>
      <li class="item">This is item 11</li>
    </ul>
  </div>
</div>

revised codepen


1
投票

要启用滚动,元素必须满足两个规则:

  1. 一个限制
  2. [overflow设置为autoscroll] >>
  3. 在您的情况下,不遵守规则1。

我们可以简单地向网格添加一个宽度,它将按预期工作。

.wrapper{
  display: grid;
  grid-template-columns: 0.5fr 0.5fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  height: 100vh;
  width: 100vw;
  grid-template-areas:
  "side side main main"
  "side side main main"
}

.side {
  grid-area: side;
  display: grid;
  grid-template-columns: 1fr;
  padding: 20px;
  color: #fff;
  background-color: green;
}


.main {
  grid-area: main;
  display: grid;
  background-color: gray;
  grid-template-columns: 1px 1fr 1px;
  gap: 20px;
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
}

.main > * {
  grid-column: 1 / -1;
}

.map {
  background-image: url("https://lh3.googleusercontent.com/-bQzIWFMAYus/WXy3WDcphBI/AAAAAAAAAMs/unOi6HiEoi4VWaM0WiP5q32q9zDbIhUvwCLcBGAs/s1600/7-29-2017%2B11-14-59%2BAM.jpg");
  height: 100%;
  overflow: auto;
}

.container-for-items {
  display: grid;
  grid-template-columns: 10px; /* this is making the first column shorter than the grid item so it will be overlapped by the next element */
  grid-template-rows: 1fr;  
  /* removed columns rule */
  grid-auto-flow: column;
  grid-gap: 20px;
  padding: 20px;
  z-index: 99;
  position: absolute;
  bottom: 20px;
  overflow-x: auto;
  
  width:100%; /* Added */
}

container-for-items:before,
.container-for-items:after {
  content: '';
  width: 10px;
}

.item {
  display: grid; 
  background-color: white;
  border: 2px solid blue;
  padding: 25px;
  width: 300px;
  height: 150px;
}
<div class="wrapper">
  <div class="side">Don't scroll</div>
  <div class="main">
    <div class="map"></div>
    <ul class="container-for-items">
      <li class="item">This is item 1</li>
      <li class="item">This is item 2</li>
      <li class="item">This is item 3</li>
      <li class="item">This is item 4</li>
      <li class="item">This is item 5</li>
      <li class="item">This is item 6</li>
      <li class="item">This is item 7</li>
      <li class="item">This is item 8</li>
      <li class="item">This is item 9</li>
      <li class="item">This is item 10</li>
      <li class="item">This is item 11</li>
    </ul>    
  </div>  
</div>

在上面的代码段中,您可以看到我一起删除了grid-auto-columns为什么?

First网格是绝对定位的元素,这意味着它将取决于其内容来定义其宽度。

minmax(auto,1fr);

1fr基本相同,这意味着网格track/columns不能小于网格项目的内容,这将防止网格缩小,但您看不到它,因为.main上隐藏了溢出,因此没有滚动条。


在这种情况下更改为minmax(0, 1fr);,可以根据需要更改track/columns,因此,如果我们只有很少的项目,track/columns将等于网格项目。

但是,如果我们继续添加项目,则网格将最终保持增长,直到它碰到其父对象的右边缘时,网格将停止收缩,内部的track/columns将缩小以适合(1fr),但是网格项目将重叠,因为它们是比track/columns


现在的问题是:网格是否取决于内容,为什么它停止增长?

[我怀疑是因为overflow:auto是阻止元素根据内容增长的约束之一,还是因为网格的绝对位置达到right:0;而停了下来。

我不确定,因为它不适用于flexbox或正常的块流,所以我不太确定,我希望有人能对此进行解释。

© www.soinside.com 2019 - 2024. All rights reserved.