问题描述
前两天接到业务反馈,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则表现一致。
