Блоки поднимаются вверх

Столкнулся с проблемой , у меня при нажатии на кнопку Item, блоки опускаются вниз , как сделать так, чтобы старые сообщения уходил в верх страницы , а не в низ ?

const app = new Vue({
   el: '#app',
   data() {
     return {
       currentElement: 0,
       color: 0,
       changColor: [{
           class: 'blue',
           img: 'source/img/infocircle.png'
         },
         {
           class: 'grey',
           img: 'source/img/infocircle.png'
         },
         {
           class: 'green',
           img: 'source/img/accept.png'
         },
         {
           class: 'orange',
           img: 'source/img/warning.png'
         },
         {
           class: 'red',
           img: 'source/img/x.png'
         },
       ],
       messages: []
     }
   },
   methods: {
     setElement() {
       this.currentElement = (1 + this.currentElement) % this.firstItem.length;
     },
     changeCollors() {
       this.color = (1 + this.color) % this.changColor.length;
     },
     changeItemss() {
       let timeStamp = Date.now().toLocaleString();
       this.messages.unshift({
         id: timeStamp,
         colorId: this.color,
         currentElementId: this.currentElement
       })
     },
   },
 });
.notification {
  position: relative;
  overflow: hidden;
  top: 85.18519vh;
  left: 75vh;
  width: 46.2963vh;
  height: 7.40741vh;
  background: rgba(0, 0, 0, 0.6);
  -webkit-box-shadow: 0vh 0.37037vh 2.96296vh 0.27778vh rgba(0, 0, 0, 0.25);
          box-shadow: 0vh 0.37037vh 2.96296vh 0.27778vh rgba(0, 0, 0, 0.25);
  border-radius: 1.85185vh;
}

.notification__fade {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(41, 138, 238, 0) 95.58%);
  border-radius: 1.85185vh 0vh 0vh 1.85185vh;
}

.notification__img {
  width: 4.62963vh;
  height: 4.62963vh;
  margin-top: 1.85185vh;
  margin-left: 0.92593vh;
}

.notification__text {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  text-align: center;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-size: 1.66667vh;
  line-height: 2.03704vh;
  color: #FFFFFF;
  text-shadow: 0vh 0.37037vh 0.37037vh rgba(0, 0, 0, 0.5);
  margin-left: 0.92593vh;
}

.notification__progresbar {
  position: absolute;
  width: 51.38889vh;
  bottom: 0vh;
  border-bottom: 0.37037vh solid #FFFFFF;
}

.notification {
  -webkit-animation: fadeOut 5s linear forwards;
  animation: fadeOut 5s linear forwards;
}

.notification__progresbar {
  -webkit-animation: runProgress 4s linear forwards;
  animation: runProgress 4.6s linear forwards;
}

@-webkit-keyframes fadeOut {
  0% {
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  100% {
    opacity: 0;
    -webkit-transform: translateY(-25px);
  }
}

@-webkit-keyframes runProgress {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}

@keyframes runProgress {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}

.blue {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(41, 138, 238, 0) 95.58%);
}

.grey {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #BBBBBB 0.42%, rgba(187, 187, 187, 0) 95.58%);
}

.orange {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #FF6B00 0.42%, rgba(255, 107, 0, 0) 95.58%);
}

.green {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #6FDE00 0.42%, rgba(111, 222, 0, 0) 95.58%);
}

.red {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #FF0000 0.42%, rgba(255, 0, 0, 0) 95.58%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="wraper">
      <button @click="changeCollors">Color</button>
      <button @click="changeItemss">Items</button>
        <div class="notification" v-for="message in messages" :key="message.id">
          <div :class= "changColor[message.colorId].class">
            <img class="notification__img" :src="changColor[message.colorId].img">
            <p class="notification__text">{{message.id}}</p>
          </div>
          <div class="notification__progresbar"></div>
        </div>
    </div>


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

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

У вас массив messages только заполнялся. Контейнеры с уведомлениями скрывались из из-за анимации, но из дерева DOM не исчезали.

Если стараться максимально ничего не менять, то функция changeInemss() должна выглядеть так:

changeItemss() {
       let timeStamp = Date.now().toLocaleString();
       this.messages.push({ // добавим в список
         id: timeStamp,
         colorId: this.color,
         currentElementId: this.currentElement
       })
       setTimeout(() => { 
         this.messages.shift(); // уберем из списка
       },4600) // через 4.6s закончится анимация
     },

Вероятно вы ожидаете такого результата:

const app = new Vue({
   el: '#app',
   data() {
     return {
       currentElement: 0,
       color: 0,
       changColor: [{
           class: 'blue',
           img: 'source/img/infocircle.png'
         },
         {
           class: 'grey',
           img: 'source/img/infocircle.png'
         },
         {
           class: 'green',
           img: 'source/img/accept.png'
         },
         {
           class: 'orange',
           img: 'source/img/warning.png'
         },
         {
           class: 'red',
           img: 'source/img/x.png'
         },
       ],
       messages: []
     }
   },
   methods: {
     setElement() {
       this.currentElement = (1 + this.currentElement) % this.firstItem.length;
     },
     changeCollors() {
       this.color = (1 + this.color) % this.changColor.length;
     },
     changeItemss() {
       let timeStamp = Date.now().toLocaleString();
       this.messages.push({
         id: timeStamp,
         colorId: this.color,
         currentElementId: this.currentElement
       })
       setTimeout(() => {
         this.messages.shift();

       },4600)
     },
   },
 })
.notification-container { /** общий контейнер для notification */
  position: fixed;
  bottom: 1rem;
  margin: auto;
  left: calc(50% - 23.1527vh); /** не понятно зачем вы так используете vh */
}
.notification {
  position: relative;
  overflow: hidden;
  bottom: 0;
  margin-top: 1rem;
  width: 46.2963vh; 
  height: 7.40741vh;
  background: rgba(0, 0, 0, 0.6);
  -webkit-box-shadow: 0vh 0.37037vh 2.96296vh 0.27778vh rgba(0, 0, 0, 0.25);
          box-shadow: 0vh 0.37037vh 2.96296vh 0.27778vh rgba(0, 0, 0, 0.25);
  border-radius: 1.85185vh;
}

.notification__fade {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(41, 138, 238, 0) 95.58%);
  border-radius: 1.85185vh 0vh 0vh 1.85185vh;
}

.notification__img {
  width: 4.62963vh; 
  height: 4.62963vh;
  margin-top: 1.85185vh;
  margin-left: 0.92593vh;
}

.notification__text {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  text-align: center;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-size: 1.66667vh;
  line-height: 2.03704vh;
  color: #FFFFFF;
  text-shadow: 0vh 0.37037vh 0.37037vh rgba(0, 0, 0, 0.5);
  margin-left: 0.92593vh;
}

.notification__progresbar {
  position: absolute;
  width: 51.38889vh;
  bottom: 0vh;
  border-bottom: 0.37037vh solid #FFFFFF;
}

.notification {
  -webkit-animation: fadeOut 5s linear forwards;
  animation: fadeOut 5s linear forwards;
}

.notification__progresbar {
  -webkit-animation: runProgress 4s linear forwards;
  animation: runProgress 4.6s linear forwards;
}

@-webkit-keyframes fadeOut {
  0% {
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  100% {
    opacity: 0;
    -webkit-transform: translateY(-25px);
  }
}

@-webkit-keyframes runProgress {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}

@keyframes runProgress {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}

.blue {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #007EFF 0.42%, rgba(41, 138, 238, 0) 95.58%);
}

.grey {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #BBBBBB 0.42%, rgba(187, 187, 187, 0) 95.58%);
}

.orange {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #FF6B00 0.42%, rgba(255, 107, 0, 0) 95.58%);
}

.green {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #6FDE00 0.42%, rgba(111, 222, 0, 0) 95.58%);
}

.red {
  position: absolute;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 7.40741vh;
  background: linear-gradient(90.49deg, #FF0000 0.42%, rgba(255, 0, 0, 0) 95.58%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="wraper">
  <button @click="changeCollors">Color</button>
  <button @click="changeItemss">Items</button>
  <div class="notification-container">
    <div class="notification" v-for="message in messages" :key="message.id">
      <div :class= "changColor[message.colorId].class">
        <img class="notification__img" :src="changColor[message.colorId].img">
        <p class="notification__text">{{message.id}}</p>
      </div>
      <div class="notification__progresbar"></div>
    </div>
  </div>
</div>

→ Ссылка