Для решения только с CSS я бы рассмотрел радиальный градиент и некоторую фоновую анимацию:
.box {
height:50px;
width:600px;
padding-top:50px;
background:
/*concave*/
radial-gradient(410px 50px at 50% 0,transparent, 80%, #000 80.5%) center,
/*convexe*/
radial-gradient(410px 50px at 50% 50px,#000, 80%, transparent 80.5%)center,
linear-gradient(#000,#000) content-box;
background-size:100% 100%,100% 0px,auto;
background-repeat:no-repeat;
transition:1s all;
}
.box:hover {
background-size:100% 0,100% 100%,auto;
}
<div class="box"></div>
Вы также можете использовать его для прямоугольника полной ширины:
.box {
height:50px;
padding-top:50px;
background:
/*concave*/
radial-gradient(70% 50px at 50% 0,transparent, 80%, #000 80.5%) center,
/*convexe*/
radial-gradient(70% 50px at 50% 50px,#000, 80%, transparent 80.5%)center,
linear-gradient(#000,#000) content-box;
background-size:100% 100%,100% 0px,auto;
background-repeat:no-repeat;
transition:1s all;
}
.box:hover {
background-size:100% 0,100% 100%,auto;
}
<div class="box"></div>
В случае, если вы будете иметь большую высоту или динамическую высоту, лучше рассмотрите псевдоэлемент, чтобы эффект не изменялся при изменении высоты:
.box {
height: 80vh;
position: relative;
padding-top: 50px;
background: #000 content-box;
}
.box::before {
content: "";
position: absolute;
top: 1px;
left: 0;
right: 0;
padding: inherit;
background:
/*concave*/
radial-gradient(70% 50px at 50% 0, transparent, 80%, #000 80.5%) bottom,
/*convexe*/
radial-gradient(70% 50px at 50% 50px, #000, 80%, transparent 80.5%)bottom;
background-size: 100% 100%, 100% 0px;
background-repeat: no-repeat;
transition: 1s all;
}
.box:hover::before {
background-size: 100% 0, 100% 100%;
}
<div class="box"></div>
Обновление
Вы также можете настроить эффект, как показано ниже:
.box {
height: 80vh;
position: relative;
padding-top: 100px;
background: #000 content-box;
}
/*concave*/
.box::before {
content: "";
position: absolute;
top: 50px;
left: 0;
right: 0;
height: 51px;
background:
radial-gradient(70% 50px at 50% 0, transparent, 80%, #000 80.5%) top center;
background-size: 100% 200%;
background-repeat: no-repeat;
transition: 0.5s all 0.4s ease-out;
}
/*convexe*/
.box::after {
content: "";
position: absolute;
top: 1px;
left: 0;
right: 0;
height: 51px;
background:
radial-gradient(70% 50px at 50% 50px, #000, 80%, transparent 80.5%)bottom center;
background-size: 200% 0%;
background-repeat: no-repeat;
transition: 0.5s all ease-in;
}
.box:hover::before {
background-position: bottom center;
background-size: 200% 200%;
transition: 0.5s all ease-in;
}
.box:hover::after {
background-size: 100% 100%;
transition: 0.5s all 0.4s ease-out;
}
<div class="box"></div>