Another perspective to consider
<div id="app"></div>
#app {
height: 300px;
width: 300px;
min-height: 50vh;
padding-top: 35px;
padding-bottom: 75px;
text-align: center;
background-image: radial-gradient(circle at 50% 95%, #ffa400ff 0%, #fd6e00ff 33.3333%, black 60%, black 100%);
background-size: 100% 300%;
background-position: 50% 100%;
transition: background-position 1s;
}
#app:hover {
background-position: 50% 0%;
}
Alternatively, using two layers of background
<div id="app"></div>
#app {
height: 300px;
width: 300px;
min-height: 50vh;
padding-top: 35px;
padding-bottom: 75px;
text-align: center;
background-color: red;
background-image: linear-gradient(180deg, #ffa400ff 0%, #ffa400ff 50%, #ffa40000 100%), radial-gradient(circle at 50% 95%, #ffa400ff, #fd6e00ff);
background-size: 100% 200%, 100% 100%;
background-position: 0 200%, 0 0;
background-repeat: no-repeat;
transition: background-position 1s;
}
#app:hover {
background-position: 0 0, 0 0;
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html,body,ul,li{
height: 100%;
margin: 0;
padding: 0;
}
.flip-list-enter-active, .flip-list-leave-active {
transition: all 1s;
}
.flip-list-enter, .flip-list-leave-active {
opacity: 0;
}
.demo {
position: relative;
height: 100%;
}
.demo > ul {
position: absolute;
z-index: 0;
height: 100%;
width: 100%;
}
.demo .bg-color-li {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.demo .bg-color-li div {
height: 100%
}
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
text-shadow: 0 0 3px #ffffff;
}
</style>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" class="demo">
<transition-group name="flip-list" tag="ul">
<li v-for="curColor in curColors" v-bind:key="curColor" class="bg-color-li">
<div :style="`background-image: ${curColor}`"></div>
</li>
</transition-group>
<div class="content">
content...
</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
curColors: [],
colors: [
'linear-gradient(45deg, blue, black)',
'linear-gradient(45deg, red, orange)',
'linear-gradient(45deg, pink, purple)',
'linear-gradient(45deg, green, brown)'
],
index: 0
},
mounted: function () {
this.curColors = [this.colors[0]];
this.startChange();
},
methods: {
startChange () {
setInterval(() => {
if (this.index < this.colors.length - 1) {
this.index++
} else {
this.index = 0
}
this.curColors.splice(0, 1, this.colors[this.index]);
}, 2000);
}
}
})
</script>
</body>
</html>