用户体验思考与flex三坑:元素不均分、溢出不省略和垂直不滚动

article/2025/7/21 13:08:07

flex已经越来越成为前端不可避免的话题。曾经为了搞清flex的原理偶然画了一张图。但后来发现只是冰山一角。
flex-盗自己文章的图-flex到底是谁orflex到底像谁
在某些你想实现的交互效果中使用flex后可能会发现并不起作用。通过我的实践,大致有三个问题:子元素不平分父元素空间、对文字设置了溢出省略却失效、flex下列表溢出但是滚动失效。常常会让人摸不着头脑。这里记录探究。

元素不均分

“均分列”,也就是子元素等宽应该是项目中最常见的效果。我常常在项目中见到这样的代码:

flex: 1;

似乎有很多人认为在 Flex 布局中这样显式设置即可“一劳永逸”。
但事实是什么?事实是我们都知道flex: 1是下面这三个属性的简写:

flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;

如果未显式设置flex时,其初始值是:

flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;

flex-basis 为 auto 时,Flex布局元素的宽度是max-content。也就是说,flex:1时,flex-basis变成了0%,这将覆盖Flex布局的内在尺寸max-content。但Flex布局的基本尺寸变为 0 以后,由于 flex-grow的存在,它们都可以增长以填补父元素的剩余空间。
而实际上,在这种情况下,flex-shrink不再做任何事情,因为所有的Flex布局现在的宽度都是0,并且正在自动填补可用空间。只不过,这时候Flexbox容器却并不一定有剩余空间了,甚至有可能空间不足。这时候flex:1也就不能均分Flexbox容器了。
这是有情况可循的:
微店卖家版-app-满减赠部分截图

可以看到,在空间拥挤的情况下,后面的元素明显要比前面的元素宽。而且越来越宽。就好像前面的元素因为不知道要“压缩”多少所以按照内容压缩到能压缩的最小宽度,但是到后面元素时发现空间够了不用收缩了一样。
其实这就是触发了flex的边缘情况。说到这里我们要简单说一下max-content:容器占据的它所能占据宽度的全部就是max-content的尺寸。也有人叫“假设宽度”(因为你可能并不知道到底是多宽)。比如:
模拟满减赠项目-css研究test

有意思的是,相对应的min-content是在内部做了一次比较:采用内部元素最小宽度值最大的那个元素的宽度作为最终容器的宽度。

回到正题,上面其实就是触发了flex的边缘情况。在W3C中有一段描述翻译过来是这样的:“默认情况下,弹性Flex(设置为flex:1的Flex元素)在收缩的时候,其宽度不会小于其最小内容尺寸(即 min-width,也就是max-content或固定尺寸元素的长度)。要改变这一点,需要显式设置min-widthmin-height的值”。
括号里的话非常重要!它会涉及min-width的值。默认情况下,min-width的值为 auto,它会被计算为 0。当一个元素采用了Flex布局时,min-width的值又不会被计算为 0,它的值为max-content。这时就会触发边缘计算。

为此,要真正达到均分列,只显式设置flex:1还不行,还需要在Flex项目上显式设置min-width的值为0:

flex: 1;
min-width: 0;

溢出不省略

你应该遇到过这样的问题吧?就像我之前在项目中遇到的:
微店-加价换购部分截图
在笔者的这篇文章中,我曾经给出了一个比较复杂的解读。但是后来看到了W3C中的这段话:“主轴上Flex元素的overflow属性是visible时,主轴上Flex元素的最小尺寸(min-size)将会指定一个自动的最小尺寸”。
结合上面那段W3C的语录,很容易想到问题出在了min-width属性上!
所以解决方法就是在需要换行/省略的元素上,将min-width显式地设为0。一般这样操作:

flex: 1 1 0%;
min-width: 0;

滚动失效

之前在我司加价换购的项目中,我惊讶的发现,列表中明明有超过显示区域的元素数量,但是上下并不滚动。一开始是以为动态高度导致了没有识别到元素。但是发现此时父元素上已经有了overflow-y: scroll; 这说明不是这里的问题。最终在我无意间注掉了display: flex;发现可以了…

这个bug我问了我司的其他同事并没有遇到过,说明和使用的结构有关:
因为是一个大弹层,所以我在最外层设置了flex,然后在主体区域使用了flex: 1让其能够自适应。在主体内还有一层,是滚动元素的父元素,接着才是真正的滚动内容。
HTML结构大概是这样的:

<div class="main-container"><!-- main-container是flex布局,里面上下两层 --><div class="fixed-container">头部</div><!-- 下面是主体区域,content-wrapper是最外层的 --><div class="content-wrapper"><!-- 下面的overflow-container是滚动容器,里面的over-content才是滚动项 --><div class="overflow-container"><div class="overflow-content"> 滚动项,不止一条 </div></div></div>
</div>

这同样是触发了flex边缘计算导致的。这个问题的解决方案就是给滚动容器的父元素,也就是设置了flex: 1的元素添加min-height属性:

.content-wrapper {/** ... */flex: 1;min-height: 0; /** !!!*/
}
.overflow-container {flex: 1;overflow-y: auto; /** 然后这个就能发挥作用了 */
}

后来阅读 @张旭鑫 张大的 flex-end为什么overflow无法滚动及解决方法 才知道,并且很快就遇到了另一个场景,同样会导致滚动失效。这里凑巧了一直想记录下。
这种情况是由于justify-content: flex-end;属性导致的,是因为:

在 Web 中,我们的书写习惯和阅读模式是从左到右(LTR),从上到下。也就是说,一般情况之下(先不考虑其他的书写模式),水平方向内容向右溢出,垂直方向的内容向底部溢出,即滚动条在设计的时候,就约定了,只有容器下方(或右侧)内容有多余,才需要滚动。

在滚动容器(它刚好是Flexbox容器)显式设置了justify-content: flex-end(主轴方向从flex-start换成了flex-end)。这就导致,如果有内容是在上方或左侧超过容器的尺寸限制,滚动条是不会有任何变化的。也因此,滚动容器里面内容溢出容器的方向不是在容器的下方或者右侧,而是在容器的顶部和左侧,自然就无法触发滚动条的出现。

简单地说,flex-end 会让内容反向溢出,也就没有滚动条,自然无法滚动。要解决这个问题,只需要给滚动方向上的第一个子元素margin-*: auto;实现块元素的对齐效果,并且删掉flex-end即可。


瞎想

最近无事,到处看APP和网站,倒也真给我的用户体验进度出了一份力。有些地方感觉还是值得想一下的。
比如弹窗,这里先不说弹窗与用户打扰的问题。现在的app和移动端网站中对弹窗的设计逻辑可以分为两种:侧滑返回时弹窗消失(这一种是把弹窗作为一个大组件、一个拥有独立操作与逻辑的功能部分了)和侧滑返回时直接返回上一页面(这一种是把弹窗当做当前页面的附属小功能了,和页面一体)。这玩意你很难说谁对谁错的问题,用户更喜欢哪种也只能靠数据说话。甚至哪一种功能用哪一种弹窗设计都是可以规范一二的。

比如移动端网页的「返回」操作。之前看到 @HullQin(掘金) 说可以用push代替做侧滑返回逻辑。但笔者觉得这里还有两个问题:①侧滑返回这件事在移动端只有浏览器APP中可以,在QQ内置(默认打开)浏览器页面中侧滑就直接退出了,行为的不统一带来的割裂感很难被交互认同,很离谱②怎么判定用户是想回到网站首页或者是网站某个页面还是直接回到上一个打开的页面,这确实值得思考和改进。

这里没有“批判”的意思。事实上这位老哥对极致用户体验的研究挺深入的,能够给人不少感悟。

比如响应式。拿我司多件优惠和加价换购买家侧中的某一个场景(左边)来看,如果拿到更小的空间,这时候怎么更好地展示呢?
微店买家版APP/小程序/H5-活动页
目前可以确定的是,下面那种方式 所代表的展示形式 似乎并不被设计师喜爱。各位有遇到类似的场景吗?


http://chatgpt.dhexx.cn/article/5n9Jg0ZS.shtml

相关文章

DIV居中的经典方法

参考&#xff1a;https://www.cnblogs.com/rubykakas/articles/7992662.html 1. 实现DIV水平居中 设置DIV的宽高&#xff0c;使用margin设置边距0 auto&#xff0c;CSS自动算出左右边距&#xff0c;使得DIV居中。 div{width: 100px;height: 100px;margin: 0 auto; } 缺点&…

局域网屏幕共享_给安卓手机连一个大屏幕——多端协作(六)

好久不见,时下情势严峻,我们这儿封村了,生活变得更加不方便了。本来在网上买了肉,等到终于发货送到县城,我却不能进城去取了…… 希望顺丰营业点有冰箱,我的肉不会坏掉 今天给大家介绍的是Android系统的无线投屏功能,简单来说就是将支持的设备作为安卓手机的外接屏幕,以…

安卓手机与蓝牙模块联合调试(二)—— 单片机蓝牙控制LED灯亮灭(上)

系列博文&#xff1a; &#xff08;1&#xff09;安卓手机与蓝牙模块联合调试&#xff08;一&#xff09;——蓝牙模块的串口通讯 &#xff08;2&#xff09;安卓手机与蓝牙模块联合调试&#xff08;二&#xff09;—— 单片机蓝牙控制LED灯亮灭&#xff08;上&#xff09; …

android 多屏幕显示activity,副屏,无线投屏

目录 1. 首先&#xff0c;需要一个副屏 1. 1 可以通过代码的形式自己创建VirtualDispaly ,创建副屏。 1.2 或者&#xff0c;在手机的开发者模式中直接开启模拟副屏&#xff0c;也是可以的。 2.0 怎么利用这个副屏幕&#xff1f; 2.1 用作 presentation 演示ppt&#xff1…

【Android 屏幕扩展/共享】5分钟搞定—电脑 与 手机共享屏幕

回去看看老家是不是还有旧平板电脑&#xff0c;可以跨设备&#xff0c;共享屏幕哦 一些远程控制软件&#xff0c;诸如&#xff1a;TeamViewer、AnyDesk等。 但是这次我要介绍的是 一款远程显示软件&#xff0c;甚至可以理解成一款简易的KVM系统。 虽然市面上许多远程控制软件…

Android设备之间投屏功能实现

简介 简单实现两个android设备之间的投屏功能。设备间通信是通过局域网&#xff0c;需要连接同一个wifi。 录屏用到系统的MediaProjection&#xff0c;MediaProjectionManager&#xff0c;而编解码用的是MediaCodec&#xff0c;所以设备需要有DSP芯片&#xff0c;大部分手机应…

CSS实现垂直居中的5种方法

第一种 position定位margin负距离 前提是知道居中元素的宽高&#xff0c;首先给居中元素定位&#xff0c;之后设置margin的负距离为具体宽高的一半便可达到垂直居中效果 <style>.box1 {height: 300px;width: 300px;border: 10px solid pink;position: relative;}.box2 {…

在html中如何使div在页面中居中显示

在html中如何使div在页面中居中显示 最近无聊中又再温习了下html,发现好多东西都忘了。尝试着写了一个html网页&#xff0c;结果就连div如何在页面中居中显示都查了好久才弄出来。其实我不知道为什么这样可以实现&#xff0c;因为css还没仔细研究过&#xff0c;等我参加完复试定…

实现div里的img图片水平垂直居中

body结构 <body><div><img src"1.jpg" alt"haha"></div> </body>方法一&#xff1a; 将display设置成table-cell&#xff0c;然后水平居中设置text-align为center&#xff0c;垂直居中设置vertical-align为middle。 <s…

程序运行的错误

程序的运行当可能会出现的问题 没有找到文件&#xff0c;可能是相应的文件没有编写&#xff0c;或者文件名输入的有错误 程序运行可能会出现500的错误&#xff0c;错误原因大概有&#xff0c;下面几种

小程序错误

小程序报错1&#xff1a;unknown: Unexpected token, expected “,” [ appservice 生成错误] pages/page04/page04.js: file: pages/page04/page04.js unknown: Unexpected token, expected “,” (25:4) 错误原因&#xff1a;没有逗号。 小程序报错2 设置 enable-flex 属…

winword.exe应用程序错误0xc0000142

正常使用Word&#xff0c;关机再开机&#xff0c;发现提示错误“winword.exe应用程序错误0xc0000142”&#xff0c;有效解决方法 1、winR&#xff0c;输入CMD 2、输入sfc/scannow 注&#xff1a;sfc/scannow&#xff1a;立即扫描所有受保护系统文件的完整性&#xff0c;并尽可…

解决devenv.exe应用程序错误,应用程序发生异常

解决devenv.exe应用程序错误&#xff0c;应用程序发生异常 打开VS2008/2010时&#xff0c;经常碰到:devenv.exe应用程序错误&#xff0c;应用程序发生异常&#xff0c;造成的原因是多种的&#xff0c;可能是环境变量配置出错&#xff0c;可能是你安装了冲突的插件&#xff0c;如…

添加或删除程序 rundll32.exe-应用程序错误

rundll32.exe-应用程序错误 点击开始-运行&#xff0c;输入 “cmd”&#xff0c;单击确定。 在打开的命令提示符窗口中依次输入第三步中的命令复制&#xff0c;然后粘贴到命令提示符窗口中运行。 regsvr32 Appwiz.cpl regsvr32 Jscript.dll regsvr32 Mshtml.dll regsvr32…

ps无法完成请求因为程序错误

目录 方法一&#xff1a;兼容性 方法二&#xff1a;清空缓存 方法三&#xff1a;图形处理器 方法一&#xff1a;兼容性 1、右击PS软件图标&#xff0c;选择“属性” 2.选择“兼容性”选项卡&#xff0c;勾选“以兼容模式运行这个程序”&#xff0c;并选择兼容的系统&#xf…

ArcGIS遇到严重的应用程序错误的解决办法

ArcGIS遇到严重的应用程序错误的解决办法 GIS思维 很多ArcGIS用户经常会碰到程序突然崩溃遇到严重错误的时候且重启无法解决。网上给出的方法基本就是几种没有&#xff0c;基本也解决不了。 也可以去测试&#xff0c;基本就是&#xff1a; ArcGIS找打不到配置信息&#xff0c…

Photoshop储存为psd出现程序错误提示怎么办?程序错误解决教程

Photoshop是大家进行平面设计是不可或缺的图像处理工具&#xff0c;然而大家在使用Photoshop做图像处理&#xff0c;准备将psd文件保存到电脑&#xff0c;是不是经常遇到过弹出了Photoshop【无法完成请求&#xff0c;因为程序错误】的提醒窗口&#xff0c;无法完成保存工作。具…

java程序出错_java程序错误类型及异常处理

一、程序的错误类型 在程序设计中,无论规模是大是小,错误总是难免的。程序的设计很少有能够一次完成,没有错误的(不是指HelloWorld这样的程序,而是要实现一定的功能,具备一定实用价值的程序),在编程的过程中由于种种原因,总会出现这样或那样的错误,这些程序的错误就是我…

VMware.exe应用程序错误--应用程序无法正常启动(0xc000007b)错误解决方法

1.找到VMware安装包&#xff0c;双击打开安装包 2.进去到选择修复界面 3.等待修复完成然后重启电脑再进去VMware正常工作了 有什么问题可以在评论区交流

计算机显示应用程序错误窗口,电脑提示explorer.exe应用程序错误怎么办|电脑explorer.exe应用程序错误的解决方法...

‍‍ 大家应该都知道explorer.exe是什么进程&#xff0c;这是windows系统中的资源管理器&#xff0c;是windows系统提供的资源管理工具。可是有很多用户遇到了电脑提示explorer.exe应用程序错误的情况&#xff0c;这该怎么办呢&#xff1f;下面由小编跟大家介绍电脑explorer.ex…