不同浏览器计算和渲染的子像素不同
Sub-Pixels calculated and rendered differently among browsers
目的:
我正在编写与此类似的代码来创建一个 组件,其中输入字段具有嵌入式按钮:
http://codepen.io/anon/pen/pgwbWG?editors=110
如你所见,按钮是绝对定位的,top
和bottom
设置为0
,达到100%高度元素。
还要注意 text-input 的边框必须保持可见,并且还要包裹 button。
为了实现这一点,我在 按钮 中添加了一个 margin: 1px
以便有(应该) space 显示周围的 text-input红色边框(一般是输入框内容无效时)。
问题:
是在 Firefox 上它(大部分)呈现正确,而在 Chrome 上(显然在最新的 Safari 上)它将在 [= 底部有一个 1px 的间隙50=]按钮.
CSS 看起来不错,但它似乎是渲染中的 calculation/rounding 问题,按钮的底部或顶部边距不是真正的 1px(可以看到它检查元素) .
而且输入的填充似乎也影响了这一点。
在不同的缩放率下,它将在 按钮 的顶部或底部添加或删除 1px 的边距,从而导致 1px 的间隙或在覆盖边界.
当我将 按钮 边距设置为 0px
时,底部边距是固定的,但我松开了顶部的 1px 边距,完成以覆盖红色边框文本输入.
例子:
可能我解释的不是很清楚或太冗长,所以这里有一些错误的截图,来自 Chrome 的不同缩放(注意 CSS 总是相同的):
解决方法:
我找不到跨浏览器解决方案。
如何处理它并获得一致的组件?
(请不要Javascript)
如您所知,问题是由浏览器之间的亚像素计算方法不同引起的
例如,在 Chrome 中,边框的大小可以是小数,但页边距的处理方式不同(作为整数)。
Chrome 团队没有关于它的文档,但可以在开发工具中看到:
据我所知,没有办法改变它。
相反,您可以将按钮中边距的使用转移到边框。
由于input的1px边框需要得到space,所以在按钮中做同样的事情,设置一个1px的边框(而不是外边距),并设置为透明。
剩下的技巧是将background-clip 属性设置为填充框,这样透明度就不受背景影响了
Chrome 中还有另一个错误,当浏览器缩放时,以 em 表示的填充在此精度级别上不可靠。我在代码段中更改了它。
由于我们使用边框按钮来确定尺寸,我们可以使用内嵌阴影来设置边框样式。
* {
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>
另一个例子,按钮 有 边框。但是我们需要一个包装器来确定尺寸。
* {
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>
使用 http://autoprefixer.github.io/ 获得显示所需的跨浏览器支持:flex;
button, input, wrapper {
display: inline-block; <----- Remove "display: inline-block;"
border-radius: 3px;
}
.wrapper {
position: relative;
display: -webkit-box;<----- Add "display: flex;"
display: -webkit-flex;<----- Add "display: flex;"
display: -ms-flexbox;<----- Add "display: flex;"
display: flex;<----- Add "display: flex;"
width: 60%;
margin: 1em;
background-color: #ccc;
}
额外的阅读和学习material:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/
http://www.sketchingwithcss.com/samplechapter/cheatsheet.html
注意:要覆盖 flex 规则,您将需要使用 flex shorthand 而不是特定的 over-ride,因为当前的浏览器存在缺陷,例如。
.item {
flex: 0 0 300px;
}
/* overide for some reason */
.item {
flex: 1 0 300px;
}
/* NOT */
.item {
flex-grow: 1;
}
您可能需要为 ie11 做一个 over-ride:
.ie11std .wrapper {
display:table;
}
.ie11std .item {
display:table-cell;
}
虽然这不会响应。
目的:
我正在编写与此类似的代码来创建一个 组件,其中输入字段具有嵌入式按钮:
http://codepen.io/anon/pen/pgwbWG?editors=110
如你所见,按钮是绝对定位的,top
和bottom
设置为0
,达到100%高度元素。
还要注意 text-input 的边框必须保持可见,并且还要包裹 button。
为了实现这一点,我在 按钮 中添加了一个 margin: 1px
以便有(应该) space 显示周围的 text-input红色边框(一般是输入框内容无效时)。
问题:
是在 Firefox 上它(大部分)呈现正确,而在 Chrome 上(显然在最新的 Safari 上)它将在 [= 底部有一个 1px 的间隙50=]按钮.
CSS 看起来不错,但它似乎是渲染中的 calculation/rounding 问题,按钮的底部或顶部边距不是真正的 1px(可以看到它检查元素) . 而且输入的填充似乎也影响了这一点。
在不同的缩放率下,它将在 按钮 的顶部或底部添加或删除 1px 的边距,从而导致 1px 的间隙或在覆盖边界.
当我将 按钮 边距设置为 0px
时,底部边距是固定的,但我松开了顶部的 1px 边距,完成以覆盖红色边框文本输入.
例子:
可能我解释的不是很清楚或太冗长,所以这里有一些错误的截图,来自 Chrome 的不同缩放(注意 CSS 总是相同的):
解决方法:
我找不到跨浏览器解决方案。 如何处理它并获得一致的组件? (请不要Javascript)
如您所知,问题是由浏览器之间的亚像素计算方法不同引起的
例如,在 Chrome 中,边框的大小可以是小数,但页边距的处理方式不同(作为整数)。
Chrome 团队没有关于它的文档,但可以在开发工具中看到:
据我所知,没有办法改变它。
相反,您可以将按钮中边距的使用转移到边框。
由于input的1px边框需要得到space,所以在按钮中做同样的事情,设置一个1px的边框(而不是外边距),并设置为透明。
剩下的技巧是将background-clip 属性设置为填充框,这样透明度就不受背景影响了
Chrome 中还有另一个错误,当浏览器缩放时,以 em 表示的填充在此精度级别上不可靠。我在代码段中更改了它。
由于我们使用边框按钮来确定尺寸,我们可以使用内嵌阴影来设置边框样式。
* {
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>
另一个例子,按钮 有 边框。但是我们需要一个包装器来确定尺寸。
* {
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>
使用 http://autoprefixer.github.io/ 获得显示所需的跨浏览器支持:flex;
button, input, wrapper {
display: inline-block; <----- Remove "display: inline-block;"
border-radius: 3px;
}
.wrapper {
position: relative;
display: -webkit-box;<----- Add "display: flex;"
display: -webkit-flex;<----- Add "display: flex;"
display: -ms-flexbox;<----- Add "display: flex;"
display: flex;<----- Add "display: flex;"
width: 60%;
margin: 1em;
background-color: #ccc;
}
额外的阅读和学习material:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/
http://www.sketchingwithcss.com/samplechapter/cheatsheet.html
注意:要覆盖 flex 规则,您将需要使用 flex shorthand 而不是特定的 over-ride,因为当前的浏览器存在缺陷,例如。
.item {
flex: 0 0 300px;
}
/* overide for some reason */
.item {
flex: 1 0 300px;
}
/* NOT */
.item {
flex-grow: 1;
}
您可能需要为 ie11 做一个 over-ride:
.ie11std .wrapper {
display:table;
}
.ie11std .item {
display:table-cell;
}
虽然这不会响应。