下拉框高度别再靠蒙了,calc-size() 能把 select 高度控制到像素级

下拉框高度别再靠蒙了,calc-size() 能把 select 高度控制到像素级

导语

你有没有遇到过这种情况:表单里的 高度总是不听话,在 Chrome 里 40px,到 Safari 就变成 42px,再换台手机又变了?如果你还在用 appearance: none + 固定 height 硬压,那这篇文章能帮你省掉一堆 @media!important

正文

问题:select 高度为什么这么难控制?

原生 的高度并不是你 CSS 里写的那个值。

浏览器在渲染 select 时,会把内容高度“ intrinsic size ”算进去,然后再套一层系统原生 UI。结果是:

  • height: 40px 不生效,实际高度跟着选项文字跑
  • 不同系统、不同浏览器、不同字体设置下,表现都不一样
  • 就算加上 box-sizing: border-box,也压不住

更麻烦的是,以前我们没有“基于 intrinsic size 再算一次”的 CSS 函数,只能靠 JS 测高度再写回去,或者接受系统默认值。

方案:calc-size() 来了

calc-size() 是 CSS Sizing 规范里的新函数,语法是:

calc-size(, )

第一个参数是“基础尺寸”,第二个是在这个基础上加减。关键来了: 可以是 autointrinsic 等关键词,浏览器会先算出元素本来想变成多大,再按你给的公式算。

Jake Archibald 在 2025 年底写了一篇被广泛转发的文章,标题就叫 “Goldilocks Select Height”——用 calc-size() 给 select 找一个“刚刚好”的高度。

他的核心代码长这样:

select {
  /* 先拿 intrinsic size 作为基础 */
  --base: calc-size(auto, size);
  height: calc-size(var(--base) - 2em);
}

这行代码的意思是:先让浏览器算出来 select 本该有的高度,再从中减去 2em。结果就是 select 高度永远比内容“刚好矮一点”,而且跨浏览器、跨系统一致。

代码:完整可落地的示例

Jake Archibald 给的完整方案还要加 field-sizing,让 textarea 也能自动跟着内容长:

/* 1. select:用 calc-size() 做“刚刚好”的高度 */
select {
  --base: calc-size(auto, size);
  height: calc-size(var(--base) - 2em);
  padding: 0.5em 2.5em 0.5em 0.75em;
  border: 1px solid #ccc;
  border-radius: 6px;
  background: white
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' fill='none' stroke='%23666' stroke-width='1.5'/%3E%3C/svg%3E")
    no-repeat right 0.75em center;
  appearance: none;
}

/* 2. textarea:用 field-sizing 自动撑高 */
textarea {
  field-sizing: content;
  min-height: 4em;
  width: 100%;
  padding: 0.5em;
  border: 1px solid #ccc;
  border-radius: 6px;
}

这段代码有两个亮点:

1. calc-size(auto, size) 作为基础auto 让浏览器先算 intrinsic size,size 是别名,代表“元素原本的大小”。这个组合在 Chrome 149+ 已经支持。

2. field-sizing: content:这是 CSS 的新属性,让 textarea 高度跟着内容走,不用 JS 监听 input 事件。

兼容性:现在能用吗?

截至 2026 年 7 月:

  • calc-size():Chrome 149+、Edge 149+ 已支持,Safari 和 Firefox 仍在实现中
  • field-sizing:Chrome 150+ 进入 Baseline,Safari 跟进中

如果你的项目面向现代浏览器,已经可以放心用。如果还需要兼容 Safari/Firefox,建议加一个 @supports 降级:

@supports (height: calc-size(auto, size)) {
  select {
    --base: calc-size(auto, size);
    height: calc-size(var(--base) - 2em);
  }
}

@supports not (height: calc-size(auto, size)) {
  select {
    height: 42px; /* fallback */
  }
}

结论

calc-size() 解决的问题很具体:让 CSS 能“先知道元素本来多大,再按你的公式算”。对 select、textarea、甚至自定义组件的高度控制都很有用。

如果你厌倦了 JS 测高度、CSS 写死值、不同浏览器表现不一样,现在可以把这组新属性放进你的表单样式里了。

收尾

下一步:在你的下一个表单页面里,把 select 的高度改成 calc-size() 版本,对比一下跨浏览器的表现。如果你用的是 Chrome 149+,应该能立刻看到差异。

评论区

0 条评论

登录后可评论。

查看完整榜单
查看完整榜单
查看完整榜单