浏览器将边界值截断为整数
Browsers truncate border values to integers
只要元素的边框使用了非整数像素值,浏览器就会将该值截断为整数。为什么会这样?
我知道边框 实际上 不会占据一个像素的一部分,但这些类型的值有时会与其他值结合使用以形成完整像素。例如,宽度为 1.6px 的左右边框应导致元素的总宽度增加 3px。这是有效的,因为 the full value is stored in memory and used for calculations.
但是,即使宽度、填充和边距都正确运行,渲染边框时似乎并非如此。
var div = document.getElementsByTagName('div'),
len = div.length,
style;
for (var i = 0; i < len; i++) {
style = getComputedStyle(div[i]);
div[i].innerHTML = div[i].className + ': ' + style.getPropertyValue(div[i].className) + '<br>height: ' + style.getPropertyValue('height');
}
div {
width: 300px;
border: 1px solid black;
padding: 50px 0;
text-align: center;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
div.width {
width: 300.6px;
}
div.padding-top {
padding-top: 50.6px;
}
div.margin-top {
margin-top: 0.6px;
}
div.border-top-width {
border-top-width: 1.6px;
}
<div class="width"></div>
<div class="padding-top"></div>
<div class="margin-top"></div>
<div class="border-top-width"></div>
测试时,代码始终产生相同的结果(不考虑精确度)。大多数主要浏览器(Chrome、Firefox、Opera)的行为都是一样的。例外情况是 Safari 5.1(它呈现的填充和边距类似于边框,但这可能只是由于版本)和 Internet Explorer(它正确计算了 border-top-width)。
宽度、填充和边距都被记住为十进制值,并允许填充相应地影响高度,但边框不是。它被截断为一个整数。为什么这只是案例宽度边框?是否有任何方法可以以更完整的形式记住边框值,以便可以使用 JavaScript?
检索元素的 true 高度
据我从几个简单的测试中可以看出,子像素边框宽度完全可以正常工作。我认为您示例中的错字("border-top-width" 与 "border-left-width")可能是造成差异的原因。这个例子对我来说按预期工作:
var div = document.getElementsByTagName("div");
for (var i = 0; i < div.length; i++)
{
div[i].innerHTML += getComputedStyle(div[i]).getPropertyValue("width");
}
DIV
{
width: 300px;
border: 1px solid black;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
DIV.subpixel
{
border-width: 1.23px;
}
<DIV>border-width: 1px<BR>width: </DIV>
<DIV CLASS="subpixel">border-width: 1.23px<BR>width: </DIV>
简单的解释是浏览器在内部使用整数作为边框宽度(或者至少公开公开它们)。
这方面的一个例子是 Chrome (Chromium) 的源代码,它在文件 ComputedStyle.h 中将所有边框宽度定义为整数 (line 508):
我们对此无能为力,至于 为什么 :W3C specification for CSS Backgrounds and Borders 中关于边框宽度的信息非常少。它只说明 line-width
,没有关于如何处理这个单位的单位、类型或定义,除非它是绝对的(非负数):
Value: <line-width>
[...]
Computed value: absolute length; ‘0’ if the border style is ‘none’ or ‘hidden’
并且:
The lengths corresponding to ‘thin’, ‘medium’ and ‘thick’ are not
specified, but the values are constant throughout a document and thin
≤ medium ≤ thick. A UA could, e.g., make the thickness depend on the
‘medium’ font size: one choice might be 1, 3 & 5px when the ‘medium’
font size is 17px or less. Negative values are not allowed.
找到相同的信息 in the box model document,没有新的详细信息。
由于 所有 值最终都以像素值结束(因为我们的屏幕是像素设备),因此数字来自 em,vw、% 等在不考虑子像素化的情况下,在边框宽度方面似乎最终是一个整数。
在使用整数作为边框宽度的浏览器中,甚至转换(缩放)似乎都不会影响这一点。
最终,如何处理这些值似乎取决于浏览器供应商(这样做可能只是出于审美原因,性能,..我们只能猜测..) .
只要元素的边框使用了非整数像素值,浏览器就会将该值截断为整数。为什么会这样?
我知道边框 实际上 不会占据一个像素的一部分,但这些类型的值有时会与其他值结合使用以形成完整像素。例如,宽度为 1.6px 的左右边框应导致元素的总宽度增加 3px。这是有效的,因为 the full value is stored in memory and used for calculations.
但是,即使宽度、填充和边距都正确运行,渲染边框时似乎并非如此。
var div = document.getElementsByTagName('div'),
len = div.length,
style;
for (var i = 0; i < len; i++) {
style = getComputedStyle(div[i]);
div[i].innerHTML = div[i].className + ': ' + style.getPropertyValue(div[i].className) + '<br>height: ' + style.getPropertyValue('height');
}
div {
width: 300px;
border: 1px solid black;
padding: 50px 0;
text-align: center;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
div.width {
width: 300.6px;
}
div.padding-top {
padding-top: 50.6px;
}
div.margin-top {
margin-top: 0.6px;
}
div.border-top-width {
border-top-width: 1.6px;
}
<div class="width"></div>
<div class="padding-top"></div>
<div class="margin-top"></div>
<div class="border-top-width"></div>
测试时,代码始终产生相同的结果(不考虑精确度)。大多数主要浏览器(Chrome、Firefox、Opera)的行为都是一样的。例外情况是 Safari 5.1(它呈现的填充和边距类似于边框,但这可能只是由于版本)和 Internet Explorer(它正确计算了 border-top-width)。
宽度、填充和边距都被记住为十进制值,并允许填充相应地影响高度,但边框不是。它被截断为一个整数。为什么这只是案例宽度边框?是否有任何方法可以以更完整的形式记住边框值,以便可以使用 JavaScript?
检索元素的 true 高度据我从几个简单的测试中可以看出,子像素边框宽度完全可以正常工作。我认为您示例中的错字("border-top-width" 与 "border-left-width")可能是造成差异的原因。这个例子对我来说按预期工作:
var div = document.getElementsByTagName("div");
for (var i = 0; i < div.length; i++)
{
div[i].innerHTML += getComputedStyle(div[i]).getPropertyValue("width");
}
DIV
{
width: 300px;
border: 1px solid black;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
DIV.subpixel
{
border-width: 1.23px;
}
<DIV>border-width: 1px<BR>width: </DIV>
<DIV CLASS="subpixel">border-width: 1.23px<BR>width: </DIV>
简单的解释是浏览器在内部使用整数作为边框宽度(或者至少公开公开它们)。
这方面的一个例子是 Chrome (Chromium) 的源代码,它在文件 ComputedStyle.h 中将所有边框宽度定义为整数 (line 508):
我们对此无能为力,至于 为什么 :W3C specification for CSS Backgrounds and Borders 中关于边框宽度的信息非常少。它只说明 line-width
,没有关于如何处理这个单位的单位、类型或定义,除非它是绝对的(非负数):
Value: <line-width>
[...]
Computed value: absolute length; ‘0’ if the border style is ‘none’ or ‘hidden’
并且:
The lengths corresponding to ‘thin’, ‘medium’ and ‘thick’ are not specified, but the values are constant throughout a document and thin ≤ medium ≤ thick. A UA could, e.g., make the thickness depend on the ‘medium’ font size: one choice might be 1, 3 & 5px when the ‘medium’ font size is 17px or less. Negative values are not allowed.
找到相同的信息 in the box model document,没有新的详细信息。
由于 所有 值最终都以像素值结束(因为我们的屏幕是像素设备),因此数字来自 em,vw、% 等在不考虑子像素化的情况下,在边框宽度方面似乎最终是一个整数。
在使用整数作为边框宽度的浏览器中,甚至转换(缩放)似乎都不会影响这一点。
最终,如何处理这些值似乎取决于浏览器供应商(这样做可能只是出于审美原因,性能,..我们只能猜测..) .