HTML: 子像素边框

16

在IE6+中,是否可能有一条比1像素更细的边框,不是图片,并且在视觉上正确呈现?

谢谢。


为什么你要问这个问题?你是在看某个实现吗? - KJ Saxena
2
听起来像是一场灾难的配方。即使在浏览器之间整个像素对齐已经很困难了。 - SpliFF
更好的问题和答案的副本,不幸的是被标记为此问题的重复:https://dev59.com/3mYr5IYBdhLWcg3wLXSh - feeela
@feeela,不是的,这个先出现了。你发送链接的那个是2012年12月,而这个是2011年4月。但感谢您指出另一个是重复的。 - user17585064
17个回答

10

编辑:我忽略了IE6的限制,但我将答案留在这里供他人参考...

可以使用transform:scale(0.5),并在内部放置一个具有border:1px;的边框元素来实现。因此,您会得到一条半像素的边框(虽然是受欺骗和依赖于浏览器),但它会显示在屏幕上。但我用这个技巧来打印。

当然,您必须调整元素的内容或玩弄position

.outer {
  border:1px solid green;
}

.halfpix {
  -ms-transform-origin: 0 0;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  -ms-transform:scale(0.5);
  -webkit-transform:scale(0.5);
  transform:scale(0.5);
  width:200px;
  height:100px;
  border:1px solid black;
  }
<div class="outer">
 
  <div class="halfpix">
    </div>
  zoom browser window if your browser does not display 
  </div>


2
这是唯一一个回答了问题的答案。谢谢! - tomekwi
你也可以使用 scaleX(0.5)scaleY(0.5) 来仅在一个维度上进行缩放,非常好的答案! - M3RS

10

我认为你可以使用像em这样的单位定义边框的宽度,这将小于1像素,并且是有效的。然而,就像Will Martin所说的那样,出于显示目的,它会将其四舍五入到整个像素。


没错,你说的 em 单位在某些情况下会被解析成部分像素。我忘记了这一点。 - Will Martin
在绘制多个像素的“1px”线条的高清屏幕上,使用em技巧是否有效以获得更细的线条? - Thomas Ahle
非常晚了,但是没错,它应该可以! - crimson_penguin
这在任何浏览器上都不会产生与等效的“px”单位不同的结果。 - Adam Leggett

4
我不确定IE8-10的情况(IE6-7肯定不行),但在Chrome和FF中,使用box-shadow可以得到最细的边框。最好使用1px<hr>而不是自动生成的2px,但也可用于边框。
HR上的细边框在FF中比Chrome更明显,但Chrome也会呈现2px。 http://jsfiddle.net/GijsjanB/3G28N/
.thin {
    border: 1px solid white;
    box-shadow: 0 0 1px black;
}

2

不行。因为像素是显示器的基本单位,所以你不能显示小于一个像素的大小。而且,我所知道的任何浏览器都不允许您指定子像素宽度。它们只会被四舍五入到1px或向下取整到0px。


7
随着现代分辨率的提升,这个说法已经不再正确。显示器可以呈现亚像素精度的显示物品,许多字体实际上需要这样才能在视网膜显示屏上显示得好看。 - Bjorn
对于打印而言,Chrome 52存在一个问题——它忽略了(可能对其来说无法知晓的)打印机像素,并使用1px = 1/72in作为最细线条。尝试过分数像素、英寸、ems等方式,但都无法创建比1/72in更细的线条,即使在打印媒体查询中也是如此。虽然很想尝试使用图像,但我怀疑我只能接受这些粗线条的规则。 - Roger Krueger

2

虽然目前在IE或Edge的任何版本中都不可能实现,但在最新版本的Firefox和Chrome中,您现在可以使用小于1px的边框宽度值。

.borderTest {
 box-sizing: border-box;
 display: block;
 margin: 0.5em;
 padding: 0.5em;
 width: calc( 100% - 1em );
}
.borderTest:nth-child(1){
 border: 1px solid #000
}
.borderTest:nth-child(2){
 border: 0.75px solid #000
}
.borderTest:nth-child(3){
 border: 0.5px solid #000
}
.borderTest:nth-child(4){
 border: 0.25px solid #000
}
<div class="borderTest">1px</div>
<div class="borderTest">0.75px</div>
<div class="borderTest">0.5px</div>
<div class="borderTest">0.25px</div>

这在UHD屏幕上的输出如下所示:

输入图像描述


谢谢您指出这一点!顺便提一下,如果有人在Chrome/FF和IE中遇到不同的边框计算问题,请注意这一点。 - Olga Gnatenko
所有在Chrome 62 macOS 10.13上(视网膜显示器@2x)看起来都一样。不过使用“box-shadow”技巧可以解决问题。 - frosty

1
为了在高DPI/@2x/Retina显示屏上呈现本地1像素边框,有一些技巧。
在Firefox和Safari(macOS和iOS)上,使用0.5像素边框:
/* Fallback: Most browsers now render 0.5px as 1px though */
.el {
  border: 1px solid red;
}
.retina .el {
  border: 0.5px solid red;
}

在Chrome中,使用0.5px的扩展的box-shadow:
.retina-chrome .el {
  box-shadow: 0 0 0 0.5px red;
}

使用JS为HTML元素添加类,以仅针对@2x+显示器进行目标定位。
if (window.devicePixelRatio >= 2) {
  document.documentElement.classList.add(
    window.chrome ? 'retina-chrome' : 'retina'
  );
}

对于@1x的显示屏,使用稍浅的颜色1像素边框。


1

编辑:Chrome 98(2022年2月1日)直接支持小于1px的border-width值。

截至2020年中期,当前版本的Safari和Firefox都支持border-width: .5px

另一方面,Chrome将其视为1px

您可以使用类似以下代码检测浏览器是否支持:

var el = document.createElement('div');
el.style.position = 'fixed';
el.style.borderTop = '.5px solid';
document.body.appendChild(el);
var hasSubpixelBorder = el.getBoundingRect().height < 1;
document.body.removeChild(el);

如果您在启动时进行此操作,请确保在创建document.body之后调用。

如果不支持此操作(例如Chrome),则可以向document.body或某个父元素添加类,以使后代元素采用不同的边框样式:

@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
    .noSubpixelBorder .border-top {
        border-top-width: 0;
        background-image: linear-gradient(180deg, var(--mycolor) 0, var(--mycolor) .5px, transparent 0);
    }
}
@media (-webkit-min-device-pixel-ratio: 3) and (-webkit-max-device-pixel-ratio: 3.5), (min-resolution: 3dppx) and (max-resolution: 3.5dppx) {
    .noSubpixelBorder .border-top {
        background-image: linear-gradient(180deg, var(--mycolor) 0, var(--mycolor) .333333px, transparent 0);
    }
}

你可以使用多个线性渐变来实现多边框。这会覆盖background-image,因此如果你将其用于其他用途,则需要找到另一种方法(还有几种方法)。
这不是特别干净的方法,但它似乎始终有效。
如果你想要非常巧妙,你可以通过动态计算样式表来支持奇怪的像素比率。

1
你可以将该行转换为:

你可以像这样转换该行:

.thin{ -ms-transform:scale(1, 0.5); -webkit-transform:scale(1, 0.5); transform:scale(1, 0.5);}

或者,如果线是垂直的。
.thin{ -ms-transform:scale(0.5, 1); -webkit-transform:scale(0.5, 1); transform:scale(0.5, 1);}

1
尝试添加一个box-shadow。
box-shadow: 0px 0px 1px 0px black;

0

尝试

 border-top: 1px solid #c9d6df;

小于

 border: 1px solid #c9d6df;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接