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:我真的更喜欢使用 <img>
,而不是使用带有背景图像 hack 的 <div>
。
【问题讨论】:
【参考方案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:使用深度嵌套的图像来摊销不断变化的布局尺寸的主要内容,如果未能解决你的问题,请参考以下文章
在 CSS FlexBox 布局中自动调整图像大小并保持纵横比?