子像素在浏览器中的计算和渲染方式有所不同 [英] Sub-Pixels calculated and rendered differently among browsers

查看:146
本文介绍了子像素在浏览器中的计算和渲染方式有所不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与此类似的代码上创建一个组件,其中输入字段具有嵌入式按钮:

I am working on a code similar to this to create a component where an input field has an embedded button:

http://codepen.io/anon/pen/pgwbWG?editors=110

如您所见,按钮的位置绝对是top,并且bottom设置为0,以实现高度为100%的元素.

As you can see, the button is positioned absolutely with top and bottom set to 0, to achieve a 100% height element.

还要注意的是,文本输入的边框必须保持可见,并且还包裹按钮. 为此,我在 button 中添加了margin: 1px,以便(应该)有空间显示周围的 text-input 红色边框(通常在输入字段时内容无效).

Also to note is that the border of the text-input must stay visible and also wrap the button. To achieve this I added a margin: 1px to the button so that there is (should be) space to display the surrounding text-input red border (usually when the input field content is invalid).

是在Firefox上(大部分)正确渲染,而在Chrome上(显然在最新的Safari上),它在按钮底部有一个 1px的间距.

is that on Firefox it is (mostly) rendered correctly, while on Chrome (and apparently on the newest Safari) it will have a 1px gap at the bottom of the button.

CSS似乎还可以,但是这似乎是渲染中的计算/舍入问题,其中按钮的底部或顶部边距并不是真正的1px(可以检查元素). 输入的填充似乎也会对此产生影响.

CSS seems ok but it appears to be a calculation/rounding problem in the rendering, where the bottom or the top margin of the button are not really 1px (can see it inspecting the element). And also the padding of the input seems to influence in that.

在不同的缩放比例下,它将在按钮的顶部或底部添加或删除1px的边距,从而导致1px的间隔或覆盖边框 strong>.

At different zoom-rates it will add or remove 1px of margin to the top or the bottom of the button, resulting in a 1px-gap or in a covered-border.

当我将 button 边距设置为0px时,底部边距是固定的,但是我松开顶部的1px边距,结束了 text-input的红色边框的覆盖. .

As I set the button margin to 0px then the bottom margin is fixed but I loose the 1px margin on the top, finishing to cover the red border of the text-input.

可能我在解释它时不清楚或太冗长,因此这里是一些错误的屏幕快照,它们来自Chrome的不同缩放(请注意CSS始终是相同的):

Probably I am not clear or too verbose in explaining it, so here are some screenshots of the bug, from different zooms on Chrome (note the CSS is always the same):

我找不到跨浏览器解决方案. 如何处理并获得一致的组件? (请不要使用Javascript)

I was not able to find a cross-browser solution. How to deal with it and get a consistent component? (no Javascript please)

推荐答案

您已经知道,问题出在浏览器之间使用不同的子像素演算方法

As you already know, the problem arises from a different approach to subpixel calculus between browsers

例如,在Chrome中,边框的大小可以为小数,但是页边距的处理方式不同(整数).

In Chrome, for instance, borders can have a fractional size, but margins are handled different (as integers).

我没有来自Chrome团队的文档,但这可以在开发工具中看到:

I don't have documentation about it from the Chrome team, but it's what can be seen in dev tools:

AFAIK,无法更改它.

AFAIK, there is not a way to change that.

相反,您可以将按钮中的边距的使用转移到边框上.

Instead, you can transfer the use of the margin in the button to a border.

由于您需要获得输入1px边框的空间,因此请在按钮中进行相同的操作,设置1px边框(而不是边距),然后将其设置为透明.

Since you need to get space for the 1px border of the input, do the same in the button, set a 1px border (instead of a margin), and set it transparent.

剩下的技巧是将background-clip属性设置为padding box,以便此透明度不受背景影响

The remaining trick is to set the background-clip property to padding box, so that this transparency is not affected by the background

Chrome浏览器中还有另一个错误,当缩放浏览器时,以em表示的填充在这种精度级别上并不可靠.我在代码段中对此进行了更改.

There is another bug in Chrome, the padding expressed in em is not reliable at this level of precision when the browser is zoomed. I changed this in the snippet.

由于我们使用边框按钮来确定尺寸,因此我们可以使用嵌入阴影代替边框的样式.

Since we are using the border button to get the dimension ok, we can style the border using instead a inset shadow.

* {
  margin: 0; padding: 0; box-sizing: border-box;
}
button, input, wrapper {
  display: inline-block; border-radius: 3px;
}

.wrapper {
  position: relative;
  
  width: 60%;
  margin: 1em;
  background-color: #ccc;
}

input {
  border: 1px solid red;
  width: 100%;
  
  background-color: limegreen;
  line-height: 3em;
/*  padding: 0.75em; */
  padding: 10px;
}

button {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  border: 1px solid transparent;
  width: 7em;
  margin: 0px;
  background-clip: padding-box;
  box-shadow:  inset 0px 0px 0px 2px  black;
}

<div class="wrapper">
  <input type="text">
  <button>Test</button>
</div>

另一个示例,其中按钮具有边框.但是我们需要一个包装器来确定尺寸.

Another example, where the button has a border. But we need a wrapper around it to get the dimensions ok.

* {
  margin: 0; padding: 0; box-sizing: border-box;
}
button, input, wrapper {
  display: inline-block; border-radius: 3px;
}

.wrapper {
  position: relative;
  
  width: 60%;
  margin: 1em;
  background-color: #ccc;
}

input {
  border: 1px solid red;
  width: 100%;
  
  background-color: limegreen;
  line-height: 3em;
/*  padding: 0.75em; */
  padding: 10px;
}

.buttonwrap {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  border: 1px solid transparent;
  width: 7em;
  margin: 0px;
  background-clip: padding-box;
}
button {
  position: absolute;
  right: 0px;
  top: 0;
  bottom: 0;
  width: 100%;
  border: 2px solid blue;
  margin: 0px;
}

<div class="wrapper">
  <input type="text">
  <div class="buttonwrap">
      <button>Test</button>
  </div>
</div>

这篇关于子像素在浏览器中的计算和渲染方式有所不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆