Элементы с дробной высотой рендерятся по разному

Дано: Hamburger из трех ровных линий, где линии состоят из (::before + div + ::after) Правила заданы одинаковые, за исключением отступ margin-top для (div + ::after).

Проблема: Высота div - меньше на пиксель, чем ::before и ::after. НО! Это только при определенных размера экрана. Так как высота строится от rem, который в свою очередь меняется от размера экрана.

Решение: Так как px иногда генерируются дробными, то в этом и есть вся проблема, также изменения margin иногда дает результат. Но интересно, почему линии генерируются так не по одному алгоритму. Возможно есть способ без медия, исправить эту не справедливость. В данный момент это не большая проблема, но не первый раз подобная проблема.

P.S.: Проблема встречается на webkit. Высота родителя не ограничена

.header-hamburger {
  cursor: pointer;
  width: 1.5rem;
  background: none;
  border: 0;
  padding: 0;
  position: relative;
  z-index: 9999;

  & > *, &::after, &::before {
    border-radius: 3px;
    height: .1rem;
    background: $white;
    transition: all .3s;
    position: relative;
    display: block;
  }

  & > *, &::after {
    margin-top:  0.4rem;
  }

  &::before, &::after {
    content: '';
  }
}

Ответы (1 шт):

Автор решения: Vadizar

Высота с дробным значением

Браузеры по разному округляют размеры с дробными числами – этой проблеме уже не первый год. Хотя это даже не проблема, а нормальное поведение – нельзя "закрасить" половину пикселя или же его треть. В таком случае браузер для себя округляет значение и отрисовывает уже его – отличаются лишь алгоритмы.

Более того, даже выравнивание элемента с нечетной высотой через display: flex и align-items: center в разных браузерах будет иметь разный эффект – опять таки из-за округления в большую или меньшую сторону.

Как работает REM

Есть несколько правил, которые помогут вам понять работу rem:

  • rem всегда относителен размеру шрифта корневого элемента – то есть к тегу html. Если размер шрифта html элемента равен 16px, то 1rem = 16px, тогда как .1rem = 1.6px.
  • rem будет ВСЕГДА относителен корневому элементу, не полагаясь на вложенные элементы.

Таким образом, rem работает так: число, заданное в rem, умножается на font-size корневого элемента, а полученное значение отрисовывается браузером в px.

Как решить вашу проблему

Что касается вашей проблемы, её исправить можно двумя способами:

  1. использовать фиксированные величины в px;
  2. в rem указывать лишь те значения, которые при умножении на font-size корневого элемента будут выдавать целые числа.
→ Ссылка