问题描述
前两天接到业务反馈,nav-bar组件在部分机型上右侧图标位置异常。
大概的表现如下图所示
问题分析
通过反馈可以提取到两条有用的信息。
- 部分机型
- 位置异常
基于以往的经验,从这两条信息可以快速得出定位问题的大致方向。
- 只在部分机型复现 -> 有可能是兼容性问题 -> 浏览器内核版本 -> UA
- 位置异常 -> 样式问题 -> CSS
于是让业务提供了UA,浏览器内核版本是chrome 69,属于比较旧的版本,更有可能出现兼容性问题。
有了内核版本就可以去下载对应版本的浏览器进行复现,很顺利的复现了。既然是样式问题,就优先查看CSS,这两个icon的父容器使用了flex布局,并且设置了justify-content: end;
让子元素从结束位置排列,但从表现来看,在有问题的浏览器中,子元素是从起始位置排列的,不符合预期。因此基本可以大胆猜测问题是justify-content: end
引起的。
上面的只是猜测,仍然需要小心求证,先通过查阅MDN,确认下我对这个属性的用法是否有误解。
end
The items are packed flush to each other toward the end edge of the alignment container in the main axis.
flex-end
The items are packed flush to each other toward the edge of the alignment container depending on the flex container’s main-end side. This only applies to flex layout items. For items that are not children of a flex container, this value is treated like end.
通过文档可以看到用法应该是没有问题的,但同时发现还有另一个属性值flex-end
,是专门用于flex布局的,在我们的场景中使用flex-end
更适合。按文档的说法,如果不是flex布局的子元素,会与end
表现一致,但并未提到flex布局中不能使用end
,而且在较新版本的浏览器中end
表现确实是符合预期的。
确认了用法无误,再看看这个属性是否有版本兼容问题,通过查看caniuse,发现end
是在chrome >= 93
及ios safari >= 15.3
开始支持的,业务反馈的机型是chrome 69
,确实还未支持。
再看属性值flex-end
在caniuse中没有特殊说明,那应该是和flex支持justify-content属性同时支持的。
- chrome >= 21
- ios safari >= 7
这样的话,把end
换成flex-end
就应该能解决这个bug了。
结论
验证
写了个小demo,再次验证上面的推测和结论。
iOS safari 14 VS. safari 15.4
Android chrome 76 VS. chrome 114
结论
- ios >= 15.4和chrome >= 93,flex布局中,
justify-content: end;
与justify-content: flex-end;
表现一致,都符合预期。 - ios < 15.4和chrome < 93,flex布局中,
justify-content: end;
无法生效,justify-content: flex-end;
符合预期。 - 使用grid布局,
justify-content: end;
在各个版本的浏览器中表现都符合预期。
因此,对justify-content
设置值时,为了保障最大程度的兼容性,如果是flex布局,使用flex-start
或flex-end
,其它布局方式则使用start
、end
、left
或right
。
还有一个值得注意的点,align-items
和justify-content
非常类似,上面的结论对于align-items
属性同样适用。
align-items
属性chrome 87 VS. chrome 95
在这个示例中,垂直方向排列受align-items
属性控制,低于chrome 93时,align-items: end;
表现不符合预期,而flex-end
则表现一致。