CSS实现倾斜文本流:如何使外层容器宽度包含浮动伪元素
纯CSS实现带倾斜文本流的自适应宽度容器
我想要创建一种倾斜文本流,其中文本行的固定宽度由CSS变量--w定义。目前已实现的代码如下,但存在文本溢出外容器的问题:
初始代码
CSS
* { margin: 0 } html, body { display: grid } body { --w: min(35em, 65vw); --f: 1/ 8; background: linear-gradient(90deg, transparent var(--w), pink 0); font: 1em ubuntu, sans-serif } .outer-wrapper { width: min-content; box-shadow: 0 0 0 2px red; background: lemonchiffon } span::before, span::after { --i: 0; --j: calc(1 - var(--i)); --g: linear-gradient(to right bottom, hsla(50, 50%, 50%, var(--j)) 50%, hsla(50, 50%, 50%, var(--i)) 0); float: left; height: 100%; aspect-ratio: var(--f); background: var(--g); shape-outside: var(--g); content: '' } span::after { --i: 1; float: right } .inner-wrapper { width: var(--w); box-shadow: inset 0 0 0 2px blue }
HTML
<div class="outer-wrapper"> <span aria-hidden="true"></span> <div class="inner-wrapper"> <p>Gingerbread macaroon cake topping wafer cake dessert. Lemon drops cheesecake lemon drops lollipop biscuit tart. Chupa chups bonbon dragée tart pie. Oat cake cupcake bear claw pie ice cream ice cream. Jelly beans ice cream icing halvah cotton candy. Tiramisu dragée macaroon chocolate bar chocolate cake. Sweet roll wafer candy gummies donut wafer liquorice sugar plum. Icing gummies chocolate cake gummies caramels sweet roll. Tootsie roll jelly beans jelly chocolate jelly beans pie. Halvah lollipop lemon drops shortbread bonbon. Jelly biscuit bear claw cotton candy cotton candy chocolate bar soufflé donut lollipop. Fruitcake lemon drops marshmallow sugar plum cheesecake gingerbread. Sugar plum chupa chups candy canes jelly-o powder liquorice icing.</p> <p>Gingerbread macaroon cake topping wafer cake dessert. Lemon drops cheesecake lemon drops lollipop biscuit tart. Chupa chups bonbon dragée tart pie. Oat cake cupcake bear claw pie ice cream ice cream. Jelly beans ice cream icing halvah cotton candy. Tiramisu dragée macaroon chocolate bar chocolate cake. Sweet roll wafer candy gummies donut wafer liquorice sugar plum. Icing gummies chocolate cake gummies caramels sweet roll. Tootsie roll jelly beans jelly chocolate jelly beans pie. Halvah lollipop lemon drops shortbread bonbon. Jelly biscuit bear claw cotton candy cotton candy chocolate bar soufflé donut lollipop. Fruitcake lemon drops marshmallow sugar plum cheesecake gingerbread. Sugar plum chupa chups candy canes jelly-o powder liquorice icing.</p> <p>Gingerbread macaroon cake topping wafer cake dessert. Lemon drops cheesecake lemon drops lollipop biscuit tart. Chupa chups bonbon dragée tart pie. Oat cake cupcake bear claw pie ice cream ice cream. Jelly beans ice cream icing halvah cotton candy. Tiramisu dragée macaroon chocolate bar chocolate cake. Sweet roll wafer candy gummies donut wafer liquorice sugar plum. Icing gummies chocolate cake gummies caramels sweet roll. Tootsie roll jelly beans jelly chocolate jelly beans pie. Halvah lollipop lemon drops shortbread bonbon. Jelly biscuit bear claw cotton candy cotton candy chocolate bar soufflé donut lollipop. Fruitcake lemon drops marshmallow sugar plum cheesecake gingerbread. Sugar plum chupa chups candy canes jelly-o powder liquorice icing.</p> </div> </div>
问题描述
当前.outer-wrapper(红色外框)的宽度仅由.inner-wrapper的--w决定,两侧浮动的伪元素宽度未被计入,导致文本溢出容器。我希望完全用CSS解决该问题,不使用JavaScript,也不能用倾斜容器的方案。
纯CSS解决方案
利用CSS容器查询(Container Queries)获取容器高度,计算伪元素宽度并叠加到文本宽度上,让外容器自动适配总宽度:
修改后的CSS
* { margin: 0 } html, body { display: grid } body { --w: min(35em, 65vw); --f: 1/ 8; background: linear-gradient(90deg, transparent var(--w), pink 0); font: 1em ubuntu, sans-serif } .outer-wrapper { /* 启用容器查询,允许获取容器尺寸 */ container-type: size; /* 外容器宽度 = 文本宽度 + 左右伪元素宽度(每个伪元素宽度=容器高度*比例--f) */ width: calc(var(--w) + 2 * calc(container-height() * var(--f))); box-shadow: 0 0 0 2px red; background: lemonchiffon } span::before, span::after { --i: 0; --j: calc(1 - var(--i)); --g: linear-gradient(to right bottom, hsla(50, 50%, 50%, var(--j)) 50%, hsla(50, 50%, 50%, var(--i)) 0); float: left; height: 100%; /* 直接用容器高度计算伪元素宽度,替代aspect-ratio */ width: calc(container-height() * var(--f)); background: var(--g); shape-outside: var(--g); content: '' } span::after { --i: 1; float: right } .inner-wrapper { width: var(--w); box-shadow: inset 0 0 0 2px blue }
核心修改点
- 给
.outer-wrapper添加container-type: size,启用容器查询功能,可获取容器的高度值container-height()。 - 外容器宽度改为
calc(var(--w) + 2 * calc(container-height() * var(--f))),将左右两个伪元素的宽度(基于容器高度计算)叠加到文本宽度上。 - 伪元素改用
width: calc(container-height() * var(--f))替代aspect-ratio,确保宽度计算和外容器完全匹配。
兼容性说明
容器查询目前支持Chrome 105+、Firefox 110+、Safari 16+,如果需要兼容旧版浏览器,仍需使用JavaScript方案,但这是纯CSS下的最优解。
内容的提问来源于stack exchange,提问作者Ana
相关产品推荐
相关产品推荐

