技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTBR

怎么画一条 0.5px 的边(更新)

所属馆藏
Browser
文件格式
Markdown
原始路径
Browser/26-怎么画一条0 5px的边(更新)
本文目录12 个章节
  1. 一、CSS 像素、设备像素和 DPR
  2. 二、直接使用 border: 0.5px
  3. 三、使用伪元素 + transform: scaleY(.5)
  4. 四、线性渐变
  5. 五、box-shadow
  6. 六、SVG 线条
  7. 七、不要用 viewport 缩放制造 0.5px
  8. 八、更加实用的方案选择
  9. 九、如何验证效果
  10. 十、原文结论的现代修正
  11. 总结
  12. 参考资料

怎么画一条 0.5px 的边(更新)

Category(分类): Browser, CSS Status: 已更新

在设计稿中,分隔线有时希望比一个 CSS 像素更细。原文比较了直接设置 0.5pxtransform: scale()、渐变、box-shadow、SVG 和 viewport 缩放等方案。本文保留这些思路,但不再把某个浏览器在某个年份的表现当成通用规则。

一、CSS 像素、设备像素和 DPR

px 在 CSS 中首先是一个逻辑长度,不是永远等于屏幕上的一个物理像素。window.devicePixelRatio 表示设备物理像素与 CSS 像素的比例:

console.log(window.devicePixelRatio)

例如:

  • DPR 为 1 时,1 CSS px 约对应 1 个设备像素;
  • DPR 为 2 时,1 CSS px 约对应 2×2 的设备像素区域;
  • DPR 为 3 时,1 CSS px 约对应更高密度的设备像素区域。

浏览器缩放、系统显示缩放、屏幕切换和 WebView 配置都可能改变 DPR。不要把“Mac 默认 DPR=2”“iPhone 某型号宽度固定为 750 CSS px”当成当前所有设备的事实。

CSS 像素和设备像素关系示意

CSS 的长度值可以是浮点数:

.example {
  width: 12.5px;
  transform: translateX(0.5px);
}

但最终绘制要经过布局、栅格化和抗锯齿。对于 border-width 等属性,浏览器还可能根据设备像素对计算值进行取整或栅格化,因此不同 DPR、缩放比例、浏览器和平台的视觉结果可能不同。

二、直接使用 border: 0.5px

最简单的方案:

.hairline {
  border-top: 0.5px solid #d9d9d9;
}

现代移动浏览器和高 DPR 屏幕通常可以呈现比 1 CSS px 更细的线,但不能保证所有浏览器、DPR=1 显示器、打印输出和嵌入式 WebView 的效果完全一致。

可以给普通屏幕提供 1px 回退:

.hairline {
  border-top: 1px solid #d9d9d9;
}

@media (min-resolution: 2dppx) {
  .hairline {
    border-top-width: 0.5px;
  }
}

这个 media query 是能力提示,不是“DPR≥2 就一定清晰”。仍要在目标设备上检查颜色、对齐和可见性。

直接设置小数 px 的注意点

  • 不是所有属性都以相同方式处理小数长度;
  • 高 DPR 不意味着线一定比 1 CSS px 更清晰;
  • 细线颜色太浅时可能不满足对比度和可访问性;
  • 浏览器缩放后 DPR 可能变化;
  • 设计系统应允许 1px 回退,而不是依赖某个历史浏览器的特殊四舍五入行为。

三、使用伪元素 + transform: scaleY(.5)

这个方案保留一个 1px 的布局盒子,再缩放它的视觉内容:

.hairline-transform {
  position: relative;
}

.hairline-transform::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: #d9d9d9;
  content: '';
  transform: scaleY(0.5);
  transform-origin: center bottom;
}

伪元素缩放绘制细线示意

优点:

  • 不依赖 border-width 对小数的具体处理;
  • 不改变主要元素的布局尺寸;
  • 可以通过伪元素控制位置、圆角和颜色。

限制:

  • 缩放后可能落在半个设备像素上,出现抗锯齿或发虚;
  • 变换元素可能影响层化和合成成本,但不能保证一定独立成层;
  • 需要处理 position、层叠、点击区域和伪元素覆盖;
  • 对垂直线使用 scaleX(.5),对四边分别处理。

如果线条需要贴合设备像素,可结合实际 DPR 调整位置,但不要写死某个 iOS/Android 型号的偏移。最终仍然应该在真实目标设备上验证。

四、线性渐变

可以用渐变在一个 CSS 像素区域内混合颜色:

.hairline-gradient {
  height: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0,
    #d9d9d9 50%,
    transparent 100%
  );
}

使用线性渐变模拟细线

渐变的本质是颜色插值,不是严格意义上的“只绘制半个物理像素”。它可能产生柔和、抗锯齿的效果,适合视觉分隔线,但不适合要求一条绝对锐利的几何线的场景。

原文使用从白色到黑色的渐变来“凑出半像素”,这种写法会让线条变成颜色过渡,不建议直接复制:

/* 不推荐:线条颜色和背景耦合,容易得到渐变而非 hairline */
background: linear-gradient(#fff, #000);

五、box-shadow

历史上有人用小数偏移的阴影模拟细线:

.hairline-shadow {
  height: 1px;
  background: transparent;
  box-shadow: 0 0.5px 0 #d9d9d9;
}

使用 box-shadow 模拟细线

优点是写法简单,阴影不会改变文档流布局;缺点是:

  • 阴影同样经过栅格化和抗锯齿;
  • 不同浏览器和输出媒介的最小可见宽度不同;
  • 阴影可能被 overflow: hidden、层叠和裁剪影响;
  • 过多阴影会增加绘制成本。

把它作为普通 UI 分隔线方案时,伪元素通常更容易控制。

六、SVG 线条

SVG 可以描述矢量几何图形:

<svg
  class="hairline-svg"
  viewBox="0 0 100 1"
  preserveAspectRatio="none"
  aria-hidden="true"
>
  <line x1="0" y1="0.5" x2="100" y2="0.5" stroke="currentColor" />
</svg>
.hairline-svg {
  display: block;
  width: 100%;
  height: 1px;
  color: #d9d9d9;
}

使用 SVG 描绘细线

SVG 的 stroke-width 默认是 SVG 用户坐标中的值,最终仍然需要栅格化,并不会神奇地绕过设备像素限制。它适合:

  • 需要画任意几何图形、圆角、路径和装饰;
  • 希望把线条作为图片或图标复用;
  • 需要通过 currentColor 主题化。

使用 data URL 时要处理 URL 编码、CSP、缓存和可读性:

.hairline-svg-bg {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 1' preserveAspectRatio='none'%3E%3Cline x1='0' y1='.5' x2='100' y2='.5' stroke='%23d9d9d9'/%3E%3C/svg%3E");
}

直接把 #000 放进未编码的 data URL 可能被 URL 解析器截断或解释,生产代码更推荐独立 SVG 文件或经过可靠编码的资源。

七、不要用 viewport 缩放制造 0.5px

原文提出把移动端 viewport 设置成 scale=0.5,让 1 CSS px 对应一个设备像素。这个方法会改变整个页面的布局宽度和缩放比例,可能导致:

  • 文本、按钮和点击区域变得不符合设计预期;
  • 用户缩放和可访问性受到影响;
  • 不同设备、WebView 和浏览器行为不一致;
  • 需要把所有 UI 尺寸按倍数重新设计,维护成本很高。

正常移动页面应使用正确的 viewport:

<meta
  name="viewport"
  content="width=device-width, initial-scale=1"
>

原文中的 initial-sacle 是拼写错误,应为 initial-scale。不要通过禁止用户缩放来“保证像素”,例如不建议添加 user-scalable=no;可访问性优先于一条视觉细线。

rem 也不能解决物理像素对齐问题:它最终会参与 CSS 计算,仍然要经过 CSS 像素到设备像素的转换。

八、更加实用的方案选择

1. 普通分隔线

.divider {
  border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}

如果目标浏览器不支持 color-mix(),使用预先计算好的颜色。许多场景 1px 加合适的颜色已经足够清晰,不需要追求 0.5px。

2. 移动端高 DPR hairline

.divider {
  border-top: 1px solid #e5e5e5;
}

@media (min-resolution: 2dppx) {
  .divider {
    border-top-width: 0.5px;
  }
}

3. 不影响布局的装饰线

.card {
  position: relative;
}

.card::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: #e5e5e5;
  content: '';
  transform: scaleY(0.5);
  transform-origin: center bottom;
  pointer-events: none;
}

4. 需要图形能力

使用 SVG 或 CSS border/gradient;如果是图标、曲线、圆角和复杂路径,不要为了“0.5px”强行用 box-shadow。

九、如何验证效果

可以用下面的方式观察目标环境:

console.table({
  devicePixelRatio: window.devicePixelRatio,
  width: window.innerWidth,
  visualScale: window.visualViewport?.scale
})

验证时至少覆盖:

  • DPR=1 的普通显示器;
  • DPR=2/3 的移动设备;
  • 浏览器缩放 80%、100%、125%、200%;
  • Chromium、Safari、Firefox 和目标 WebView;
  • 浅色/深色背景、不同线条颜色;
  • 页面缩放、打印和无障碍字体设置;
  • 线条是否影响布局、点击和滚动。

devicePixelRatio 变化时可以重新计算样式或使用 resolution 媒体查询:

const watchDpr = () => {
  console.log('当前 DPR:', window.devicePixelRatio)
  const media = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
  media.addEventListener('change', watchDpr, { once: true })
}

watchDpr()

十、原文结论的现代修正

  • “一个像素就是一个固定大小的色块”不准确,CSS px 和设备像素不是一回事;
  • 现代浏览器可以接受浮点 CSS 长度,但最终效果受属性、DPR、缩放和栅格化影响;
  • 不能把 Chrome、Firefox、Safari 某个旧版本的 0.5px 结果当作当前通用规则;
  • transform: scale(.5) 可能产生抗锯齿,不能保证所有设备都锐利;
  • 渐变和阴影是视觉模拟,不是严格物理半像素;
  • SVG 是矢量描述,但最终仍然要栅格化;
  • initial-sacle 应改为 initial-scale,不建议通过 viewport scale=0.5 改变整站坐标系;
  • 是否使用 0.5px 要服从设计、可访问性和目标设备验证,1px 回退仍然必要。

总结

  1. CSS px 是逻辑单位,DPR 表示 CSS 像素和设备像素的比例;
  2. border: 0.5px 在现代高 DPR 环境通常可用,但不是所有环境都一致;
  3. 伪元素加 transform: scaleY(.5) 适合不改变布局的装饰线,但可能抗锯齿;
  4. 渐变、box-shadow 和 SVG 各有适用场景,都不能绕过最终栅格化;
  5. 不要使用 viewport scale=0.5 作为全局 hairline 方案;
  6. 先提供 1px 回退,再按 DPR、浏览器和设计目标增强;
  7. 最终必须在真实目标设备和缩放比例下验证清晰度、对比度与可访问性。

参考资料

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS