CSS Layout API实现列表居中左对齐效果实例页面
展示
第1行
第2行,文字较多
第3行,哈
第4行
第5行
102.00
23.80
12,334.00
2.88
99.99
// zxx: 打开控制台,注释掉 display: layout(center) 观察效果
代码
-
HTML:
<section> <p>第1行</p> <p>第2行,文字较多</p> <p>第3行,哈</p> <p>第4行</p> <p>第5行</p> </section>
CSS:
section { display: layout(center); outline: 1px dotted; } /* 可以避免加载内容跳动问题 */ section p { margin: 0 -999px 0 -3800px; }
页面内JS:
if (window.CSS) { CSS.layoutWorklet.addModule('layout-center.js'); }
-
layout-center.js代码:
registerLayout('center', class { static inputProperties = ['line-height', 'text-align']; static layoutOptions = { childDisplay: 'normal', sizing: 'block-like' }; async intrinsicSizes(children, edges, styleMap) { // 内部尺寸相关代码 } async layout(children, edges, constraints, styleMap, breakToken) { // 布局相关代码 let lineHeight = styleMap.get('line-height').value; let textAlign = styleMap.get('text-align').value; // 计算内容的长度 const childrenSizes = await Promise.all(children.map((child) => { return child.intrinsicSizes(); })); // 求得最大内容宽度 const maxContentSize = childrenSizes.reduce((max, childSizes) => { return Math.max(max, childSizes.maxContentSize); }, 0) + edges.inline; // 约定俗称的一些初始化套路 const availableInlineSize = constraints.fixedInlineSize - edges.inline; const availableBlockSize = constraints.fixedBlockSize ? constraints.fixedBlockSize - edges.block : lineHeight; const childConstraints = { availableInlineSize, availableBlockSize }; const childFragments = await Promise.all(children.map((child) => { return child.layoutNextFragment(childConstraints); })); // 子元素的垂直偏移大小 let blockOffset = edges.blockStart; childFragments.forEach((fragment, index) => { fragment.inlineOffset = Math.max(0, availableInlineSize - maxContentSize) / 2; if (textAlign == 'right' || textAlign == 'end') { fragment.inlineOffset += (maxContentSize - childrenSizes[index].maxContentSize); } fragment.blockOffset = blockOffset; // 偏移递增 blockOffset += lineHeight; }); // 最终元素的高度大小 const autoBlockSize = blockOffset + edges.blockEnd; return { autoBlockSize, childFragments }; } });