场景描述工作中遇到这样一个需求场景:由于视觉设计师的视觉审美要求下,h5页面中,查询的商品列表每行有多个标签标签个数不固定,宽度自适应,左右间距固定。
整体左右间距30px,标签之间间距6px,页面整体宽度640px(不同机型不同宽度)。
注:当前h5脚手架开发采用的scss,已集成了px2rem也就是像素转rem,编写px即可实现不同宽度的自适应。
初步思考通常,由于移动端布局有一定兼容性等问题,一些特定的布局如display:grid等,我们还是谨慎使用。
我们想到的第一想法是flex布局,可以使得宽度自适应,闪现的思路是:父元素设置为display:flex,自动换行子元素设置间距:距离上下左右,然后宽度就自适应,然后就好了?// scss// 父元素.parent {display:flex;flex-wrap:wrap;margin-left: 10px;margin-right: 30px;}// 大致的想法.child {flex: 1;margin: 10px 6px;width: auto; // ?这个宽度如何处理}对于justify-content:space-between,期初也想使用这种,但需求要间距固定,无法适用。
问题来了现实是残酷的,你会发现子元素全部在一排,没有宽度,也发现这里的最大难点就是如何确定标签宽度如何实现一行三个每行的三个标签第二个标签和第三个标签之间有间距,而第一个和左边相对页面左右边是没有间距的。
尝试解决我们知道问题中使用flex布局的核心问题是要有最小宽度,没有宽度就不会撑开。
css3的calc在移动h5中的兼容性还是不错的,我们可以动态计算宽度。
根据每行显示3个,间距固定,那么我们可以得出以下计算公式:子元素标签宽度 = ( 页面总宽度100% – 页面左右宽度30px * 2 – 标签左右边框2px * 3 – 边框左右间距6px * 2 ) / 3;化简:子元素标签宽度 = 100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – 6px * 2 / 3= 100% / 3 – 26px// 子元素宽度.child {width: calc(100% / 3 – 26px);}还是有问题,1行只能展示2个这样布局,还是发现出现问题,虽然我们按照思路进行布局,但我们忽略了一个重点:标签的左右间距规律是:第1、4、7等最左侧第一个,也就是3n+1距离左侧是空的。
第一时间,你会想通过伪类 nth-chilld(3n+1)来实现标签。
但如果真这样做,这里对于h5页面来说,误差大,这种间距稍不留神就会出现溢出换行维护成本高,其他小伙伴维护需要注意这个伪类控制我们换一种思路来考虑。
其实这类场景PC端是很常见的,我们可以联动父元素来解决。
思路:父元素宽度设置为100%加上一个间距的距离父元素距离左侧减少一个间距的距离优点:间距可以抽出为变量,方便维护误差小最终方案父元素flex布局,距离左侧为指定宽度,子元素宽度应该为正常的三个相同宽度和间距元素。
子元素标签宽度 = ( 页面总宽度100% – 页面左右宽度30px * 2 – 标签左右边框2px * 3 – 边框左右间距6px * 3 ) / 3;化简:子元素标签宽度 = 100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – 6px * 3 / 3= 100% / 3 – 28px// scss$width: 6px;// 父元素.parent {display:flex;flex-wrap:wrap;margin-left: (30px – $width);margin-right: 30px;width: calc(100% + $width);}// 大致的想法.child {flex: 1;margin: 10px $width;width: calc(100% / 3 – 30px * 2 / 3 – 2px * 3 / 3 – $width * 3 / 3)// width: calc(100% / 3 – 28px);}总结看似一个很容易很常见标签宽度自适应的布局样式问题,却引发了坑,各种思考,当然方案远不止这一种。
我们可以通过实践经验总结出以下几点:宽度自适应问题可以通过动态计算(当前主流浏览器基本都支持)子节点的宽度问题可以去思考父元素是不是能够做一些改变实现多思考,大胆实践,方法总比困难多,这样你才会摸索出更多的方法。
web前端开发岗位,一定要能够脑洞灵活,各种角度各种方法思考。
我们才能游刃有余。
谢谢大家。
我是路程lucky,6年web前端开发经验,目前参与的项目技术栈主要是React,欢迎关注~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)