#html #css
#HTML #css
Вопрос:
Мне нужно создать макет с 3 строками, который будет находиться внутри среднего столбца макета flex с 3 столбцами.
Макет должен заполнять этот средний столбец (100%, 100%) и должен содержать:
- Верхняя строка: может быть пустой или содержать содержимое. Его высота должна быть автоматической и должна расширяться до его содержимого.
- Нижняя строка: такая же, как и верхняя строка.
- Центральная строка: должна заполнять остальную часть вертикального пространства и не должна заставлять всю структуру расширяться за пределы того, что было изначально
Вот графическое описание:
Сначала я попробовал с таблицей, однако возникла проблема, заключающаяся в том, что при расширении центральной ячейки она расширяла всю таблицу, и таблица не учитывала высоту.
Затем я попробовал с помощью display: flex и столкнулся с практически той же проблемой, когда центральный div получал много содержимого, внутреннее содержимое не прокручивалось, но div расширялся за пределы доступного пространства.
Я изо всех сил пытаюсь заставить эту работу работать так, как ожидалось…
Это одна из моих неудачных попыток:
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>
Здесь все выглядит нормально, пока вы не нажмете кнопку, и белое поле не расширит таблицу … даже если таблица имеет фиксированный размер (50% от родительского). Pre получает полосу прокрутки, но поскольку она расширена до максимума, это ничего не значит…
Что должно произойти, так это то, что белое поле остается того же размера, и pre заполняет его, а pre получает полосу прокрутки, которая фактически прокручивается.
Еще одна проблема заключается в том, что в pre есть «пробел: pre», который не должен расширять белое поле ни по горизонтали. он должен быть обрезан или, если я добавлю overflow-x: scroll, он должен быть доступен для просмотра путем прокрутки pre.
Комментарии:
1. Я пытался создать для вас фрагмент, но ваш код div не совпадает с кодом таблицы в скрипке
2. извините, я разместил неправильную ссылку, я обновил вопрос сейчас
3. Но сделайте ФРАГМЕНТЫ, чтобы нам не приходилось оставлять ТАК, чтобы выглядеть
4. Сейчас есть один, но я не знал, как это сделать. Попробую в следующий раз. Извините.
5. Просто нажмите кнопку
[<>]
редактора фрагментов
Ответ №1:
Не можете ли вы просто добавить класс таким образом…
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>
Комментарии:
1. Il работает в Chrome, в Firefox таблица расширяется по вертикали за пределы процента от относительного родительского набора в его стиле.
2. Возможно, tables — это не выход, но у меня похожие проблемы с настройками макета с помощью divs.
3. Просто установите position: absolute и top: 0; Проверьте обновление.
Ответ №2:
Вам действительно следует избегать использования <table>
для размещения вашей страницы (если только это не для реальной таблицы). Избавьте себя от будущих проблем и используйте вместо этого CSS grid.
Макет из 3 столбцов, аналогичный тому, как вы описали, так же прост, как:
.container {
height: 100%;
display:grid;
grid-template-rows: auto 1fr auto;
}
.middle {
overflow: scroll;
}
РЕДАКТИРОВАТЬ: я не мог легко определить, какой код в вашей скрипке был требованием, а какой был просто частью процесса отладки. Итак, вот реплика, которую я перестроил с помощью CSS grid, которая решает вашу проблему:
Комментарии:
1. Мне кажется, что 1fr расширяется дальше, чем высота его родительского элемента, когда содержимое внутри высокое. По крайней мере, протестировано в firefox. Возможно, я что-то упускаю. Если вы можете заставить скрипку работать, начав с моей скрипки в вопросе, это было бы идеально.
2. Я обновил свой ответ новой скрипкой. Много html / css было удалено, но я надеюсь, что вы все еще можете найти это полезным. 🙂
3. Спасибо за усилия, Эдди, к сожалению, я уже знал, что предоставление переполнения средней ячейки устраняет проблему. Однако это не работает для меня, потому что внутренний PRE, который я вводю, является компонентом, к которому у меня нет доступа, и управляет его собственной прокруткой. Таким образом, PRE должен прокручиваться, а не div, как в вашем примере.
4. Интересно, вы можете присвоить внутреннему
<pre>
aheight: 100%
? Это приведет к его сужению и позволит прокручивать. (Я изменил ту же скрипку на новую с примером)