CSS flexbox:使用深度嵌套的图像来摊销不断变化的布局尺寸

Posted

技术标签:

【中文标题】CSS flexbox:使用深度嵌套的图像来摊销不断变化的布局尺寸【英文标题】:CSS flexbox: use deeply nested images to amortize changing layout dimensions 【发布时间】:2021-10-11 11:28:16 【问题描述】:

我无法理解 FlexBox。

这就是我想要的:

一个组件垂直分成3个部分:

主视图 状态栏 日志窗口(通过状态栏中的按钮切换)

日志的窗口 max-height: 80px(以后可能会根据屏幕大小更改为 25%/100%,所以不要坚持固定的 80px 值)

状态栏和组件div底部的日志窗口和可见在所有时间(不垂直溢出)

主视图可能不包含一个或多个带有图片的项目(不知道会有多少项目)

主视图项尽可能多地占用空间(拉伸图像;保留比例):垂直和水平

主视图项目必须在它们到达水平(其他项目或组件 div 的侧面)或垂直(状态栏和/或组件 div 的顶部)时立即停止拉伸限制

主视图项不得缩小到超过某个固定大小 (300x150px) - 如果他们试图让它们溢出。

这大概是横向的样子(轮廓只是为了清楚起见)-来自 JSFiddle 的屏幕截图

我已经制作了基本布局,但响应速度快要死了。我什至不确定是什么阻碍了我:是图像吗?嵌套很深吗?是我误用了 flexbox 吗?

简单地说,我希望图像能够摊销组件/屏幕尺寸的变化:组件 div 扩展时拉伸,组件 div 缩小时收缩。所有这些都在一定范围内:最小 300x150 像素; max - 周围 div 允许的任何值。

谁能帮我修复布局?

/* 
https://flexbox.malven.co/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
 */

body 
  height: 100vh;


.border 
  outline: solid black thin;
  /* border-style: solid;
  border-color: black;
  border-radius: 5px; */


.m5 
  margin-left: 5px;
  margin-right: 5px;
  /* margin-top: 5px;
  margin-bottom: 5px; */


.component 
  height: 100%;


.container 
  display: flex;
  flex-flow: column nowrap;
  width: 100%;
  height: 100%;


.content 
  box-sizing: border-box;
  flex: 1 1 auto;
  height: 100%;


.module1 
  height: 100%;


.module1-main 
  box-sizing: border-box;
  display: flex;
  flex-flow: row wrap;
  align-content: center;
  justify-content: center;
  align-items: center;
  height: 100%;


.module1-item 
  box-sizing: border-box;
  flex: 1 1 auto;
  display: flex;
  flex-flow: column nowrap;
  align-content: center;
  justify-content: center;
  align-items: stretch;
  max-height: 100%;


.viewport 
  box-sizing: border-box;
  flex: 1 1 auto;
  display: flex;
  align-items: stretch;
  flex-direction: column;


.viewport-thumbnail 
  box-sizing: border-box;
  object-fit: contain;
  max-width: 100%;
  max-height: 100%;
  min-width: 300px;
  min-height: 150px;


.menu 
  box-sizing: border-box;
  flex: 1 1 auto;
  display: flex;
  flex-flow: row nowrap;
  align-items: stretch;


.log-panel 
  box-sizing: border-box;
  flex: 1 1 auto;
  height: 80px;
  overflow-y: auto;


.full-w 
  width: 100%;


.item2 
  /* display: none; */
<html class="border">

<body>
  <div class="component">


    <div class="container border">
      <div class="content">
        <div class="generated module1">
          <div class="module1-main border m5">

            <div class="module1-item border m5 item1">
              <div class="viewport border">
                <img src="https://www2.lunapic.com/editor/premade/transparent.gif" class="viewport-thumbnail">
              </div>
              <div class="menu border">
                <button>crop</button>
                <button>resize</button>
                <span class="full-w">Image_0001.jpg</span>
                <button>share</button>
              </div>
            </div>

            <div class="module1-item border m5 item2">
              <div class="viewport border">
                <img src="https://www2.lunapic.com/editor/premade/transparent.gif" class="viewport-thumbnail">
              </div>
              <div class="menu border">
                <button>crop</button>
                <button>resize</button>
                <span class="full-w">Image_0002.jpg</span>
                <button>share</button>
              </div>
            </div>

          </div>
        </div>
      </div>
      <div class="status-bar border m5">
        <button>show logs</button>
        <span>Found files: 2</span>
      </div>
      <div class="log-panel border m5">
        <ul>
          <li>Collecting parameters</li>
          <li>In progress...</li>
          <li>Rendering</li>
        </ul>
      </div>
    </div>
  </div>
</body>

</html>

这是小提琴:https://jsfiddle.net/netikras/uzsr1p4f/79/

旁注1:HTML 将使用 angular 生成。

旁注 2:我真的更喜欢使用 &lt;img&gt;,而不是使用带有背景图像 hack 的 &lt;div&gt;

【问题讨论】:

【参考方案1】:

我的尝试:

HTML

<div class="main-view">
  <div class="modules">
    <div class="module1-item border m5 item1">
      <div class="viewport border">
        <img src="https://www2.lunapic.com/editor/premade/transparent.gif" class="viewport-thumbnail">
      </div>
      <div class="menu border">
        <button>crop</button>
        <button>resize</button>
        <span class="full-w">Image_0001.jpg</span>
        <button>share</button>
      </div>
    </div>
    <div class="module1-item border m5 item2">
      <div class="viewport border">
        <img src="https://www2.lunapic.com/editor/premade/transparent.gif" class="viewport-thumbnail">
      </div>
      <div class="menu border">
        <button>crop</button>
        <button>resize</button>
        <span class="full-w">Image_0002.jpg</span>
        <button>share</button>
      </div>
    </div>
  </div>
<div class="bottom-windows">
    <div class="status-bar border m5">
    <button>show logs</button>
    <span>Found files: 2</span>
  </div>

  <div class="logs-window">
    <ul>
      <li>Collecting parameters</li>
      <li>In progress...</li>
      <li>Rendering</li>
    </ul>
  </div>
  </div>
</div>

CSS

html,
body 
  height: 100%;
  margin: 0;


.main-view 
  height: 100%;
  display: flex;
  flex-direction: column;


.modules 
  height: 100%;
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;


.module1-item 
  width: 100%;
  display: flex;
  flex-direction: column;


.viewport 
  display: flex;
  justify-content: center;


.viewport-thumbnail 
  width: 100%;
  height: auto;


.bottom-windows 
  max-height: 25%;
  display: flex;
  flex-direction: column;


/* Do this 300px and down */
@media only screen and (max-width: 300px) 
  .modules 
    flex-wrap: wrap;
    overflow-y: auto;
  

  .bottom-windows 
    width: 100%;
    align-self: flex-end;
  

Codepen: Click here

【讨论】:

这与我所追求的非常接近。它能在利用所有可见空间后立即停止拉伸吗?即按钮不应隐藏在状态栏后面。拉伸应在到达边界后立即停止 - 状态栏。【参考方案2】:

感谢@dom_ahdigital,我想我终于成功了!对规范的轻微修改:该项目始终最大化。只有图片在改变它的尺寸。

我的错误是没有完全理解 flex-grow 和 flex-basis。

这是我的解决方案。适用于我尝试过的任何调整大小。

/* 
https://flexbox.malven.co/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
 */

html,
body 
  height: 100%;
  margin: 0;


.bottom-windows 
  max-height: 25%;
  flex: 1 1 0;
  display: flex;
  flex-flow: column nowrap;


.container 
  display: flex;
  flex-flow: column nowrap;
  width: 100%;
  height: 100%;


.content 
  flex: 4 1 0;


.module1 
  height: 100%;


.module1-main 
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  align-items: stretch;
  height: 100%;
  overflow-y: auto;


.module1-item 
  flex: 1 1 0;
  display: flex;
  flex-flow: column nowrap;
  align-content: flex-start;
  justify-content: center;
  align-items: stretch;
  height: 100%;


.viewport 
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  flex-direction: column;


.viewport-thumbnail 
  flex: 1 1 0;
  object-fit: contain;
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;


.menu 
  flex: 1 1 0;
  display: flex;
  flex-flow: row nowrap;
  align-items: stretch;


.log-panel 
  flex: 1 1 100%;
  display: flex;
  flex-flow: column-reverse nowrap;
  /* height: 80px; */
  overflow-y: auto;


.full-w 
  width: 100%;


.item2 
  /* display: none; */


.m5 
  margin-left: 5px;
  margin-right: 5px;
  /* margin-top: 5px;
  margin-bottom: 5px; */


.border 
  outline: black solid thin;
  /*     border-style: solid;
      border-color: black;
      border-radius: 5px; */
<div class="container">
  <div class="content">
    <div class="generated module1">
      <div class="module1-main">

        <div class="module1-item m5 item1 border">
          <div class="viewport">
            <img src="https://www2.lunapic.com/editor/premade/transparent.gif" class="viewport-thumbnail">
          </div>
          <div class="menu border">
            <button>crop</button>
            <button>resize</button>
            <span class="full-w">Image_0001.jpg</span>
            <button>share</button>
          </div>
        </div>

        <div class="module1-item m5 item2 border">
          <div class="viewport">
            <img src="https://media.istockphoto.com/vectors/cute-penguin-icon-in-flat-style-vector-id868646936" class="viewport-thumbnail">
          </div>
          <div class="menu border">
            <button>crop</button>
            <button>resize</button>
            <span class="full-w">Image_0002.jpg</span>
            <button>share</button>
          </div>
        </div>

      </div>
    </div>
  </div>
  <div class="bottom-windows border">
    <div class="status-bar">
      <button>show logs</button>
    </div>
    <div class="log-panel border">
      <ul>
        <li>Collecting parameters</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Downloading</li>
        <li>Extracting</li>
        <li>In progress...</li>
        <li>Rendering</li>
        <li>Done</li>
      </ul>
    </div>
  </div>
</div>

JSFiddle:https://jsfiddle.net/netikras/uzsr1p4f/142/

这是现在的样子

正常

非常窄且可滚动

【讨论】:

以上是关于CSS flexbox:使用深度嵌套的图像来摊销不断变化的布局尺寸的主要内容,如果未能解决你的问题,请参考以下文章

深度嵌套的 flexbox 布局会导致性能问题吗?

Flexbox不包含整个图像(CSS)

在 CSS FlexBox 布局中自动调整图像大小并保持纵横比?

CSS:Firefox/Internet Explorer 中 flexbox 的图像缩放问题

Flexbox 高度和背景图像高度

Flexbox 图像在浏览器中的大小调整不同