这感觉应该是可以实现的,但我找不到合适的属性组合来满足我的需求.

我有一个布局,其中包含以下内容:

  • 顶部的标题栏应始终可见
  • 左侧的菜单,可通过标题栏中的按钮打开/关闭
  • 剩余空间(菜单右侧标题栏下方)由显示的任何内容填充(根据用户单击的菜单项,此div中会放置不同的页面/内容)

我想要的关键是,当内容需要更多的空间时,滚动条应该是用于滚动page-container内的东西,而不是整个页面(即标题栏和菜单应该显示在固定的位置).

此外,在页面内容中有一个details-panel div,我希望它总是可见的,它应该会导致它上面的内容(在本例中为page-content)缩小以适应这一点.

下面是一个代码片段,它显示了我已经到了哪里;注意,当视图小于内容时,滚动条滚动整个页面(包括标题栏和菜单项),以及视图中不保留的detail-panel.

Here is a codepen of the same.

document.getElementById('menu-toggle').addEventListener('click', function () {
 document.getElementById('menu').classList.toggle('closed');
        
document.getElementById('menu-toggle').classList.toggle('closed');
    });
html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    box-sizing: border-box;
    height: 100vh;
    width: 100vw;
    margin: 0;
    padding: 0;
}

h1 {
    font-size: 1.5em;
    margin: 0;
    padding: 0;
}

#parent-container {
    height: 100vh;
    max-height: 100vh;
    width: 100vw;
    max-width: 100vw;
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

#title-bar {
    background-color: blue;
    color: #fff;
    display: flex;
    align-items: center;
    flex-shrink: 0;
    flex-grow: 0;
}

#menu-toggle {
    cursor: pointer;
    font-size: 2em;
    user-select: none;
    flex-shrink: 0;
    padding: 10px;
    transform: rotate(45deg);
    transition: transform .3s ease-in;
}

#menu.closed {
    max-width: 0;
    transition: max-width 0.3s ease-out;
    overflow: hidden;
}

#menu-toggle.closed {
    transform: rotate(0);
    transition: transform .3s ease-in;
}

.top-container {
    display: flex;
    flex-grow: 1;
}

#menu {
    background-color: grey;
    max-width: 200px; /* just an arbitrary bigger-than-needed value to allow transition */
    transition: max-width 0.3s ease-in;
    flex-shrink: 0;
    flex-grow: 0;
    overflow: hidden;
}

#content {
    flex-shrink: 1;
    flex-grow: 1;
}

.page-container {
    display: flex;
    flex-direction: column;
    background-color: pink;
}

.page-content {
    overflow-y: auto;
    overflow-x: auto;
    flex-grow: 1;
    flex-shrink: 1;
}

.detail-panel {
    background: teal;
    flex-shrink: 0;
}
<div id="parent-container">

    <div id="title-bar">
        <h1 id="menu-toggle">+</h1>
        <h1>The Title</h1>
    </div>

    <div class="top-container">
        <div id="menu">
          <ul>
            <li>Menu Item 1</li>
            <li>Menu Item 2</li>
            <li>Menu Item 3</li>
            <li>Menu Item 4</li>
            <li>Menu Item 5</li>
          </ul>
        </div>

        <div id="content">
            <div class="page-container">
              The stuff in within page-container could change to anything based on whichever menu item the user selects, so everything "above" this must be fairly generic, and not dependent on the content within.
              </br></br>
      
              <div class="page-content">
                
                  This should show a scrollbar (horizontal and vertical) if required.
                
                </br></br>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mauris ultrices eros in cursus turpis massa tincidunt dui ut. Tellus elementum sagittis vitae et leo duis. Laoreet sit amet cursus sit. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Enim eu turpis egestas pretium. Tristique senectus et netus et malesuada fames ac. Proin fermentum leo vel orci porta non pulvinar neque. Faucibus vitae aliquet nec ullamcorper sit. Non consectetur a erat nam at lectus urna duis.

Vestibulum morbi blandit cursus risus at. Aenean et tortor at risus viverra adipiscing at in tellus. Tellus molestie nunc non blandit massa. Urna id volutpat lacus laoreet non curabitur. Sem viverra aliquet eget sit amet tellus cras. Sapien faucibus et molestie ac feugiat sed lectus. Vel quam elementum pulvinar etiam non quam lacus suspendisse faucibus. Nibh ipsum consequat nisl vel pretium. Vulputate dignissim suspendisse in est. Bibendum at varius vel pharetra vel turpis nunc eget. A scelerisque purus semper eget duis at tellus at. Venenatis tellus in metus vulputate eu scelerisque felis. Lectus vestibulum mattis ullamcorper velit. Ipsum consequat nisl vel pretium lectus quam id leo. Tempor nec feugiat nisl pretium. Maecenas sed enim ut sem viverra aliquet.

Ornare arcu odio ut sem. Cras adipiscing enim eu turpis egestas pretium aenean pharetra magna. Facilisis gravida neque convallis a cras. Enim diam vulputate ut pharetra sit amet. Hac habitasse platea dictumst vestibulum rhoncus est. Sit amet nisl suscipit adipiscing bibendum est ultricies. Risus in hendrerit gravida rutrum. Laoreet suspendisse interdum consectetur libero id faucibus nisl. Quam pellentesque nec nam aliquam sem et. Gravida quis blandit turpis cursus.

Et malesuada fames ac turpis egestas. Viverra nibh cras pulvinar mattis nunc. Nulla pellentesque dignissim enim sit amet venenatis urna cursus eget. Viverra vitae congue eu consequat ac. Nibh praesent tristique magna sit amet purus gravida quis blandit. Enim eu turpis egestas pretium aenean pharetra magna ac. Aliquet nec ullamcorper sit amet risus nullam. Amet consectetur adipiscing elit ut aliquam purus sit amet luctus. Metus dictum at tempor commodo ullamcorper. Magna ac placerat vestibulum lectus mauris. Arcu vitae elementum curabitur vitae nunc sed velit. At augue eget arcu dictum varius duis at consectetur lorem. Velit egestas dui id ornare arcu odio ut. Platea dictumst quisque sagittis purus sit amet. Vel fringilla est ullamcorper eget nulla facilisi etiam. Volutpat maecenas volutpat blandit aliquam etiam. Semper viverra nam libero justo.

Eu consequat ac felis donec. Faucibus vitae aliquet nec ullamcorper. Faucibus turpis in eu mi bibendum neque egestas congue. Nibh nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam. Tortor at auctor urna nunc id cursus metus aliquam. Turpis cursus in hac habitasse platea dictumst quisque sagittis purus. Lacus vel facilisis volutpat est velit egestas dui id. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Cras adipiscing enim eu turpis. Scelerisque varius morbi enim nunc. Pulvinar proin gravida hendrerit lectus. Laoreet sit amet cursus sit amet dictum sit amet justo. Lacinia quis vel eros donec ac odio tempor. Feugiat in ante metus dictum at tempor commodo. Purus in mollis nunc sed id.
              </div>

              <div class="detail-panel">
                  This should always be displayed at the bottom of the view.
              </div>
          </div>
        </div>
    </div>
</div>

推荐答案

有很多方法可以做到这一点,但在本例中,我 Select 使用grid来创建布局.div.detail-panel将根据需要进行扩展,而每当内容溢出时,div.page-content将始终成为滚动容器.

我注意到你有一个动画菜单,所以我在div.container上添加了动画效果

const toggle = document.getElementById('menuToggle');

toggle.addEventListener('click', () => {
  document.querySelector('.container').classList.toggle('show-menu');
})

const menuItems = document.querySelectorAll('.menu li');
const pageContent = document.querySelector('.page-content');
menuItems.forEach((li) => {
  li.addEventListener('click', () => {
    pageContent.textContent = data[li.dataset.id];
  })
})

const data = {
  1: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mauris ultrices eros in cursus turpis massa tincidunt dui ut. Tellus elementum sagittis vitae et leo duis. Laoreet sit amet cursus sit. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Enim eu turpis egestas pretium. Tristique senectus et netus et malesuada fames ac. Proin fermentum leo vel orci porta non pulvinar neque. Faucibus vitae aliquet nec ullamcorper sit. Non consectetur a erat nam at lectus urna duis.

        Vestibulum morbi blandit cursus risus at. Aenean et tortor at risus viverra adipiscing at in tellus. Tellus molestie nunc non blandit massa. Urna id volutpat lacus laoreet non curabitur. Sem viverra aliquet eget sit amet tellus cras. Sapien faucibus et molestie ac feugiat sed lectus. Vel quam elementum pulvinar etiam non quam lacus suspendisse faucibus. Nibh ipsum consequat nisl vel pretium. Vulputate dignissim suspendisse in est. Bibendum at varius vel pharetra vel turpis nunc eget. A scelerisque purus semper eget duis at tellus at. Venenatis tellus in metus vulputate eu scelerisque felis. Lectus vestibulum mattis ullamcorper velit. Ipsum consequat nisl vel pretium lectus quam id leo. Tempor nec feugiat nisl pretium. Maecenas sed enim ut sem viverra aliquet.

        Ornare arcu odio ut sem. Cras adipiscing enim eu turpis egestas pretium aenean pharetra magna. Facilisis gravida neque convallis a cras. Enim diam vulputate ut pharetra sit amet. Hac habitasse platea dictumst vestibulum rhoncus est. Sit amet nisl suscipit adipiscing bibendum est ultricies. Risus in hendrerit gravida rutrum. Laoreet suspendisse interdum consectetur libero id faucibus nisl. Quam pellentesque nec nam aliquam sem et. Gravida quis blandit turpis cursus.

        Et malesuada fames ac turpis egestas. Viverra nibh cras pulvinar mattis nunc. Nulla pellentesque dignissim enim sit amet venenatis urna cursus eget. Viverra vitae congue eu consequat ac. Nibh praesent tristique magna sit amet purus gravida quis blandit. Enim eu turpis egestas pretium aenean pharetra magna ac. Aliquet nec ullamcorper sit amet risus nullam. Amet consectetur adipiscing elit ut aliquam purus sit amet luctus. Metus dictum at tempor commodo ullamcorper. Magna ac placerat vestibulum lectus mauris. Arcu vitae elementum curabitur vitae nunc sed velit. At augue eget arcu dictum varius duis at consectetur lorem. Velit egestas dui id ornare arcu odio ut. Platea dictumst quisque sagittis purus sit amet. Vel fringilla est ullamcorper eget nulla facilisi etiam. Volutpat maecenas volutpat blandit aliquam etiam. Semper viverra nam libero justo.

        Eu consequat ac felis donec. Faucibus vitae aliquet nec ullamcorper. Faucibus turpis in eu mi bibendum neque egestas congue. Nibh nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam. Tortor at auctor urna nunc id cursus metus aliquam. Turpis cursus in hac habitasse platea dictumst quisque sagittis purus. Lacus vel facilisis volutpat est velit egestas dui id. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Cras adipiscing enim eu turpis. Scelerisque varius morbi enim nunc. Pulvinar proin gravida hendrerit lectus. Laoreet sit amet cursus sit amet dictum sit amet justo. Lacinia quis vel eros donec ac odio tempor. Feugiat in ante metus dictum at tempor commodo. Purus in mollis nunc sed id.`,
  2: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mauris ultrices eros in cursus turpis massa tincidunt dui ut. Tellus elementum sagittis vitae et leo duis. Laoreet sit amet cursus sit. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Enim eu turpis egestas pretium. Tristique senectus et netus et malesuada fames ac. Proin fermentum leo vel orci porta non pulvinar neque. Faucibus vitae aliquet nec ullamcorper sit. Non consectetur a erat nam at lectus urna duis.',
  3: 'Vestibulum morbi blandit cursus risus at. Aenean et tortor at risus viverra adipiscing at in tellus. Tellus molestie nunc non blandit massa. Urna id volutpat lacus laoreet non curabitur. Sem viverra aliquet eget sit amet tellus cras. Sapien faucibus et molestie ac feugiat sed lectus. Vel quam elementum pulvinar etiam non quam lacus suspendisse faucibus. Nibh ipsum consequat nisl vel pretium. Vulputate dignissim suspendisse in est. Bibendum at varius vel pharetra vel turpis nunc eget. A scelerisque purus semper eget duis at tellus at. Venenatis tellus in metus vulputate eu scelerisque felis. Lectus vestibulum mattis ullamcorper velit. Ipsum consequat nisl vel pretium lectus quam id leo. Tempor nec feugiat nisl pretium. Maecenas sed enim ut sem viverra aliquet',
  4: 'Ornare arcu odio ut sem. Cras adipiscing enim eu turpis egestas pretium aenean pharetra magna. Facilisis gravida neque convallis a cras. Enim diam vulputate ut pharetra sit amet. Hac habitasse platea dictumst vestibulum rhoncus est. Sit amet nisl suscipit adipiscing bibendum est ultricies. Risus in hendrerit gravida rutrum. Laoreet suspendisse interdum consectetur libero id faucibus nisl. Quam pellentesque nec nam aliquam sem et. Gravida quis blandit turpis cursus.',
  5: 'Et malesuada fames ac turpis egestas. Viverra nibh cras pulvinar mattis nunc. Nulla pellentesque dignissim enim sit amet venenatis urna cursus eget. Viverra vitae congue eu consequat ac. Nibh praesent tristique magna sit amet purus gravida quis blandit. Enim eu turpis egestas pretium aenean pharetra magna ac. Aliquet nec ullamcorper sit amet risus nullam. Amet consectetur adipiscing elit ut aliquam purus sit amet luctus. Metus dictum at tempor commodo ullamcorper. Magna ac placerat vestibulum lectus mauris. Arcu vitae elementum curabitur vitae nunc sed velit. At augue eget arcu dictum varius duis at consectetur lorem. Velit egestas dui id ornare arcu odio ut. Platea dictumst quisque sagittis purus sit amet. Vel fringilla est ullamcorper eget nulla facilisi etiam. Volutpat maecenas volutpat blandit aliquam etiam. Semper viverra nam libero justo.',
  6: 'Eu consequat ac felis donec. Faucibus vitae aliquet nec ullamcorper. Faucibus turpis in eu mi bibendum neque egestas congue. Nibh nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam. Tortor at auctor urna nunc id cursus metus aliquam. Turpis cursus in hac habitasse platea dictumst quisque sagittis purus. Lacus vel facilisis volutpat est velit egestas dui id. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Cras adipiscing enim eu turpis. Scelerisque varius morbi enim nunc. Pulvinar proin gravida hendrerit lectus. Laoreet sit amet cursus sit amet dictum sit amet justo. Lacinia quis vel eros donec ac odio tempor. Feugiat in ante metus dictum at tempor commodo. Purus in mollis nunc sed id.'
}
.container {
  display: grid;
  grid-template-areas: "title title" "menu content" "menu content" "menu detail";
  transition: 300ms;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 130px 1fr;
  height: 100%;
  &.show-menu {
    grid-template-columns: 0 1fr;
  }
}

.page-content {
  grid-area: content;
  background: green;
  overflow: auto;
}

.detail-panel {
  grid-area: detail;
  background: turquoise;
}

.menu {
  grid-area: menu;
  background: grey;
}

.title-bar {
  grid-area: title;
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  gap: 5px;
  color: white;
  padding: 3px 5px;
  background: blue;
}

html,
body {
  height: 100%;
}


/* CSS RESET */


/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}


/* HTML5 display-role reset for older browsers */

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
  display: block;
}

body {
  line-height: 1;
}

ol,
ul {
  list-style: none;
}

blockquote,
q {
  quotes: none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content: '';
  content: none;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}
<div class="container">

  <div class="title-bar">
    <button id="menuToggle">
            X
        </button>
    <h1>
      The Title
    </h1>
  </div>
  <div class="menu">
    <ul>
      <li data-id="1">Menu Item 1</li>
      <li data-id="2">Menu Item 2</li>
      <li data-id="3">Menu Item 3</li>
      <li data-id="4">Menu Item 4</li>
      <li data-id="5">Menu Item 5</li>
    </ul>
  </div>
  <div class="page-content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mauris ultrices eros in cursus turpis massa tincidunt dui ut. Tellus elementum sagittis vitae et leo duis. Laoreet sit amet cursus
    sit. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Enim eu turpis egestas pretium. Tristique senectus et netus et malesuada fames ac. Proin fermentum leo vel orci porta non pulvinar neque. Faucibus vitae aliquet nec ullamcorper
    sit. Non consectetur a erat nam at lectus urna duis. Vestibulum morbi blandit cursus risus at. Aenean et tortor at risus viverra adipiscing at in tellus. Tellus molestie nunc non blandit massa. Urna id volutpat lacus laoreet non curabitur. Sem viverra
    aliquet eget sit amet tellus cras. Sapien faucibus et molestie ac feugiat sed lectus. Vel quam elementum pulvinar etiam non quam lacus suspendisse faucibus. Nibh ipsum consequat nisl vel pretium. Vulputate dignissim suspendisse in est. Bibendum at
    varius vel pharetra vel turpis nunc eget. A scelerisque purus semper eget duis at tellus at. Venenatis tellus in metus vulputate eu scelerisque felis. Lectus vestibulum mattis ullamcorper velit. Ipsum consequat nisl vel pretium lectus quam id leo.
    Tempor nec feugiat nisl pretium. Maecenas sed enim ut sem viverra aliquet. Ornare arcu odio ut sem. Cras adipiscing enim eu turpis egestas pretium aenean pharetra magna. Facilisis gravida neque convallis a cras. Enim diam vulputate ut pharetra sit
    amet. Hac habitasse platea dictumst vestibulum rhoncus est. Sit amet nisl suscipit adipiscing bibendum est ultricies. Risus in hendrerit gravida rutrum. Laoreet suspendisse interdum consectetur libero id faucibus nisl. Quam pellentesque nec nam aliquam
    sem et. Gravida quis blandit turpis cursus. Et malesuada fames ac turpis egestas. Viverra nibh cras pulvinar mattis nunc. Nulla pellentesque dignissim enim sit amet venenatis urna cursus eget. Viverra vitae congue eu consequat ac. Nibh praesent tristique
    magna sit amet purus gravida quis blandit. Enim eu turpis egestas pretium aenean pharetra magna ac. Aliquet nec ullamcorper sit amet risus nullam. Amet consectetur adipiscing elit ut aliquam purus sit amet luctus. Metus dictum at tempor commodo ullamcorper.
    Magna ac placerat vestibulum lectus mauris. Arcu vitae elementum curabitur vitae nunc sed velit. At augue eget arcu dictum varius duis at consectetur lorem. Velit egestas dui id ornare arcu odio ut. Platea dictumst quisque sagittis purus sit amet.
    Vel fringilla est ullamcorper eget nulla facilisi etiam. Volutpat maecenas volutpat blandit aliquam etiam. Semper viverra nam libero justo. Eu consequat ac felis donec. Faucibus vitae aliquet nec ullamcorper. Faucibus turpis in eu mi bibendum neque
    egestas congue. Nibh nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam. Tortor at auctor urna nunc id cursus metus aliquam. Turpis cursus in hac habitasse
    platea dictumst quisque sagittis purus. Lacus vel facilisis volutpat est velit egestas dui id. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Cras adipiscing enim eu turpis. Scelerisque varius morbi enim nunc. Pulvinar proin gravida
    hendrerit lectus. Laoreet sit amet cursus sit amet dictum sit amet justo. Lacinia quis vel eros donec ac odio tempor. Feugiat in ante metus dictum at tempor commodo. Purus in mollis nunc sed id.
  </div>

  <div class="detail-panel">
    detail
  </div>
</div>

Javascript相关问答推荐

如何访问react路由v6加载器函数中的查询参数/搜索参数

是什么原因导致此Angular 16应用程序中类型错误时属性结果不存在?

格式值未保存在redux持久切片中

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

当点击注册页面上的注册按钮时,邮箱重复

从Node JS将对象数组中的数据插入Postgres表

如何使用子字符串在数组中搜索重复项

类构造函数不能在没有用With Router包装的情况下调用

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

搜索功能不是在分页的每一页上进行搜索

是否可以在Photoshop CC中zoom 路径项?

如何在Press上重新启动EXPO-AV视频?

AddEventListner,按键事件不工作

JS Animate()方法未按预期工作

有没有一种直接的方法可以深度嵌套在一个JavaScript对象中?

匹配一个或多个可选重复的特定模式

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

Clip-Path在网页浏览器(Mozilla、Edge、Chrome)上不能正常工作,但在预览版Visual Code Studio HTML、CSS、JS上却能很好地工作

如何在Reaction中清除输入字段

我如何才能让p5.js在不使用实例模式的情况下工作?