你以为 width 只能靠 100% 占满容器?Safari 27 今天用 stretch 把这件事彻底原生化了
写过前端的都知道,width: 100% 是个坑——它指的是父元素的 content box,不算 margin,一旦你给子元素加了 margin,overflow 就来了。所以很多人长期靠 width: calc(100% - 2rem) 活着,改一次 margin 还要回头同步 calc 里的值。
Safari 27 今天把这件事彻底原生化了:stretch 关键字现在可以直接用在 width、min-width、max-width、height、min-height、max-height 和 flex-basis 上,用来替代那个老 hack。
/* 以前 */
.card {
width: calc(100% - 2rem);
/* 或者那个非标准的 -webkit-fill-available */
width: -webkit-fill-available;
}
/* Safari 27+ */
.card {
width: stretch;
margin: 1rem;
}
-webkit-fill-available 是这些年最接近 stretch 的方案,但它本身是 webkit 私有前缀,用在哪些场景下行为正确、哪些场景下会踩雷,一直没有文档说清楚过。而且这个关键字本身对 margin 的处理逻辑和 stretch 并不完全等价——Safari 27 的 stretch 才是真正把「填满父容器,同时正确处理 margin」这件事做对了。
一个实际场景感受一下:width: 100% 加上 margin: 1rem 之后,实际宽度 = 父容器 content 宽度,不会把两边的 1rem 留出来,所以会溢出。而 width: stretch 加上 margin: 1rem 时,浏览器在 stretch 层面就把 margin 的空间留出来了,不会溢出。这两行 CSS 在视觉上可能差不多,但在有边距的实际项目里,差距立竿见影。
浏览器兼容性
Safari 15.1+ 支持 height 方向上的 stretch,但 Safari 27 才把 stretch 扩展到了所有 box-sizing 属性。Firefox 和 Chrome 目前还没有支持 stretch。这个功能目前只有 Safari 独享,用的时候建议加上备用方案:
.card {
width: 100%;
width: stretch; /* Safari 27+ */
margin: 1rem;
}
非 Safari 浏览器会用 width: 100%,效果差不多但 margin 处理方式不同;Safari 27+ 用户会用到真正的 stretch。如果想保持一致,继续用 calc() 也可以,但每次改 margin 都要回头同步 calc 里的值。
Safari 27 这次把 height、width、flex-basis 的 stretch 全收进来了,之前用 -webkit-fill-available 这个私有前缀 hack 解决的问题,现在有了一个干净的原生标准。该升级了。
评论区
登录后可评论。