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)
Ответы
Ответ 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;
}
хотя это не будет реагировать.