Подтвердить что ты не робот

Sub-Pixels вычисляются и отображаются по-разному среди браузеров

Цель:

Я работаю над кодом, подобным этому, чтобы создать компонент , где поле ввода имеет встроенную кнопку:

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

Как вы можете видеть, кнопка позиционируется абсолютно с top и bottom, установленными на 0, для достижения 100% -ного элемента высоты.

Также следует отметить, что граница ввода текста должна оставаться видимой и также обернуть кнопку. Для этого я добавил кнопку margin: 1px к кнопке, чтобы было (должно быть) пространство для отображения внешней границы ввода текста с красным цветом (обычно, когда содержимое поля ввода недействительно).

Проблема:

заключается в том, что в Firefox он (в основном) отображается правильно, а в Chrome (и, по-видимому, на новейшем Safari) он будет иметь 1px зазор в нижней части кнопки.

CSS выглядит нормально, но, похоже, это проблема вычисления/округления в рендеринге, где нижнее или верхнее поле кнопки не действительно 1px (можно увидеть, как он проверяет элемент). А также добавление входных данных влияет на это.

При разных значениях масштабирования он добавит или удалит 1px поля в верхнюю или нижнюю часть кнопки, в результате получится 1px-зазор или в закрытой рамке.

Когда я устанавливаю маркер кнопки 0px, то нижнее поле фиксируется, но я теряю край 1px сверху, заканчивая, чтобы покрыть красную границу текстового ввода.

Примеры:

Вероятно, я не ясен или слишком подробен в объяснении, так что вот несколько скриншотов ошибки, от разных масштабов в Chrome (обратите внимание, что CSS всегда один и тот же):

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

Решение:

Мне не удалось найти кросс-браузерное решение. Как справиться с этим и получить согласованный компонент? (без Javascript)

4b9b3361

Ответ 1

Как вы уже знаете, проблема возникает из-за другого подхода к исчислению субпикселей между браузерами

В Chrome, например, границы могут иметь дробный размер, но поля обрабатываются разными (как целые числа).

У меня нет документации об этом из команды Chrome, но это то, что можно увидеть в инструментах dev:

dev tools capture

AFAIK, нет способа изменить это.

Вместо этого вы можете перенести использование поля в кнопку на границу.

Так как вам нужно получить место для 1px границы ввода, сделайте то же самое в кнопке, установите границу 1px (вместо поля) и установите ее прозрачно.

Оставшийся трюк заключается в том, чтобы установить свойство background-clip в поле отступов, так что на эту прозрачность не влияет фон

В Chrome есть еще одна ошибка, добавление, выраженное в em, не является надежным на этом уровне точности при увеличении браузера. Я изменил это в фрагменте.

Так как мы используем кнопку border, чтобы получить размер в порядке, мы можем пометить рамку, используя вместо нее тень вставки.

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

Ответ 2

Используйте 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;
}

Дополнительный материал для чтения и обучения:

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

Примечание. Чтобы преодолеть правило гибкости, вам нужно будет использовать сокращенную гибкость, а не конкретную чрезмерную езду из-за текущих недостатков браузера, например.

.item {
  flex: 0 0 300px;
}

/* overide for some reason */

.item {
  flex: 1 0 300px;
}

/* NOT */

.item {
  flex-grow: 1;
}

Вам может потребоваться переезд для ie11:

.ie11std .wrapper {
  display:table;
}

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

хотя это не будет реагировать.