当前位置: 首页 > 科技观察

Flexbox中的优雅布局

时间:2023-03-12 04:36:57 科技观察

body{font-size:32px;}工作中前端布局问题比比皆是,是时候花点时间上下挖掘一下了。本文尝试从标题布局、左右布局、均分布局、跟进布局、父子宽度约束探索、无限空间缩减六个案例中实践解题思路,看窍门。希望对大家提高工作效率和技术水平有所启发。(1)标题布局标题:标题居中超长,标题左右各有几个图标。答:⑴标题居中,左右距离要控制相等,是典型的左右中右结构。常见的做法是使用绝对布局,在标题左右设置相同的外边距(marginorpadding),使用绝对布局(position:absolute)覆盖标题左右外边距在左右图标上。需要注意的是,标题容器需要设置为相对布局(position:relative)作为左右图标的锚点。更优雅的方式是使用flexbox布局,左右固定宽度,剩余空间在中间,即elastic属性设置为automatic(flex:auto),相当于flex:11auto.其中flex-grow为1表示有足够的??空间展开,flex-shrink为1表示没有足够的空间收缩,flex-basis为auto表示使用width或height来显示设置的宽度和height(主轴方向横向取宽度,纵向取height),不设置则使用内容的宽度和高度。⑵如果标题超长,需要设置不换行(white-space:nowrap)、溢出隐藏(overflow:hidden)和文字溢出点(text-overflow:ellipsis)。⑶左右图标布局,常见的做法是准确计算边距,使左边左对齐,右边右对齐。但更优雅的做法是flexbox布局,将计算“丢”给柔性布局,直接将左主轴方向指向正方向(flex-direction:row,默认值),右主轴方向到相反的方向(flex-direction:row-reverse)。(2)左右布局题:左边几个图标从左到右依次排列,最后一个图标放在最右边。答:解决问题的方法有以下三种。除了将上面的绝对布局和弹性属性设置为automatic之外,还有一个更简单的方案,就是在flexbox布局中将leftside设置为automatic(margin-left:auto)。(3)均匀分布的布局主题:不同内容宽度的子元素等距分布(下图中的绿、蓝、红为子元素,其中深色为内容区域,浅色为多余区域扩展空间)。答:众所周知,自动弹性伸缩(flex:auto)只能扩展剩余空间,不能扩展整体空间。在上面的问题中,我们很容易也似乎可以达到以下效果:空间不能均分吗?答案必须是“否”。flex:auto的全称是flex:11auto,最后一位是flex-basis,即elasticbasesize,默认为contentsize。那么contentsize可以设置为0吗?答案是“可以”。直接上传代码:(iv)遵循布局标题:图标始终紧跟标题。当标题内容过长时,仍然显示图标,标题文字可以超长。答:这个问题是不是太水了?整个标题设置为弹性布局,文字拉伸属性使用默认值(flex:initial,即flex:01auto,空间不拉伸但空间不足收缩),超级longdot(overflow:hidden;text-overflow:ellipsis;),图标可以放在标题的右边。这里再说一句,细心的朋友发现上面的超长圆点并没有设置为不换行(white-space:nowrap)。如果太长为什么不换行呢?因为div标签本身默认的块布局(display:block)是不换行的,所以如果将layout属性改为灵活布局,需要像title布局一样设置不换行。等等,这个问题中“水”怎么说?出现这个问题的原因是我一直沿用Android的布局思维(不久前从Android转Web),标题跟随不截断,首页和列表随处可见应用程序中的页面。自然,Android也需要实现这个功能。但是在Android中,如果要制作超长的点,就必须限制宽度。常规的写法是文字宽度为0,自适应占用其他控件布局后的剩余空间(LinearLayout#layout_width:0;layout_weight:1;),因为Android支持布局限制,让这道题更有趣一点.如果带到前端,假设flex属性只能设置拉伸和收缩(flex:auto),标题怎么跟不上截断呢?先直接改上面的代码看看具体效果。那么,问题来了?文字不太长的时候,图标不跟着...看看Android上的效果吧。下图显示了两个被红色框包围的区域。区域1类似于上面的Web实现。文本控件宽度为0,权重为1(android:layout_width="0px"android:layout_weight="1"),当文本较短时,多余的空间直接展开放大,导致图标变大右对齐而不是跟随。这里用到了一个“小技巧”。文本控件的属性保持不变,但文本和图标控件包裹了一层水平线性布局自适应宽度(android:layout_width="wrap_content"),可以保证文本不会被拉伸。因为父控件宽度自适应,没有多余的空间,最大空间受自身父控件约束,效果是区域2。以上思路来自前美团同事袁珏2015年的分享。原因这个解题思路之所以不能被遗忘,是因为它有点像脑筋急转弯。当然,这种情况可以通过自定义布局轻松实现。主要目的是先计算其他控件的大小。如果当前宽度过长,只会占用剩余空间,否则正常自宽。同样的方法可以复制到网络上吗?试一下,文本控件自动拉伸,Android设置属性为layout_width="0px"和layout_weight="1",相当于Web设置为flex:auto。将自适应宽度的水平线性布局层外包给文本和图标。Android设置属性为layout_width="wrap_content",相当于Web设置(width:100%;max-width:min-content;)或(width:min-content;max-width:100%;),也就是说,宽度是内容大小和父组件大小之间的最小值。抓重点,同时设置width和max-width,内容短时width跟随,内容长时dot。同意的朋友一定要记住。我为什么要绕这么大的圈子来谈Web上舍易而难的问题,主要是我通过Web实践来检验现有的Android体验。道理相通,分歧难免趋同。(iv)探索父子宽度约束题目:父组件宽度固定(width:200px),组件设置为灵活布局(display:flex),子组件为文本和图标。当文本长度超过时,组件宽度是超长内容宽度(下图标签1)还是父组件宽度(下图标签2)?答案:结论在先,实测答案标2。乍一看,弹性组件容器没有设置宽度,它的宽度应该是内容宽度。由于内容太长,背景颜色必须与内容相同。既然和你想的不一样,那就去查一下官方的CSS文档吧。宽度不显示设置时使用默认值auto。auto在文档中的解释是“浏览器会为指定的元素计算并选择一个宽度”。但是我感觉我说了就像没说一样,没有说是什么计算算法。实测发现auto对应的是父组件的大小,即背景色覆盖的区域只是父组件的范围。那么如果我们想让组件宽度成为超长内容宽度怎么办呢?这是一道子题,设置宽度为内容大小即可(width:min-content)。不过我在实际测试中发现还有一种方法可以达到同样的效果,就是将父组件设置为灵活布局。按理来说,如果不显示宽度,默认值为auto,即父组件的尺寸。不管父组件是不是弹性布局,尺寸都已经指定了,但实际上影响了组件的宽度?至于为什么会这样,我现在真的不知道,留给未来的自己,或者屏幕前的你来回答。(v)空间无限缩小。好奇心来自阅读官方文档《flex 布局的基本概念》“如果超出容器的元素过多,不包裹就会溢出。”会不会压缩太多?对于elastic默认属性(flex:initial,即flex:01auto,不扩容只缩容),怎么会溢出呢?自己复制粘贴了一堆文字,结果溢出来了?如下所示。修不了。。。后来和同事永健交流得知,当组件的宽度收缩到最小内容尺寸后,就不会再收缩了。文本本身的大小就是内容的最小大小,可以通过最小宽度(min-width)设置内容大小。至此,真相终于大白。顺便提一下,官方文档还是写的不够严谨,造成不必要的误会。附WebDemoHtml源码:flexDemobody{font-size:32px;}