Search code examples
csscss-animationstranslate-animation

CSS translate animation side effects


I am trying to position my dialogue in middle of screen. I don't know height or width of dialogue (and new elements may be added later by JS). Size of dialogue must depend on it's content.

I used transform: translate(-50%, -50%); with top: 50%; and left: 50%; and it does it's job, but also on some dialogue heights has a side effect that appears differently on different browsers:

  • Firefox - Dialogue bottom border disappears (Can be seen on test on browser, but not on jsfiddle). Extra pixel below select arrow. Label background is one pixel above the border.
  • Chrome - Borders are 2 pixel wide and blurred.
  • Explorer 11 - Label height increases by 1px.

Please help me to negate this side effect.

This side effect can be seen in example below. By changing dialogue element height by 1px up or down, effect disappears.

JSfiddle Demo

.radio label {
  padding: 4px 11px;
  border: 1px solid #000;
}
.radio label.checked {
  background-color: #0275b8;
}
select {
  border: 1px solid #000;
  margin-bottom:20px;
}
.dialogue {
  padding: 10px;
  border: 1px solid #000;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<div class="dialogue" style="height:71px;">
  <select>
    <option>Option 1</option>
  </select>
  <div class="radio">
    <label class="checked">Option 1</label><label>Option 2</label>
  </div>
</div>


Solution

  • It seems to be the problem with rounding of float width and height for dialogue. On odd height numbers no rounding is required - everything is nice. On even height numbers result height is x.5px, that seems to be processed differently in different browsers.

    To solve such it was decided to position dialogue with JS, by using MutationObserver functionality. On load and whenever MutationObserver finds a change in HTML, JS calls the following function:

    jQuery('.dialogue').css({
        'left': Math.round((jQuery(window).width() - jQuery('.dialogue').width()) / 2) + 'px',
        'top': Math.round((jQuery(window).height() - jQuery('.dialogue').height()) / 2) + 'px'
    });