【问题标题】:Make flex container restricted by window height使弹性容器受窗口高度限制
【发布时间】:2018-12-11 21:26:03
【问题描述】:

我正在尝试制作一个占据整个窗口并使用其自己的内部滚动机制的网络应用程序。我不希望任何内容出现在浏览器窗口之外。

现在我正在尝试使用包含 flex 容器的布局,设置为 flex 列,具有固定的标题导航栏,然后是显示动态数据的内容区域,该区域将具有滚动条来查看内容溢出。这样第二个标题将始终在页面上。我正在使用 Angular 来执行此操作,并且因为被路由的组件在标题和内容 divs 之前向 DOM 添加了另一个级别,因此 flex 容器不会限制它们的高度。

.page {
  display: flex;
  flex-flow: column;
  height: 100%;
  max-height: 100vh;
}

.header {
  flex: 1 1 50px;
  border: 3px solid red;
}

.container {
  display: flex;
  flex: 1 1 auto;
  flex-flow: column;
  padding: 20px;
}

.dynamic-content {
  flex: 1 1 auto;
  border: 3px solid blue;
  overflow-y: scroll;
  display: flex;
  flex-flow: column;
}

.item {
  font-size: 40px;
}
<div class='page'>

  <div class="header">
    Head
  </div>
  
  <div class="container">
    
    <app-component _nghost class="ng-star-inserted">
      <div class="header">SubHeader</div>
    
      <div class='dynamic-content'>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>      
      </div>
    </app-component>
  
    
    
  </div>

我希望div.container 仅占据页面的剩余高度,并且div.dynamic-content 在添加项目超出其底部边界时不调整大小,而是切断任何溢出并显示滚动条以到达其余的内容。这样,当用户向下滚动页面时,SubHeader div 和主 Head div 将始终显示在屏幕上。

angular-router-endpointangular-routed-component divs 正如它们的类所描述的那样,是一个 Angular Router-Outlet 和一个由 Outlet 插入的自定义 Angular 组件。据我所知,该组件不能直接设置样式。

【问题讨论】:

  • 如果你想通过视口高度来限制它,只需使用max-height: 100vh
  • @Terry 确实适用于这个例子,我相信我过于简单化了。我使用的是 Angular,DOM 略有不同。我将编辑问题。

标签: html angular css flexbox


【解决方案1】:

我试图了解预期的结果。

在您的代码中,您使用了 flexbox,但忘记了包装器 .angular-routed-component,并且您从这里失去了 flex 模型的好处。

我已删除并更新了一些值。 (没有max-height 但只有heightflex 减少到一个足以使其填充剩余空间的值。(flex:1;),还添加了一些overflow:hidden,以触发稍后滚动)

.page {
  display: flex;
  flex-flow: column;
  height: 100vh;/* update */
  overflow:hidden;/* update */
}

body {/* update */
  margin: 0;
}

.header {
  min-height: 50px;/* update, no flex rules */
  border: 3px solid red;
}

.container, .angular-routed-component {/* here same rules for the angular child compoment */
  display: flex;
  flex: 1;/* update */
  flex-flow: column;
  padding: 20px;
  overflow:hidden;/* update */
}

.dynamic-content {
  flex: 1;/* update */
  border: 3px solid blue;
  overflow-y: scroll;
  display: flex;
  flex-flow: column;
}

.item {
  font-size: 40px;
}
<div class='page'>

  <div class="header">
    Head
  </div>

  <div class="container">

    <div class="angular-router-endpoint"></div>
    <div class="angular-routed-component">
      <div class="header">SubHeader</div>

      <div class='dynamic-content'>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
        <div class="item">item</div>
      </div>
    </div>



  </div>

【讨论】:

  • 问题在于.angular-routed-component 是一个有角度的插入组件,您不能将样式直接应用于该 dom 元素。
  • @MasonTurvey 你确定吗?一旦它在文档的 dom 中,只要类名匹配,样式中的 css 就会应用到它,否则,您要么有错误的类名,要么 angular 会覆盖样式。如果它确实覆盖了规则,我想到了 2 个选项:a)增加选择器的权重 b)或者一旦加载了 angular 脚本,通过 javascript 更新该元素的样式。我会避免使用!important 以保持清洁。如果该元素确实有一个,最好使用id。如果没有,请即时添加并让 CSS 在样式表中。
  • 增加权重也可以,但我发现将样式直接应用于组件的最直接方法是使用 angulars :host selector
  • @MasonTurvey 无论您使用什么方法,问题都是将此组件包含到您的 flexbox 布局中,如果您希望级联工作,您别无选择 ;)
【解决方案2】:

我已经解决了我的问题,发现这不是 CSS 问题,而是我误解了 Angular 路由器构建 DOM 的方式。

插入的组件标签必须设置display: flex。直接向组件标签添加样式的方法是使用 CSS 选择器::host,在我的情况下,我必须使用 :host { display: flex } 才能使其正常工作。

我最初的问题是我的 CSS 问题,并对其进行了编辑以匹配我的具体问题

【讨论】:

  • 这是一个 CSS 问题,级联样式表,其中级联在组件显示为无样式的级别被破坏:)。您必须对其进行样式设置并将其包含到您的 flexbox 布局中 ....
【解决方案3】:

我不确定我是否正确理解了您,但我相信我已经理解了,您可以在下面看到解决问题的方法。

关键部分

这里的关键是将height: 100vh 添加到.page,这样它就不会超过视点的高度。

.page {
  display: flex;
  flex-flow: column;
  height: 100vh;
}

片段

body {
  margin: 0;
}

.page {
  display: flex;
  flex-flow: column;
  height: 100vh;
}

.header {
  flex: 1 1 50px;
  border: 3px solid red;
}

.container {
  display: flex;
  flex: 1 1 auto;
  flex-flow: column;
  padding: 20px;
  box-sizing: border-box;
}

.dynamic-content {
  flex: 1 1 auto;
  border: 3px solid blue;
  overflow-y: scroll;
  display: flex;
  flex-flow: column;
}

.item {
  font-size: 40px;
}
<div class='page'>

  <div class="header">
    Head
  </div>

  <div class="container">

    <div class="header">SubHeader</div>

    <div class='dynamic-content'>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
      <div class="item">item</div>
    </div>

  </div>

</div>

【讨论】:

  • 我已经编辑了我的问题。您的回答确实适用于我提供的示例,但不适用于我的实际应用程序。该应用程序使用 Angular 和路由组件,我认为问题实际上在于 Angular 在路由器端点插入 DOM 对象的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 2012-04-01
  • 1970-01-01
相关资源
最近更新 更多