| LayoutNG 是小部件的新布局引擎,转为现代化 Web 应用程序而设计,布局能力全面对齐 W3C 标准。
本文主要介绍小部件在升级新布局引擎 LayoutNG 过程中可能会遇到的常见兼容问题,这些问题主要是使用了非标准的 Web 行为所导致。
基于新的渲染布局引擎 LayoutNG,这次小部件底层技术升级新增和优化了50+项功能点,涉及样式、布局、绘制、事件、动画和滚动列表等。
先更新IDE到较新的版本:https://developer.taobao.com/
1. 在 widget 目录下的 plugin.json 文件中添加一级字段: "enableLayoutNG":true。
2. 关闭项目窗口,重新打开IDE,该项目即可自动进入 LayoutNG 模式;
3. 自行检查目前项目渲染效果在真机上的差异,如有差异可以对照以下注意事项进行调整;
问题1:LayoutNG 修复了 CSS 样式优先级规则,正确处理简写样式的覆盖关系。
例如先写了展开后的样式(如 border-top)又写了简写样式(如 border),后面的会覆盖前面的。
| 比如在 class 中写 background-size,在 style 属性中写 background,会导致 background-size 失效。
解决方案:考虑 CSS 样式优先级和 shorhand 与 longhand 的覆盖关系。
问题1:LayoutNG 支持了外边距折叠特性,如果之前代码中未考虑外边距折叠,可能会出现元素间距问题。
外边距折叠条件:1. ??折叠 2. 垂直?向相邻元素 3. ?元素和第?个/最后?个?元素。
外边距折叠不会跨越 BFC (Block Formating Context),可以创建 BFC 消除外边距折叠,创建方式:
解决方案:根据元素特性,使用合适的样式创建 BFC 以消除外边距折叠。
| LayoutNG 中会把 img / video / canvas 作为置换元素(replaced element), 按照内容固有宽高比进行布局。
问题1:img 自身没有设置width和height,则默认为图片固有大小。
解决方案:为 img 设置 width 和 height。
问题2:如果 img 元素的 width 和 height 为百分比,需要确保父节点有合适的大小。
例如:图片节点的父节点是 absolute,absolute节点在未指定width, left或right为auto时会使用固有大小。
解决方案:需要确保父节点有合适的大小。
问题3:如果 embed 节点 height 是 1000px,那最后渲染的高度就是1000px,并不会与父节点高度保持一致。
解决方案:把 height 修改为 100%。
| 老布局引擎不识别 <span> 元素上的 dispaly 样式,默认创建 inline 节点,但 LayoutNG 会根据 dispaly 创建布局对象。LayoutNG 支持 display 属性:block | inline | flex | inline-block | inline-flex | flow-root。
问题1:如果之前 <span> 元素上设置了 dispaly: flex,可能会导致文本换行显示。
解决方案:去掉 <span> 元素dispaly: flex样式。
问题2:如果之前 <span value="文本内存"> 通过 value 属性设置文本,会不生效。
解决方案:把文本内容放到 span 标签内。
问题3:LayoutNG 支持 word-break: break-all,可能会出现换行策略有差异。
解决方案:如果希望使用之前的断行策略,可以去掉 word-break: break-all 样式。
| LayoutNG 对齐了 W3C position 元素的标准行为。
问题1:position: fixed 元素层级问题,fixed 节点不一定会显示在最上层,与 position 层级有关。
老布局引擎会把 position: fixed 元素放到最上层显示,而 LayoutNG 会按照 stacking context 和元素位置关系进行显示。
解决方案:设置正确的 position 层级。
问题2:如果 out-of-flow position 元素的父或祖先节点设置 tranfrom/filter 等样式,会导致position 元素 Containing Block 发生变化,可能导致位置偏移。
解决方案:考虑 transform/filter 等样式对 Containing Block 的影响。
问题3:如果 position 元素未设置left、right或者未设置top、bottom 样式,可能导致与目标位置有偏移。
在 LayoutNG 中position 元素未设置left、right或者未设置top、bottom 样式会在对应的轴上有默认位置。比如未设置left和right,position元素在横轴上会有默认位置,未设置top和bottom会在纵轴上有默认位置。
解决方案:为 position 元素设置正确的 left/top/right/bottom 样式。
问题1:flex 布局压缩子元素导致文本换行显示问题。
例如: 文本 “上滑” 宽度被压缩导致换行。
解决方案:对文本节点添加 white-space: nowrap 样式。
问题2:如果 flex 子节点设置 overflow:hidden 样式,flex布局会忽略自身的固有大小,可能导致元素被压缩或列表无法滑动。
解决方案:移除flex 子节点上的 overflow:hidden。
问题3:如果flex子节点预期不想被压缩,但是最终结果被 flex 压缩了。
解决方案:如果预期某个flex 子节点不想被 flex 压缩,可以加上 flex-shrink:0 样式,否则默认会被压缩。
问题4:image节点宽度是百分比,而且其父节点是flex节点,则 image 可能会被flex压缩。
解决方案:为image标签添加 width: auto 样式。
| 滚动列表包含 overflow: scroll/auto、scroller、list等。
问题1:滚动列表未指定 width 或 height 样式,可能会导致无法滑动。
解决方案:为滚动列表元素设置合适的 width 或 height 样式。
问题1:某个节点没有事件响应。
解决方法:可以把当前页面用 web 渲染,然后利用 web 的审查元素选中该节点,如果发现无法选中想要响应的节点,说明有更高层级的节点被挡住导致无法响应该节点。
问题2:如果想要忽略层级更高的节点,该如何操作。
解决方法:可以使用样式 pointer-event
。