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

Странное поведение ширины границы в Chrome - граница границы плавающей точки?

Некоторые модели жидкостей, особенно те, которые включают в себя% -width iFrames, по-видимому, вызывают некоторые странные ошибки округления в Chrome (у меня есть версия 21).

Эта сценария демонстрирует проблему. Установите для границы значение целочисленного пикселя, а значения, возвращаемые вами при запросе, - это числа с плавающей запятой, немного меньшие ожидаемого значения.

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

(Я также видел это поведение для основных атрибутов ширины и высоты, хотя мне не удалось воспроизвести эту часть проблемы в jsFiddle.)

Это не похоже на проблему в Firefox или в IE8.

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


Сюжет сгущается. В попытке обойти проблему, я обнаружил, что значения более 10 пикселей не подвержены этой проблеме.

Кроме того, на основе комментария @GionaF он работает правильно в Chrome 22.

4b9b3361

Ответ 1

Чтобы воспроизвести вашу проблему, мне нужно изменить уровень масштабирования Chrome. Изменение уровня масштабирования на 100% исправляет его. Кажется, это ошибка, вычисленная ширина границы всегда меньше, чем заданная ширина рамки, масштабирование или выход!

Ваша граница 10px дает значение 10, когда уровень масштабирования составляет 110%, но на 125% он имеет ту же проблему, что и ваша граница 3px.

edit: firefox имеет такое же поведение!

Ответ 2

Я не могу воспроизвести это поведение в Chrome в настоящее время, но это поведение, скорее всего, связано с Subpixel Rendering. По сути, Webkit будет выполнять вычисления с использованием целочисленной математики, чтобы избежать неточности с плавающей запятой.

Похоже, что в настоящее время border не использует подпиксельную визуализацию, которая может объяснить, почему проблема не отображается в новых версиях Chrome.

Ответ 3

Помогает ли установка размера окна в рамку для всех элементов? Это изменит способ вычисления модели ящика, где граница и отступы не будут влиять на ширину.

*,
*:before,
*:after {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box; }

Ответ 4

У меня также была проблема с границей в input и других элементах. После часа, проведенного, я нашел неожиданную причину для возникновения этой проблемы. Bootstrap css использует normalize css, и следующий код вызывает такую ​​проблему:

hr {
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;
    box-sizing: content-box;
}

Чтобы решить эту проблему, я переопределяю css в свой style.css:

hr {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

Правило hr действительно не связано с input, но оно работает. Это действительно неожиданное поведение, попробуйте и оно будет работать.

Ответ 5

У меня только что был другой пример этого с хромом (хромом 76), вызванным transform: translate().

<div class='container'>
    <div class="box-triangle"></div>
</div>

.box-triangle имеет элемент ::after, формирующий граничный треangularьник, который абсолютно расположен поверх .box-triangle (сразу после заполнения).
Если я установил перевод с% на .container, и полученный процент не является целым числом, тогда граница .box-triangle будет слегка отображаться под его элементом ::after.

Решения: используйте перевод пикселей вместо% или убедитесь, что процентное значение размера контейнера является целым числом

Редактировать: то же самое происходит, если преобразование применяется непосредственно к .box-triangle (см. последний пример во фрагменте)

* {
  box-sizing: border-box;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  min-height: 100vh;
  width: 100%;
  background-color: #e55039;
  font-size: 16px;
}

.box-triangle {
  position: relative;
  margin: 0;
  color: #f7f1e3;
  background-color: #227093;
  font-size: 20px;
  margin: 0;
  padding: 1em;
  border: 5px solid white;
}

.box-triangle::after {
  content: "";
  position: absolute;
  height: 0;
  width: 0;
  margin: 0;
  border: solid transparent;
  left: 50%;
  bottom: 100%;
  border-bottom-color: #227093;
  border-width: 1.5em;
  -webkit-transform: translate(-50%, 0);
  transform: translate(-50%, 0);
}

[class^='container'] {
  margin: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container-1 {
  position: relative;
  height: 10.5rem;
  width: 20rem;
  /* transform: translate(1%, 1%); */
}

.container-2 {
  position: relative;
  height: 10.5rem;
  width: 20rem;
  transform: translate(0, 5%);
}

.container-3 {
  position: relative;
  height: 10rem;
  width: 20rem;
  transform: translate(0, 5%);
}

.container-4 {
  position: relative;
  height: 168px;
  width: 320px;
  transform: translate(0, 5%);
}

.container-5 {
  position: relative;
  height: 168px;
  width: 320px;
  transform: translate(0, 8px);
}

.noContainer {
  position: relative;
  height: 168px;
  width: 320px;
  transform: translate(0, 5%);
}
<div class='container-1'>
  <div class="box-triangle">no translate + container height: 10.5 rem (168px)</div>
</div>

<div class='container-2'>
  <div class="box-triangle">translate(0, 5%) + container height: 10.5 rem (168px)</div>
</div>

<div class='container-3'>
  <div class="box-triangle">translate(0, 5%) + container height: 10rem (160px)</div>
</div>

<div class='container-4'>
  <div class="box-triangle">translate(0, 5%) + container height: 168px</div>
</div>

<div class='container-5'>
  <div class="box-triangle">translate(0, 8px) + container height: 168px</div>
</div>

<div class="box-triangle noContainer">No container + translate(0, 5%) + height: 168px</div>