简体   繁体   中英

How to make a html/css 3 row layout where the middle row fits the remaining content and does not expand the parent

I need to create a 3 row layout that will sit inside the middle column of a flex 3 column layout.

The layout should fill this middle column (100%,100%) and should contain:

  • Top row: can be empty or have content. It's height should be auto, and should expand to its content.
  • Bottom row: same as top row.
  • Center row: should fill the rest of the vertical space, and should not make the whole structure expand beyond what it was initially

Here is a graphical description:

在此处输入图像描述

I first tried with a table, however this had a problem that when the center cell expanded it would expand the whole table and the table would not respect the height.

Next I tried with display:flex and had basically the same problem, when the center div would get a lot of content the inner content would not scroll but the div would expand beyond the available space.

I am struggling to make this work as expected...

This is one of my failed attempts:

https://jsfiddle.net/zm12bgxq/

 $("#fillme").click(() => { $("#row-center").empty(); let pre = $("<pre>"); pre.css({ "white-space": "pre-wrap", "overflow-y": "scroll", "overflow-x": "auto" }) $("#row-center").append(pre); for (let i = 0; i < 100; i++) { pre.append("<span>Some long text, Some long text, Some long text, Some long text, Some long text, Some long text, Some long text<br></span>") } })
 html, body { width: 100%; height: 100%; } #body { position: relative; top: 50px; left: 50px; height: 50%; width: 50%; background-color: green; display: flex; flex-direction: column; } #mainWin, #content-wrapper { position: relative; width: 100%; } #content-wrapper { height: 100%; } #mainWin { flex: 1; } #menuBar { background-color: red; height: 40px; position: relative; } #content-wrapper { height: 100%; width: 100%; display: flex; border: 0;important: margin; 0:important; padding: 0;important: } #column-left { flex-direction; row: display; block: position; relative: width; auto: height; 100%: border; 0:important; margin: 0;important: padding; 0:important; background-color: green; } #column-right { flex-direction: row; display: block; position: relative; width: auto; height: 100%; border: 0;important: margin; 0:important; padding: 0;important: background-color; green: } #column-center { flex-direction; row: display; flex: position; relative: height; 100%: flex; 1: border; 0:important; margin: 0;important: padding; 0:important; background-color: yellow; } #center-content { display: flex; position: relative; height: 100%; width: 100%; flex-direction: column; } #center-content table { width: 100%; height: 100%; border: 0;important: margin; 0:important; padding: 0;important: border-collapse; collapse: border-spacing; 0: } #center-content tr { border; 0:important; margin: 0;important: padding; 0:important; } #center-content td { border: 0;important: margin; 0:important; padding: 0;important: } #row-top { position; relative: width; 100%: height; 1%: flex-direction; column: border; 0:important; margin: 0;important: padding; 0:important; background-color: blue; } #row-center { width: 100%; height: auto; position: relative; flex: 1; flex-direction: row; border: 0 !important; margin: 0 !important; padding: 0 !important; background-color: white; } #row-bottom { position: relative; width: 100%; height: 1%; flex-direction: row; border: 0 !important; margin: 0 !important; padding: 0 !important; background-color: magenta; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="body"> <div id="menuBar"> <ul> <li>Somemenu</li> </ul> </div> <div id="mainWin"> <div id="content-wrapper"> <div id="column-left"> Left </div> <div id="column-center"> <div id="center-content"> <table> <tbody> <tr> <td id="row-top">Top</td> </tr> <tr> <td id="row-center"> <button id="fillme"> Fill me </button> </td> </tr> <tr> <td id="row-bottom"> <div id="cmdCont"> <textarea autofocus="" rows="1" style="width:100%;height: 20px;"></textarea> </div> </td> </tr> </tbody> </table> </div> </div> <div id="column-right"> Right </div> </div> </div> </div>

Here it looks ok until you press the button and the white box expands the table... even tough the table has fixed size (50% of parent). The pre gets a scrollbar but since it is expanded to maximum it means nothing...

What should happen is that the white box remains the same size and the pre fills it and the pre gets a scrollbar that is actually scrolling.

Another concern is having "white-space: pre" on the pre, which should not expand the white box neither horizontally. it should be clipped or if i put overflow-x: scroll then it should be viewable by scrolling the pre.

You should really avoid using <table> for laying out your page (unless it's for an actual table). Save yourself the future hassle and use CSS grid instead.

A 3 column layout similar to how you described is as simple as:

.container {
  height: 100%;
  display:grid;
  grid-template-rows: auto 1fr auto;
}

.middle {
  overflow: scroll;
}

EDIT: I couldn't easily tell which code in your fiddle was a requirement, and which was just part of the debugging process. So here's a replica I rebuilt using CSS grid that solves your issue:

https://jsfiddle.net/mwsj94qx/

Cant you simply add a class like so...

pre {
 height: 100%;
 position: absolute;
 top: 0;
}

 $("#fillme").click(() => { $("#row-center").empty(); let pre = $("<pre>"); pre.css({ "white-space": "pre-wrap", "overflow-y": "scroll", "overflow-x": "auto" }) $("#row-center").append(pre); for (let i = 0; i < 100; i++) { pre.append("<span>Some long text, Some long text, Some long text, Some long text, Some long text, Some long text, Some long text<br></span>") } })
 pre { height: 100%; position: absolute; top: 0; } html, body { width: 100%; height: 100%; } #body { position: relative; top: 50px; left: 50px; height: 50%; width: 50%; background-color: green; display: flex; flex-direction: column; } #mainWin, #content-wrapper { position: relative; width: 100%; } #content-wrapper { height: 100%; } #mainWin { flex: 1; } #menuBar { background-color: red; height: 40px; position: relative; } #content-wrapper { height: 100%; width: 100%; display: flex; border: 0;important: margin; 0:important; padding: 0;important: } #column-left { flex-direction; row: display; block: position; relative: width; auto: height; 100%: border; 0:important; margin: 0;important: padding; 0:important; background-color: green; } #column-right { flex-direction: row; display: block; position: relative; width: auto; height: 100%; border: 0;important: margin; 0:important; padding: 0;important: background-color; green: } #column-center { flex-direction; row: display; flex: position; relative: height; 100%: flex; 1: border; 0:important; margin: 0;important: padding; 0:important; background-color: yellow; } #center-content { display: flex; position: relative; height: 100%; width: 100%; flex-direction: column; } #center-content table { width: 100%; height: 100%; border: 0;important: margin; 0:important; padding: 0;important: border-collapse; collapse: border-spacing; 0: } #center-content tr { border; 0:important; margin: 0;important: padding; 0:important; } #center-content td { border: 0;important: margin; 0:important; padding: 0;important: } #row-top { position; relative: width; 100%: height; 1%: flex-direction; column: border; 0:important; margin: 0;important: padding; 0:important; background-color: blue; } #row-center { width: 100%; height: auto; position: relative; flex: 1; flex-direction: row; border: 0 !important; margin: 0 !important; padding: 0 !important; background-color: white; } #row-bottom { position: relative; width: 100%; height: 1%; flex-direction: row; border: 0 !important; margin: 0 !important; padding: 0 !important; background-color: magenta; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="body"> <div id="menuBar"> <ul> <li>Somemenu</li> </ul> </div> <div id="mainWin"> <div id="content-wrapper"> <div id="column-left"> Left </div> <div id="column-center"> <div id="center-content"> <table> <tbody> <tr> <td id="row-top">Top</td> </tr> <tr> <td id="row-center"> <button id="fillme"> Fill me </button> </td> </tr> <tr> <td id="row-bottom"> <div id="cmdCont"> <textarea autofocus="" rows="1" style="width:100%;height: 20px;"></textarea> </div> </td> </tr> </tbody> </table> </div> </div> <div id="column-right"> Right </div> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM