How can I make this transition smooth instead of it jumping up












3















I am trying to implement a notification system in my app without the use of a library. Here is a gif of the issue: https://imgur.com/oRc11dM



And here is the jsfiddle of the gif: https://jsfiddle.net/w9yk7n54/



When you click on new notification button, already displayed notifications jump up to make room for the new notification and new notification slides in. I was wondering how I could make it so that they all smoothly go up together.



The notifications wont all be the same dimensions so I cant set static values for height/etc.



Thank you!






let btn = document.querySelector('button')
let container = document.querySelector('.notifications-container')

let notif_contents = [
"<p>1</p><p>1</p><p>1</p><p>1</p>",
"<p>test</p>",
"<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
]
let current = 0

btn.onclick = () => {

let notif = document.createElement('div')
notif.classList.add('notif')
notif.innerHTML = notif_contents[current]
notif.addEventListener('animationend', () => {
notif.parentElement.removeChild(notif)
})
current++

container.append(notif)
}

* {
box-sizing: border-box;
}

.container {
height: 300px;
width: 400px;
border: 1px solid black;
position: absolute;
}

.notifications-container {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 200px;
background: rgba( 0, 0, 0, 0.2);
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: hidden;
}

.notif {
position: relative;
width: 100%;
padding: 10px;
border: 1px solid black;
animation: notifAnim 5s forwards;
transition: all .2s;
background: white;
}

button {
z-index: 100;
background: lightcoral;
color: white;
border: none;
padding: 10px;
font-size: 20px;
margin: 5px;
}

@keyframes notifAnim {
0% {
transform: translateY( 100%)
}
20% {
transform: translateY( 0)
}
80% {
transform: translateY( 0)
}
100% {
transform: translateY( 100%)
}
}

<div class="container">
<button>New Notification</button>
<div class="notifications-container"></div>
</div>












share|improve this question





























    3















    I am trying to implement a notification system in my app without the use of a library. Here is a gif of the issue: https://imgur.com/oRc11dM



    And here is the jsfiddle of the gif: https://jsfiddle.net/w9yk7n54/



    When you click on new notification button, already displayed notifications jump up to make room for the new notification and new notification slides in. I was wondering how I could make it so that they all smoothly go up together.



    The notifications wont all be the same dimensions so I cant set static values for height/etc.



    Thank you!






    let btn = document.querySelector('button')
    let container = document.querySelector('.notifications-container')

    let notif_contents = [
    "<p>1</p><p>1</p><p>1</p><p>1</p>",
    "<p>test</p>",
    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
    ]
    let current = 0

    btn.onclick = () => {

    let notif = document.createElement('div')
    notif.classList.add('notif')
    notif.innerHTML = notif_contents[current]
    notif.addEventListener('animationend', () => {
    notif.parentElement.removeChild(notif)
    })
    current++

    container.append(notif)
    }

    * {
    box-sizing: border-box;
    }

    .container {
    height: 300px;
    width: 400px;
    border: 1px solid black;
    position: absolute;
    }

    .notifications-container {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 200px;
    background: rgba( 0, 0, 0, 0.2);
    display: flex;
    flex-flow: column nowrap;
    justify-content: flex-end;
    overflow: hidden;
    }

    .notif {
    position: relative;
    width: 100%;
    padding: 10px;
    border: 1px solid black;
    animation: notifAnim 5s forwards;
    transition: all .2s;
    background: white;
    }

    button {
    z-index: 100;
    background: lightcoral;
    color: white;
    border: none;
    padding: 10px;
    font-size: 20px;
    margin: 5px;
    }

    @keyframes notifAnim {
    0% {
    transform: translateY( 100%)
    }
    20% {
    transform: translateY( 0)
    }
    80% {
    transform: translateY( 0)
    }
    100% {
    transform: translateY( 100%)
    }
    }

    <div class="container">
    <button>New Notification</button>
    <div class="notifications-container"></div>
    </div>












    share|improve this question



























      3












      3








      3








      I am trying to implement a notification system in my app without the use of a library. Here is a gif of the issue: https://imgur.com/oRc11dM



      And here is the jsfiddle of the gif: https://jsfiddle.net/w9yk7n54/



      When you click on new notification button, already displayed notifications jump up to make room for the new notification and new notification slides in. I was wondering how I could make it so that they all smoothly go up together.



      The notifications wont all be the same dimensions so I cant set static values for height/etc.



      Thank you!






      let btn = document.querySelector('button')
      let container = document.querySelector('.notifications-container')

      let notif_contents = [
      "<p>1</p><p>1</p><p>1</p><p>1</p>",
      "<p>test</p>",
      "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
      ]
      let current = 0

      btn.onclick = () => {

      let notif = document.createElement('div')
      notif.classList.add('notif')
      notif.innerHTML = notif_contents[current]
      notif.addEventListener('animationend', () => {
      notif.parentElement.removeChild(notif)
      })
      current++

      container.append(notif)
      }

      * {
      box-sizing: border-box;
      }

      .container {
      height: 300px;
      width: 400px;
      border: 1px solid black;
      position: absolute;
      }

      .notifications-container {
      position: absolute;
      top: 0;
      right: 0;
      height: 100%;
      width: 200px;
      background: rgba( 0, 0, 0, 0.2);
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-end;
      overflow: hidden;
      }

      .notif {
      position: relative;
      width: 100%;
      padding: 10px;
      border: 1px solid black;
      animation: notifAnim 5s forwards;
      transition: all .2s;
      background: white;
      }

      button {
      z-index: 100;
      background: lightcoral;
      color: white;
      border: none;
      padding: 10px;
      font-size: 20px;
      margin: 5px;
      }

      @keyframes notifAnim {
      0% {
      transform: translateY( 100%)
      }
      20% {
      transform: translateY( 0)
      }
      80% {
      transform: translateY( 0)
      }
      100% {
      transform: translateY( 100%)
      }
      }

      <div class="container">
      <button>New Notification</button>
      <div class="notifications-container"></div>
      </div>












      share|improve this question
















      I am trying to implement a notification system in my app without the use of a library. Here is a gif of the issue: https://imgur.com/oRc11dM



      And here is the jsfiddle of the gif: https://jsfiddle.net/w9yk7n54/



      When you click on new notification button, already displayed notifications jump up to make room for the new notification and new notification slides in. I was wondering how I could make it so that they all smoothly go up together.



      The notifications wont all be the same dimensions so I cant set static values for height/etc.



      Thank you!






      let btn = document.querySelector('button')
      let container = document.querySelector('.notifications-container')

      let notif_contents = [
      "<p>1</p><p>1</p><p>1</p><p>1</p>",
      "<p>test</p>",
      "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
      ]
      let current = 0

      btn.onclick = () => {

      let notif = document.createElement('div')
      notif.classList.add('notif')
      notif.innerHTML = notif_contents[current]
      notif.addEventListener('animationend', () => {
      notif.parentElement.removeChild(notif)
      })
      current++

      container.append(notif)
      }

      * {
      box-sizing: border-box;
      }

      .container {
      height: 300px;
      width: 400px;
      border: 1px solid black;
      position: absolute;
      }

      .notifications-container {
      position: absolute;
      top: 0;
      right: 0;
      height: 100%;
      width: 200px;
      background: rgba( 0, 0, 0, 0.2);
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-end;
      overflow: hidden;
      }

      .notif {
      position: relative;
      width: 100%;
      padding: 10px;
      border: 1px solid black;
      animation: notifAnim 5s forwards;
      transition: all .2s;
      background: white;
      }

      button {
      z-index: 100;
      background: lightcoral;
      color: white;
      border: none;
      padding: 10px;
      font-size: 20px;
      margin: 5px;
      }

      @keyframes notifAnim {
      0% {
      transform: translateY( 100%)
      }
      20% {
      transform: translateY( 0)
      }
      80% {
      transform: translateY( 0)
      }
      100% {
      transform: translateY( 100%)
      }
      }

      <div class="container">
      <button>New Notification</button>
      <div class="notifications-container"></div>
      </div>








      let btn = document.querySelector('button')
      let container = document.querySelector('.notifications-container')

      let notif_contents = [
      "<p>1</p><p>1</p><p>1</p><p>1</p>",
      "<p>test</p>",
      "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
      ]
      let current = 0

      btn.onclick = () => {

      let notif = document.createElement('div')
      notif.classList.add('notif')
      notif.innerHTML = notif_contents[current]
      notif.addEventListener('animationend', () => {
      notif.parentElement.removeChild(notif)
      })
      current++

      container.append(notif)
      }

      * {
      box-sizing: border-box;
      }

      .container {
      height: 300px;
      width: 400px;
      border: 1px solid black;
      position: absolute;
      }

      .notifications-container {
      position: absolute;
      top: 0;
      right: 0;
      height: 100%;
      width: 200px;
      background: rgba( 0, 0, 0, 0.2);
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-end;
      overflow: hidden;
      }

      .notif {
      position: relative;
      width: 100%;
      padding: 10px;
      border: 1px solid black;
      animation: notifAnim 5s forwards;
      transition: all .2s;
      background: white;
      }

      button {
      z-index: 100;
      background: lightcoral;
      color: white;
      border: none;
      padding: 10px;
      font-size: 20px;
      margin: 5px;
      }

      @keyframes notifAnim {
      0% {
      transform: translateY( 100%)
      }
      20% {
      transform: translateY( 0)
      }
      80% {
      transform: translateY( 0)
      }
      100% {
      transform: translateY( 100%)
      }
      }

      <div class="container">
      <button>New Notification</button>
      <div class="notifications-container"></div>
      </div>





      let btn = document.querySelector('button')
      let container = document.querySelector('.notifications-container')

      let notif_contents = [
      "<p>1</p><p>1</p><p>1</p><p>1</p>",
      "<p>test</p>",
      "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
      ]
      let current = 0

      btn.onclick = () => {

      let notif = document.createElement('div')
      notif.classList.add('notif')
      notif.innerHTML = notif_contents[current]
      notif.addEventListener('animationend', () => {
      notif.parentElement.removeChild(notif)
      })
      current++

      container.append(notif)
      }

      * {
      box-sizing: border-box;
      }

      .container {
      height: 300px;
      width: 400px;
      border: 1px solid black;
      position: absolute;
      }

      .notifications-container {
      position: absolute;
      top: 0;
      right: 0;
      height: 100%;
      width: 200px;
      background: rgba( 0, 0, 0, 0.2);
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-end;
      overflow: hidden;
      }

      .notif {
      position: relative;
      width: 100%;
      padding: 10px;
      border: 1px solid black;
      animation: notifAnim 5s forwards;
      transition: all .2s;
      background: white;
      }

      button {
      z-index: 100;
      background: lightcoral;
      color: white;
      border: none;
      padding: 10px;
      font-size: 20px;
      margin: 5px;
      }

      @keyframes notifAnim {
      0% {
      transform: translateY( 100%)
      }
      20% {
      transform: translateY( 0)
      }
      80% {
      transform: translateY( 0)
      }
      100% {
      transform: translateY( 100%)
      }
      }

      <div class="container">
      <button>New Notification</button>
      <div class="notifications-container"></div>
      </div>






      javascript css animation css-animations






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 23:20









      Andrei Gheorghiu

      35.6k74774




      35.6k74774










      asked Nov 14 '18 at 21:05









      SynSyn

      645




      645
























          2 Answers
          2






          active

          oldest

          votes


















          1














          Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.



          The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.



          Example:






          let btn = document.querySelector('button'),
          container = document.querySelector('.notifications-container'),
          notif_contents = [
          "<p>1</p><p>1</p><p>1</p><p>1</p>",
          "<p>test</p>",
          "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
          "<code>another.test()</code>",
          "<strong>another</strong> <i>test</i>"
          ]

          btn.onclick = () => {
          let notif = document.createElement('div'),
          index = Math.floor(Math.random() * notif_contents.length)
          notif.classList.add('notif')
          notif.innerHTML = notif_contents[index]
          notif.addEventListener('animationend', () => {
          notif.parentElement.removeChild(notif)
          })

          container.append(notif)
          notif.style.marginTop = '-' + notif.offsetHeight + 'px'
          }

          * {
          box-sizing: border-box;
          }

          .container {
          height: 300px;
          width: 400px;
          border: 1px solid #888;
          position: absolute;
          }

          .notifications-container {
          position: absolute;
          top: 0;
          right: 0;
          height: 100%;
          width: 200px;
          background: rgba( 0, 0, 0, 0.2);
          display: flex;
          flex-flow: column nowrap;
          justify-content: flex-end;
          overflow: hidden;
          }

          .notif {
          position: relative;
          width: 100%;
          padding: 10px;
          border: 1px solid #ddd;
          border-bottom: none;
          animation: notifAnim 5s forwards;
          background: white;
          }

          button {
          z-index: 100;
          background: lightcoral;
          color: white;
          border: none;
          padding: 10px;
          font-size: 20px;
          margin: 5px;
          }

          @keyframes notifAnim {
          0%,
          100% {
          transform: translateY( 100%)
          }
          20%,
          80% {
          transform: translateY( 0);
          margin-top: 0
          }
          }

          <div class="container">
          <button>New Notification</button>
          <div class="notifications-container"></div>
          </div>








          share|improve this answer

































            0














            An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:






            let btn = document.querySelector('button')
            let container = document.querySelector('.notifications-container')

            let notif_contents = [
            "<p>1</p><p>1</p><p>1</p><p>1</p>",
            "<p>test</p>",
            "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
            ]
            let current = 0

            btn.onclick = () => {

            let notif = document.createElement('div')
            notif.classList.add('notif')
            notif.innerHTML = notif_contents[current]
            notif.addEventListener('animationend', () => {
            notif.parentElement.removeChild(notif)
            })
            current++

            container.append(notif)
            }

            * {
            box-sizing: border-box;
            }

            .container {
            height: 300px;
            width: 400px;
            border: 1px solid black;
            position: absolute;
            }

            .notifications-container {
            position: absolute;
            top: 0;
            right: 0;
            height: 100%;
            width: 200px;
            background: rgba( 0, 0, 0, 0.2);
            display: flex;
            flex-flow: column nowrap;
            justify-content: flex-end;
            overflow: hidden;
            }

            .notif {
            position: relative;
            width: 100%;
            padding:0 10px;
            max-height:0px;
            border: 1px solid black;
            animation: notifAnim 5s forwards;
            transition: all .2s;
            background: white;
            }

            button {
            z-index: 100;
            background: lightcoral;
            color: white;
            border: none;
            padding: 10px;
            font-size: 20px;
            margin: 5px;
            }

            @keyframes notifAnim {
            0% {
            transform: translateY( 100%);
            max-height:0;
            padding:0 10px;
            }
            30% {
            transform: translateY( 0);
            max-height:300px;
            padding:10px;
            }
            80% {
            transform: translateY( 0);
            max-height:300px;
            padding:10px;
            }
            100% {
            transform: translateY( 100%);
            max-height:300px;
            padding:10px;
            }
            }

            <div class="container">
            <button>New Notification</button>
            <div class="notifications-container"></div>
            </div>








            share|improve this answer
























            • While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

              – Andrei Gheorghiu
              Nov 14 '18 at 22:11











            • @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

              – Temani Afif
              Nov 14 '18 at 22:17











            • If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

              – Andrei Gheorghiu
              Nov 14 '18 at 22:20











            • @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

              – Temani Afif
              Nov 14 '18 at 22:29











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308701%2fhow-can-i-make-this-transition-smooth-instead-of-it-jumping-up%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.



            The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.



            Example:






            let btn = document.querySelector('button'),
            container = document.querySelector('.notifications-container'),
            notif_contents = [
            "<p>1</p><p>1</p><p>1</p><p>1</p>",
            "<p>test</p>",
            "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
            "<code>another.test()</code>",
            "<strong>another</strong> <i>test</i>"
            ]

            btn.onclick = () => {
            let notif = document.createElement('div'),
            index = Math.floor(Math.random() * notif_contents.length)
            notif.classList.add('notif')
            notif.innerHTML = notif_contents[index]
            notif.addEventListener('animationend', () => {
            notif.parentElement.removeChild(notif)
            })

            container.append(notif)
            notif.style.marginTop = '-' + notif.offsetHeight + 'px'
            }

            * {
            box-sizing: border-box;
            }

            .container {
            height: 300px;
            width: 400px;
            border: 1px solid #888;
            position: absolute;
            }

            .notifications-container {
            position: absolute;
            top: 0;
            right: 0;
            height: 100%;
            width: 200px;
            background: rgba( 0, 0, 0, 0.2);
            display: flex;
            flex-flow: column nowrap;
            justify-content: flex-end;
            overflow: hidden;
            }

            .notif {
            position: relative;
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-bottom: none;
            animation: notifAnim 5s forwards;
            background: white;
            }

            button {
            z-index: 100;
            background: lightcoral;
            color: white;
            border: none;
            padding: 10px;
            font-size: 20px;
            margin: 5px;
            }

            @keyframes notifAnim {
            0%,
            100% {
            transform: translateY( 100%)
            }
            20%,
            80% {
            transform: translateY( 0);
            margin-top: 0
            }
            }

            <div class="container">
            <button>New Notification</button>
            <div class="notifications-container"></div>
            </div>








            share|improve this answer






























              1














              Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.



              The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.



              Example:






              let btn = document.querySelector('button'),
              container = document.querySelector('.notifications-container'),
              notif_contents = [
              "<p>1</p><p>1</p><p>1</p><p>1</p>",
              "<p>test</p>",
              "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
              "<code>another.test()</code>",
              "<strong>another</strong> <i>test</i>"
              ]

              btn.onclick = () => {
              let notif = document.createElement('div'),
              index = Math.floor(Math.random() * notif_contents.length)
              notif.classList.add('notif')
              notif.innerHTML = notif_contents[index]
              notif.addEventListener('animationend', () => {
              notif.parentElement.removeChild(notif)
              })

              container.append(notif)
              notif.style.marginTop = '-' + notif.offsetHeight + 'px'
              }

              * {
              box-sizing: border-box;
              }

              .container {
              height: 300px;
              width: 400px;
              border: 1px solid #888;
              position: absolute;
              }

              .notifications-container {
              position: absolute;
              top: 0;
              right: 0;
              height: 100%;
              width: 200px;
              background: rgba( 0, 0, 0, 0.2);
              display: flex;
              flex-flow: column nowrap;
              justify-content: flex-end;
              overflow: hidden;
              }

              .notif {
              position: relative;
              width: 100%;
              padding: 10px;
              border: 1px solid #ddd;
              border-bottom: none;
              animation: notifAnim 5s forwards;
              background: white;
              }

              button {
              z-index: 100;
              background: lightcoral;
              color: white;
              border: none;
              padding: 10px;
              font-size: 20px;
              margin: 5px;
              }

              @keyframes notifAnim {
              0%,
              100% {
              transform: translateY( 100%)
              }
              20%,
              80% {
              transform: translateY( 0);
              margin-top: 0
              }
              }

              <div class="container">
              <button>New Notification</button>
              <div class="notifications-container"></div>
              </div>








              share|improve this answer




























                1












                1








                1







                Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.



                The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.



                Example:






                let btn = document.querySelector('button'),
                container = document.querySelector('.notifications-container'),
                notif_contents = [
                "<p>1</p><p>1</p><p>1</p><p>1</p>",
                "<p>test</p>",
                "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
                "<code>another.test()</code>",
                "<strong>another</strong> <i>test</i>"
                ]

                btn.onclick = () => {
                let notif = document.createElement('div'),
                index = Math.floor(Math.random() * notif_contents.length)
                notif.classList.add('notif')
                notif.innerHTML = notif_contents[index]
                notif.addEventListener('animationend', () => {
                notif.parentElement.removeChild(notif)
                })

                container.append(notif)
                notif.style.marginTop = '-' + notif.offsetHeight + 'px'
                }

                * {
                box-sizing: border-box;
                }

                .container {
                height: 300px;
                width: 400px;
                border: 1px solid #888;
                position: absolute;
                }

                .notifications-container {
                position: absolute;
                top: 0;
                right: 0;
                height: 100%;
                width: 200px;
                background: rgba( 0, 0, 0, 0.2);
                display: flex;
                flex-flow: column nowrap;
                justify-content: flex-end;
                overflow: hidden;
                }

                .notif {
                position: relative;
                width: 100%;
                padding: 10px;
                border: 1px solid #ddd;
                border-bottom: none;
                animation: notifAnim 5s forwards;
                background: white;
                }

                button {
                z-index: 100;
                background: lightcoral;
                color: white;
                border: none;
                padding: 10px;
                font-size: 20px;
                margin: 5px;
                }

                @keyframes notifAnim {
                0%,
                100% {
                transform: translateY( 100%)
                }
                20%,
                80% {
                transform: translateY( 0);
                margin-top: 0
                }
                }

                <div class="container">
                <button>New Notification</button>
                <div class="notifications-container"></div>
                </div>








                share|improve this answer















                Your notif container has justify-content: flex-end. This means that whenever you add a new one, the previous ones will be pushed up with the height of the new one.



                The "fix" is to give each element a negative margin-top equal to its height and integrate in your current transition getting margin-top back to 0.



                Example:






                let btn = document.querySelector('button'),
                container = document.querySelector('.notifications-container'),
                notif_contents = [
                "<p>1</p><p>1</p><p>1</p><p>1</p>",
                "<p>test</p>",
                "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
                "<code>another.test()</code>",
                "<strong>another</strong> <i>test</i>"
                ]

                btn.onclick = () => {
                let notif = document.createElement('div'),
                index = Math.floor(Math.random() * notif_contents.length)
                notif.classList.add('notif')
                notif.innerHTML = notif_contents[index]
                notif.addEventListener('animationend', () => {
                notif.parentElement.removeChild(notif)
                })

                container.append(notif)
                notif.style.marginTop = '-' + notif.offsetHeight + 'px'
                }

                * {
                box-sizing: border-box;
                }

                .container {
                height: 300px;
                width: 400px;
                border: 1px solid #888;
                position: absolute;
                }

                .notifications-container {
                position: absolute;
                top: 0;
                right: 0;
                height: 100%;
                width: 200px;
                background: rgba( 0, 0, 0, 0.2);
                display: flex;
                flex-flow: column nowrap;
                justify-content: flex-end;
                overflow: hidden;
                }

                .notif {
                position: relative;
                width: 100%;
                padding: 10px;
                border: 1px solid #ddd;
                border-bottom: none;
                animation: notifAnim 5s forwards;
                background: white;
                }

                button {
                z-index: 100;
                background: lightcoral;
                color: white;
                border: none;
                padding: 10px;
                font-size: 20px;
                margin: 5px;
                }

                @keyframes notifAnim {
                0%,
                100% {
                transform: translateY( 100%)
                }
                20%,
                80% {
                transform: translateY( 0);
                margin-top: 0
                }
                }

                <div class="container">
                <button>New Notification</button>
                <div class="notifications-container"></div>
                </div>








                let btn = document.querySelector('button'),
                container = document.querySelector('.notifications-container'),
                notif_contents = [
                "<p>1</p><p>1</p><p>1</p><p>1</p>",
                "<p>test</p>",
                "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
                "<code>another.test()</code>",
                "<strong>another</strong> <i>test</i>"
                ]

                btn.onclick = () => {
                let notif = document.createElement('div'),
                index = Math.floor(Math.random() * notif_contents.length)
                notif.classList.add('notif')
                notif.innerHTML = notif_contents[index]
                notif.addEventListener('animationend', () => {
                notif.parentElement.removeChild(notif)
                })

                container.append(notif)
                notif.style.marginTop = '-' + notif.offsetHeight + 'px'
                }

                * {
                box-sizing: border-box;
                }

                .container {
                height: 300px;
                width: 400px;
                border: 1px solid #888;
                position: absolute;
                }

                .notifications-container {
                position: absolute;
                top: 0;
                right: 0;
                height: 100%;
                width: 200px;
                background: rgba( 0, 0, 0, 0.2);
                display: flex;
                flex-flow: column nowrap;
                justify-content: flex-end;
                overflow: hidden;
                }

                .notif {
                position: relative;
                width: 100%;
                padding: 10px;
                border: 1px solid #ddd;
                border-bottom: none;
                animation: notifAnim 5s forwards;
                background: white;
                }

                button {
                z-index: 100;
                background: lightcoral;
                color: white;
                border: none;
                padding: 10px;
                font-size: 20px;
                margin: 5px;
                }

                @keyframes notifAnim {
                0%,
                100% {
                transform: translateY( 100%)
                }
                20%,
                80% {
                transform: translateY( 0);
                margin-top: 0
                }
                }

                <div class="container">
                <button>New Notification</button>
                <div class="notifications-container"></div>
                </div>





                let btn = document.querySelector('button'),
                container = document.querySelector('.notifications-container'),
                notif_contents = [
                "<p>1</p><p>1</p><p>1</p><p>1</p>",
                "<p>test</p>",
                "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>",
                "<code>another.test()</code>",
                "<strong>another</strong> <i>test</i>"
                ]

                btn.onclick = () => {
                let notif = document.createElement('div'),
                index = Math.floor(Math.random() * notif_contents.length)
                notif.classList.add('notif')
                notif.innerHTML = notif_contents[index]
                notif.addEventListener('animationend', () => {
                notif.parentElement.removeChild(notif)
                })

                container.append(notif)
                notif.style.marginTop = '-' + notif.offsetHeight + 'px'
                }

                * {
                box-sizing: border-box;
                }

                .container {
                height: 300px;
                width: 400px;
                border: 1px solid #888;
                position: absolute;
                }

                .notifications-container {
                position: absolute;
                top: 0;
                right: 0;
                height: 100%;
                width: 200px;
                background: rgba( 0, 0, 0, 0.2);
                display: flex;
                flex-flow: column nowrap;
                justify-content: flex-end;
                overflow: hidden;
                }

                .notif {
                position: relative;
                width: 100%;
                padding: 10px;
                border: 1px solid #ddd;
                border-bottom: none;
                animation: notifAnim 5s forwards;
                background: white;
                }

                button {
                z-index: 100;
                background: lightcoral;
                color: white;
                border: none;
                padding: 10px;
                font-size: 20px;
                margin: 5px;
                }

                @keyframes notifAnim {
                0%,
                100% {
                transform: translateY( 100%)
                }
                20%,
                80% {
                transform: translateY( 0);
                margin-top: 0
                }
                }

                <div class="container">
                <button>New Notification</button>
                <div class="notifications-container"></div>
                </div>






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 14 '18 at 22:48

























                answered Nov 14 '18 at 22:06









                Andrei GheorghiuAndrei Gheorghiu

                35.6k74774




                35.6k74774

























                    0














                    An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:






                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>








                    share|improve this answer
























                    • While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:11











                    • @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                      – Temani Afif
                      Nov 14 '18 at 22:17











                    • If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:20











                    • @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                      – Temani Afif
                      Nov 14 '18 at 22:29
















                    0














                    An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:






                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>








                    share|improve this answer
























                    • While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:11











                    • @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                      – Temani Afif
                      Nov 14 '18 at 22:17











                    • If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:20











                    • @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                      – Temani Afif
                      Nov 14 '18 at 22:29














                    0












                    0








                    0







                    An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:






                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>








                    share|improve this answer













                    An idea is to insert new element with a height equal to 0 and you animate the height in addition to translate. Of course, you should use max-height since height are unknown and we cannot animate to auto:






                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>








                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>





                    let btn = document.querySelector('button')
                    let container = document.querySelector('.notifications-container')

                    let notif_contents = [
                    "<p>1</p><p>1</p><p>1</p><p>1</p>",
                    "<p>test</p>",
                    "<div><h1>testtesttest</h1><p>yoloalsdfasdf</p></div>"
                    ]
                    let current = 0

                    btn.onclick = () => {

                    let notif = document.createElement('div')
                    notif.classList.add('notif')
                    notif.innerHTML = notif_contents[current]
                    notif.addEventListener('animationend', () => {
                    notif.parentElement.removeChild(notif)
                    })
                    current++

                    container.append(notif)
                    }

                    * {
                    box-sizing: border-box;
                    }

                    .container {
                    height: 300px;
                    width: 400px;
                    border: 1px solid black;
                    position: absolute;
                    }

                    .notifications-container {
                    position: absolute;
                    top: 0;
                    right: 0;
                    height: 100%;
                    width: 200px;
                    background: rgba( 0, 0, 0, 0.2);
                    display: flex;
                    flex-flow: column nowrap;
                    justify-content: flex-end;
                    overflow: hidden;
                    }

                    .notif {
                    position: relative;
                    width: 100%;
                    padding:0 10px;
                    max-height:0px;
                    border: 1px solid black;
                    animation: notifAnim 5s forwards;
                    transition: all .2s;
                    background: white;
                    }

                    button {
                    z-index: 100;
                    background: lightcoral;
                    color: white;
                    border: none;
                    padding: 10px;
                    font-size: 20px;
                    margin: 5px;
                    }

                    @keyframes notifAnim {
                    0% {
                    transform: translateY( 100%);
                    max-height:0;
                    padding:0 10px;
                    }
                    30% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    80% {
                    transform: translateY( 0);
                    max-height:300px;
                    padding:10px;
                    }
                    100% {
                    transform: translateY( 100%);
                    max-height:300px;
                    padding:10px;
                    }
                    }

                    <div class="container">
                    <button>New Notification</button>
                    <div class="notifications-container"></div>
                    </div>






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 14 '18 at 21:41









                    Temani AfifTemani Afif

                    75k94386




                    75k94386













                    • While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:11











                    • @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                      – Temani Afif
                      Nov 14 '18 at 22:17











                    • If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:20











                    • @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                      – Temani Afif
                      Nov 14 '18 at 22:29



















                    • While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:11











                    • @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                      – Temani Afif
                      Nov 14 '18 at 22:17











                    • If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                      – Andrei Gheorghiu
                      Nov 14 '18 at 22:20











                    • @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                      – Temani Afif
                      Nov 14 '18 at 22:29

















                    While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                    – Andrei Gheorghiu
                    Nov 14 '18 at 22:11





                    While in principle you're right, I find setting the height to 0 less robust in the open, as it sometimes reflows contents. You also have the disadvantage of having to "remember" the height and animate towards it. Negative margin seems to be a more reliable solution, IMHO. No reflow and you always animate towards 0, regardless of height.

                    – Andrei Gheorghiu
                    Nov 14 '18 at 22:11













                    @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                    – Temani Afif
                    Nov 14 '18 at 22:17





                    @AndreiGheorghiu I was thinking pure CSS and forget at the end that we are using JS and we have the flexibility to get different value like height, etc ... I thought about the margin animation but didn't find the CSS solution of it.

                    – Temani Afif
                    Nov 14 '18 at 22:17













                    If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                    – Andrei Gheorghiu
                    Nov 14 '18 at 22:20





                    If the height is variable you can't make a solution with CSS alone. In order to animate max-height smoothly you'd need to animate it towards the height value. Otherwise it will either jump or not animate for the entire time (when you animate max-height past height, the element doesn't change).

                    – Andrei Gheorghiu
                    Nov 14 '18 at 22:20













                    @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                    – Temani Afif
                    Nov 14 '18 at 22:29





                    @AndreiGheorghiu yes that's why the only CSS solution is to consider a value big enough to be sure it will also be toward height which is easy in this case since the container has a fixed height and the notification are small.

                    – Temani Afif
                    Nov 14 '18 at 22:29


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308701%2fhow-can-i-make-this-transition-smooth-instead-of-it-jumping-up%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Florida Star v. B. J. F.

                    Danny Elfman

                    Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues