问题描述
我想实现的布局是这样的,正好填满浏览器的整个视口:
The layout I am trying to achieve is like this, exactly filling the entire viewport of the browser:
[----fixed height top "menu bar"----]
/-----\/----------------------------\
|fixed|| |
|width|| both ways stretchy content |
|side || |
|bar || |
\-----/\----------------------------/
我有它几乎工作,但我还没有想出如何指定水平排列的框垂直填充可用空间,而不是页面的高度。因为它目前的状态,当侧栏中的内容足够长,导致它获得一个滚动条,我结束了一个额外的垂直滚动条在整个页面,滚动精确的顶部条的高度,这不是什么我想要。
I have it nearly working, but I haven't figured out how to specify that the horizontally-arranged boxes vertically fill the space available to them rather than the height of the page. As it currently stands, whenever the content in the sidebar is long enough to cause it to gain a scroll bar, I end up with an additional vertical scrollbar on the entire page which scrolls by exactly the height of the top bar, which is not what I want.
以下1998样式演示页面说明了这个问题。
The following 1998-styled demo page illustrates the problem. It actually produces the layout I want in Safari 9, but not Chrome or Firefox.
请注意这些额外的约束,这些约束已经由演示满足,并且必须保留:
Note these additional constraints, which are already satisfied by the demo and must be preserved:
-
在水平方向上排列的任意数量的固定宽度或弹性盒。
There may be an arbitrary number of fixed-width or stretchy boxes arranged in the horizontal direction.
每个侧栏或主要内容都有 overflow-y:auto
垂直滚动条。这也必须工作(也就是说,长内容不能使整个flexbox布局超过视口大小)。一些侧边栏本身在垂直方向上使用弹性框布局。
Each side bar or main content has an overflow-y: auto
vertical scrollbar. This must also work (that is, long content must not make the overall flexbox layout exceed the viewport size). Some of the sidebars themselves use flexbox layout in the vertical direction.
90%-10%的布局不适合此目的。也不允许剪辑一些内容。我有这个布局问题的全部原因是应用程序应该使用屏幕的每个像素显示有用的信息或控件,因此任何额外的空白或剪辑的内容是不受欢迎的。
A 90%-10% layout is not suitable for the purpose. Nor is allowing some of the content to be clipped. The entire reason I have this layout problem is that the application should be using every pixel of the screen to show useful information or controls, so any extra whitespace or clipped content is undesirable.
<!doctype html>
<html style="height: 100%;">
<title>Flexbox test</title>
<style type="text/css">
#parent-of-topbar {
height: 100%; box-sizing: border-box; margin: 0;
background: #FCC;
display: flex; flex-direction: column;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
flex: 0 0 auto;
}
#main {
display: flex; flex-direction: row;
flex: 1 1 auto;
max-height: 100%;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
max-height: 100%;
border: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%,#AAA 100%);
}
.fixed {
flex: 0 0 auto;
width: 10em;
}
.stretchy {
flex: 1 1 auto;
width: 100%;
}
</style>
<body id="parent-of-topbar">
<div id="topbar">top bar content</div>
<div id="main">
<div class="subwindow stretchy">stretchy part</div>
<div class="subwindow fixed">
fixed sidebar 1; this should be scrollable, not stretch the content
<details open><div style="font-size: 3em;">spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div></details>
</div>
<div class="subwindow fixed">
2nd fixed sidebar
</div>
</div>
</body>
我想实现的布局屏幕截图,通过硬编码维度:
Here is a screenshot of the layout I want to achieve, faked by hardcoding a dimension:
这是当前演示在Chrome上获得的布局的屏幕截图:
Here is a screenshot of the layout the current demo gets on Chrome:
推荐答案
感谢,我已经找出了适用于演示以及我的实际应用程序的解决方案。
Thanks to Michael_B's answer and comments, I've figured out the solution which works for the demo as well as my actual application.
关键规则是:不要使用 height:100%;
或 width:100%;
在flexbox中的任何位置。即使这意味着转换 .subwindow
的内容,使用 flex-grow
The key rule is: do not use height: 100%;
or width: 100%;
anywhere inside of flexbox. Use flex-grow
to make things expand to fit their containers, even if this means converting the content of the .subwindow
elements to flexbox layout where it wasn't before.
此外,不要设置 flex-basis:auto
直接或通过 flex
快捷方式)。而是使用 flex:< number> ;; $ c>隐含地执行
flex-basis:0%
$ c>,并让增长注意填充容器。我仍然不确定这是否必要,如果你遵循第一条规则绝对,但它似乎有助于不完美的情况下。
Furthermore, do not set flex-basis: auto
(directly or via the flex
shortcut) on stretchy things. Instead use flex-basis: 0%
(or any zero length), which is implicitly done by flex: <number>;
, and let the growing take care of filling the container. I'm still not sure whether this is necessary if you follow the first rule absolutely, but it seems to help in imperfect cases.
修订演示(现在显示100%像我的真实应用程序,这是另一个复杂化):
Revised demo (now showing a 100%-like main panel as my real application had, which was another complication):
<!doctype html>
<html style="height: 100%;">
<title>Flexbox test</title>
<style type="text/css">
#parent-of-topbar {
height: 100%; box-sizing: border-box; margin: 0;
background: #FCC;
display: flex; flex-direction: column;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
}
#main {
display: flex; flex-direction: row;
flex: 1;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
border: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%,#AAA 100%);
display: flex;
flex-direction: column;
}
.fixed {
flex: 0 auto;
width: 10em;
}
.stretchy {
flex: 1;
}
</style>
<body id="parent-of-topbar">
<div id="topbar">top bar content</div>
<div id="main">
<div class="subwindow stretchy">
<div style="background: #CFC; flex: 1; vertical-align: middle; text-align: center;">stretchy content</div>
</div>
<div class="subwindow fixed">
fixed sidebar 1; this should be scrollable, not stretch the content
<details open><div style="font-size: 3em;">spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div></details>
</div>
<div class="subwindow fixed">
2nd fixed sidebar
</div>
</div>
</body>
这篇关于页面填充Flexbox布局与顶部和侧边栏不是很工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!