We’ve been discussing various ways to build a UI where the display
is split into two <div>
s. One has a fixed width, the other should
occupy 100% of the remaining horizontal space. If the browser window
gets too narrow, a scrollbar should appear on the flexible element.
One solution would be to set the widths explicitly:
width: 300px
on the first elementwidth: calc(100%-300px)
on the second element
I did not like the idea, since this requires that the second element
needs to know how wide the first element is, in order to write the
calc()
property (i.e. 300 pixels). I’d rather have the browser
figure this out for me:
Here is the solution I’ve come up with:
<!DOCTYPE html>
<html>
<head>
</head>
<body style="margin: 0;
font-family: 'Open Sans', Arial, sans-serif;
font-size: 14px; line-height: 1.5;" >
<div id="root"
style="display: flex; flex-direction: row;
height: 100vh; background-color: cyan">
<div id="panel"
style="flex-basis: 100px; flex-grow: 0; flex-shrink: 0;
background-color: gold;">
</div>
<div id="surface"
style="flex-grow: 1; flex-shrink: 1;
overflow-x: auto;
display: flex; flex-direction: row;
margin: 10px; background-color: cornflowerblue;">
<div id="view"
style="min-width: 200px;
margin: 10px; background-color: white;">
<p style="padding-left: 10px; padding-right: 10px;">
Hello. This view has a minimal width of 200px. It will occupy all available
horizontal space if it is given the opportunity to grow...
</p>
</div>
</div>
</div>
</body>
</html>
Explanation
A root specifies that its children should be laid out using the
flex model,
displaying both inner <div>
side by side:
- The left panel sets its width using
flex-basis: 100px
and explicitly disables any growing or shrinking, making it fixed width. - The right surface does not set its width; it also specifies
that it may both grow and shrink. The
overflow-x: auto
ensures that a horizontal scrollbar will be added if the content no longer fits in the available space.
The surface contains an element which may not become too narrow. Its minimal width has been set to 200px. As soon as the surface gets below 210px (minimum width + left margin of view) a scrollbar appears.