. . .

Эффект волны

7 Август 2019

На одном из собеседований мне, в качестве тестового задания, предложили сверстать стартовый блок одного из сайтов. Вот этот блок:

Самым сложным элементом этого блока являлась волна на фоне, поскольку по техническому заданию требовалось, чтобы при попадании курсора в область этого блока волна выпрямлялась. Тогда у меня были только догадки в какой области кроется ответ на этот вопрос, но немногим позже я решил эту задачу. Изначально я видел решение в svg либо js. Но потом мне в голову пришла очень простая и изящная мысль.

Мое решение не выполняет эту задачу детально по макету, но оно невероятно простое и будет очень хорошо поддерживаться браузерами. Оно кроется в свойстве border-top-left-radius и border-top-right-radius. Приступим к его реализации, html-верстка:

<div class="wave-block">
    <div class="w-items">
         <div id="item1" class="w-item"></div>
         <div id="item2" class="w-item"></div>
         <div id="item3" class="w-item"></div>
         <div id="item4" class="w-item"></div>
    </div>
</div>

На главный блок wave-block будет установлено фоновое изображение, блок w-items служит для того, чтобы наложить на него прозрачность. Блоки w-item будут служить элементами волны, они будут абсолютно позиционированы и сделаны с наплывом друг на друга. Добавим css-стили:

.wave-block {
    width: 94%;
    margin-left: 3%;
    position: relative;
    overflow: hidden;
    height: 450px;
    background-image: url(wavebg.jpg);
    background-size: cover;
}
.w-items {
    opacity: .6; 
}
.wave-block .w-item {
    float: left;
    background-color: #002;
    position: absolute;
    bottom: 0;
    transition: .9s ease;
}
#item1 {
    height: 200px;
    width: 20%;
    left: 0;
    border-top-left-radius: 60% 35%;
    border-top-right-radius: 40% 15%;
}
#item2 {
    height: 230px;
    width: 30%;
    left: 15%;
    border-top-left-radius: 60% 35%;
    border-top-right-radius: 40% 15%;
}
#item3 {
    height: 260px;
    width: 45%;
    left: 40%;
    border-top-left-radius: 60% 35%;
    border-top-right-radius: 40% 15%;
}
#item4 {
    height: 290px;
    width: 40%;
    left: 75%;
    border-top-left-radius: 40% 35%;
    border-top-right-radius: 60% 55%;
}
.wave-block:hover #item1, .wave-block:hover #item2, .wave-block:hover #item3, .wave-block:hover #item4 {
    border-top-left-radius: 0 0;
    border-top-right-radius: 0 0;
    height: 150px;
}

Теперь посмотрим на получившийся результат:

К сожалению у этого подхода есть один изъян. В браузерах internet explorer и microsoft edge не работает свойство opacity. Если требуется поддержка этих браузеров, то можно сверстать элементы волны без нахлеста друг на друга и установить прозрачность у них, в таком случае все будет работать так, как нужно.

Посмотреть на github