2

I have a textarea that I want to expand to full screen and animate some aspects of that transition. Here's the markup:

<div class="wrapper">
    <textarea>This is a sample text</textarea>
    <div class="full-screen-button">x</div>
</div>

The actual animation is too complex, so to demonstrate the issue I just took font-size as an example.

.wrapper > textarea {
    font-size: 1em;
    transition: font-size 1s linear;
}

The full-screen effect is achieved by this class:

.wrapper.full-screen,
.wrapper.full-screen > textarea {
    position: fixed!important;
    left: 0!important;
    top: 0!important;
    width: 100%!important;
    height: 100%!important;
    margin: 0!important;
    border: 0!important;
    resize: none!important;
    outline: none!important;
    font-size: 3em;
}

Full screen function is working fine, but the animation is not working for no clear reason.

If I remove the .wrapper element or disable the position: fixed style, the animation magically begins to work again. However I need both of those things, so I can't just get rid of them. Why does either affects animation is beyond me.

Full working sample: https://jsfiddle.net/bypvfveh/3/

Ilia G
  • 10,043
  • 2
  • 40
  • 59

1 Answers1

1

This is Chrome specific problem. If you try it in Firefox you will find it works. For an explination see this answer https://stackoverflow.com/a/37953806 (and give him an upvote ;) ).

Quick and easy solution for your case is to break your class changes into two parts.

  1. Change the element from relative to fixed
  2. Update the remaining properties like width/height/etc...

I've updated a version of your fiddle to show this. I've sperated your full-screen class into full-screen and fixed-position. Furthermore I've put a 100ms delay on changing size properties to seperate this function from the position property change.

$("textarea").on("dblclick", function() {
    //get reference to the element as it will be overided in timeout function
    var self = this;
    
    //use timeout function so full screen class is added after fixed mode
    setTimeout(function(){
         $(self.parentNode).toggleClass("full-screen");
    }, 100);
    
    //make element fixed
    $(this.parentNode).toggleClass("fixed-mode");
});

$(".full-screen-button").on("click", function() {
    //get reference to the element as it will be overided in timeout function
    var self = this;
    
    //use timeout function so full screen class is added after fixed mode
    setTimeout(function(){
         $(self.parentNode).toggleClass("full-screen");
    }, 100);
    
    //make element fixed
    $(this.parentNode).toggleClass("fixed-mode");
});
body {
  padding: 0;
  margin: 0;
}
.wrapper {
 /* wrapper is needed to trace textarea's size, to position the button */
    display: inline-block;
    position: relative;
    top: 0;
    left: 0;
}

.wrapper > textarea {
    font-size: 1em;
    /* purposefully ugly animation to make a point */
    transition: font-size 1s linear;
}

.wrapper > .full-screen-button {
    position: absolute;
    bottom: 2px;
    left: 2px;
    cursor: pointer;
}

.fixed-mode {
  position: fixed!important;
  left: 0!important;
  top: 0!important;
}

.wrapper.full-screen,
.wrapper.full-screen > textarea {
    width: 100%!important;
    height: 100%!important;
    margin: 0!important;
    border: 0!important;
    resize: none!important;
    outline: none!important;
    font-size: 3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
    <textarea>This is a sample text</textarea>
    <div class="full-screen-button">x</div>
</div>
Jack Dalton
  • 3,536
  • 5
  • 23
  • 40