CSS弹性布局:防止孙元素溢出(即强制滚动)

3

以下是所给的内容:

<main>
  <h1>Hello World</h1>
  <nav><button>Home</button> - <button>Contact</button> - <button>About</button></nav>
  <br>
  <div class=wrapper>
    <b>List header</b>
    <ul></ul>
  </div>
</main>

如何强制使 ul 滚动,而不是溢出到 main.wrapper 中?也就是说,滚动条应该出现在 ul 上,而不是 main.wrapper 中。不使用硬编码的值。
我尝试了以下 CSS 但失败了。如果我要滚动 .wrapper,它会起作用,但是我正在尝试滚动它的子元素。
main {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
}
.wrapper {
  flex: 1;
}
ul {
  overflow: auto; /* How to force this to scroll? */
}

Codepen代码编辑器:https://codepen.io/mustafa0x/pen/oNLXyxm

1个回答

3

块级元素默认会尽可能地增长。这就是为什么你的ul元素没有显示任何滚动条。

尝试设置高度,比如height: 150px,你就会看到一些滚动条。

// Lorem ipsum
const $ = q => document.querySelector(q);
const url = 'https://baconipsum.com/api/?type=all-meat&sentences=100';
fetch(url).then(r => r.json()).then(data => {
   $('ul').innerHTML = data[0].split('. ').map(l => '<li>' + l).join('\n');
});
main {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  
  /* Styling */
  max-width: 600px;
  margin: 0 auto;
  text-align: center;
}
.wrapper {
  flex: 1;
}
ul {
  overflow: auto; /* How to force this to scroll? */
  height: 150px;
  /* Styling */
  text-align: left;
}
<main>
  <h1>Hello World</h1>
  <nav><button>Home</button> - <button>Contact</button> - <button>About</button></nav>
  <br>
  <div class=wrapper>
    <b>List header</b>
    <ul></ul>
  </div>
</main>

由于您不允许使用固定值,也不允许修改HTML,您可以引入另一个flex。

flex项默认具有min-height: auto。这意味着flex项的大小不能小于其内容的大小。

为了覆盖它,您需要在flex项上设置min-height: 0,在本例中是.wrapper。这将导致.wrapper延伸到屏幕的末端。

但仍然会使ul元素增加大小。为了防止这种情况,在不使用固定单位的情况下,您需要将.wrapper转换为基于列的flexbox。

// Lorem ipsum
const $ = q => document.querySelector(q);
const url = 'https://baconipsum.com/api/?type=all-meat&sentences=100';
fetch(url).then(r => r.json()).then(data => {
   $('ul').innerHTML = data[0].split('. ').map(l => '<li>' + l).join('\n');
});
main {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  max-width: 600px;
  margin: 0 auto;
  text-align: center;
}
.wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
ul {
  overflow: auto; /* How to force this to scroll? */
  text-align: left;
}
<main>
  <h1>Hello World</h1>
  <nav><button>Home</button> - <button>Contact</button> - <button>About</button></nav>
  <br>
  <div class=wrapper>
    <b>List header</b>
    <ul></ul>
  </div>
</main>


谢谢。如上所述,对于我的用例来说,硬编码值不是一个选项。 - mustafa.0x
你能重新排列你的元素吗? - Jorjon
如果可能的话,只需将<b>标签移至包装器之前,然后将overflow: autoul移到包装器上即可。 - Jorjon
很遗憾,这不在实际的网络应用程序中。 - mustafa.0x
@mustafa.0x 我已经根据这些限制更新了我的答案,并提供了解决方案。 - Jorjon
1
谢谢!我在测试中尝试了这种方法,但错误地将min-height应用于了子元素。非常感谢。 - mustafa.0x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接