css css3 cross-browser rendering subpixel

css - Subpíxeles calculados y representados de manera diferente entre los navegadores



css3 cross-browser (2)

El propósito:

Estoy trabajando en un código similar a este para crear un componente donde un campo de entrada tiene un botón incrustado :

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

Como puede ver, el botón se posiciona absolutamente con la top e bottom configurada en 0 , para lograr un elemento de altura del 100%.

También hay que tener en cuenta que el borde de la entrada de texto debe permanecer visible y también envolver el botón . Para lograr esto, agregué un margin: 1px al botón para que haya (debería haber) espacio para mostrar el borde rojo de entrada de texto circundante (generalmente cuando el contenido del campo de entrada no es válido).

El problema:

es que en Firefox se representa (principalmente) correctamente, mientras que en Chrome (y aparentemente en el Safari más nuevo) tendrá un espacio de 1px en la parte inferior del botón .

CSS parece estar bien, pero parece ser un problema de cálculo / redondeo en el renderizado, donde el margen inferior o superior del botón no son realmente 1px (puede verlo inspeccionando el elemento). Y también el relleno de la entrada parece influir en eso.

A diferentes velocidades de zoom, agregará o eliminará 1px de margen en la parte superior o inferior del botón , lo que dará como resultado un espacio de 1px o un borde cubierto .

Cuando configuro el margen del botón en 0px , el margen inferior está fijo pero 0px el margen de 1px en la parte superior, terminando para cubrir el borde rojo de la entrada de texto .

Los ejemplos:

Probablemente no estoy claro o demasiado detallado al explicarlo, así que aquí hay algunas capturas de pantalla del error, desde diferentes zooms en Chrome (tenga en cuenta que el CSS siempre es el mismo):

La solución:

No pude encontrar una solución de navegador cruzado . ¿Cómo lidiar con eso y obtener un componente consistente? (sin Javascript por favor)


Como ya sabe, el problema surge de un enfoque diferente del cálculo de subpíxeles entre navegadores

En Chrome, por ejemplo, los bordes pueden tener un tamaño fraccional, pero los márgenes se manejan de manera diferente (como enteros).

No tengo documentación al respecto del equipo de Chrome, pero es lo que se puede ver en las herramientas de desarrollo:

AFAIK, no hay forma de cambiar eso.

En cambio, puede transferir el uso del margen en el botón a un borde.

Dado que necesita obtener espacio para el borde de 1px de la entrada, haga lo mismo en el botón, establezca un borde de 1px (en lugar de un margen) y hágalo transparente.

El truco restante es establecer la propiedad de clip de fondo en el cuadro de relleno, para que esta transparencia no se vea afectada por el fondo.

Hay otro error en Chrome, el relleno expresado en em no es confiable en este nivel de precisión cuando se hace zoom en el navegador. Cambié esto en el fragmento.

Como estamos usando el botón de borde para obtener la dimensión correcta, podemos diseñar el borde usando en su lugar una sombra insertada.

* { 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>

Otro ejemplo, donde el botón tiene un borde. Pero necesitamos un envoltorio alrededor para obtener las dimensiones correctas.

* { 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>


Use http://autoprefixer.github.io/ para obtener el soporte de navegador cruzado que necesita para mostrar: 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 adicional de lectura y aprendizaje:

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

http://flexbox.io/#/

https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/

http://www.sketchingwithcss.com/samplechapter/cheatsheet.html

Nota: para anular una regla de flexión, deberá utilizar la taquigrafía flexible en lugar de la anulación específica debido a las deficiencias actuales del navegador, por ejemplo.

.item { flex: 0 0 300px; } /* overide for some reason */ .item { flex: 1 0 300px; } /* NOT */ .item { flex-grow: 1; }

PUEDE necesitar hacer un over-ride para ie11:

.ie11std .wrapper { display:table; } .ie11std .item { display:table-cell; }

aunque esto no responderá.