Как сделать простой Preloader при загрузке страниц
Preloader при загрузке страниц чаще всего нужен в том случае, если необходимо, чтобы пользователь начал пользоваться сайтом только после загрузки всех ресурсов (изображения, javascript-код и так далее). Но нужно использовать его с осторожностью, так как пока все ресурсы не будут загружены, контент остаётся недоступным
Пример Preloader, который будем реализовывать в этой практической статье, можно посмотреть на видео
Этот же пример на Codepen
Или просто обновите страницу с этой статьёй - при открытии статьи, вы уже, скорей всего, заметили данный Preloader :)
Верстаем структуру
Для начала необходимо найти подходящий Preloader. Небольшой набор качественных Preloaders можно посмотреть здесь - https://tobiasahlin.com/spinkit/
По ссылке выше, выбираем наиболее подходящий Preloader и нажимаем на Source
В появившемся окне копируем HTML-структуру Preloader
<div class="sk-chase">
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
</div>
В разметке создадим блок <div class="preloader"></div>
и вставляем в него скопированный HTML-код
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Preloader</title>
<link rel="stylesheet" href="css/bootstrap-reboot.min.css"/>
<link rel="stylesheet" href="css/main.css"/>
</head>
<body>
<!-- Изображения для фона и теста -->
<div class="images">
<div class="images__image"><img src="https://picsum.photos/1920/1080" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1081" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1082" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1083" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1084" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1085" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1086" alt=""/></div>
<div class="images__image"><img src="https://picsum.photos/1920/1087" alt=""/></div>
</div>
<!-- Блок Preloader -->
<div class="preloader">
<!-- Добавляем готовую структуру Preloader -->
<div class="sk-chase">
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
<div class="sk-chase-dot"></div>
</div>
</div>
<script src="js/main.js"></script>
</body>
</html>
Добавляем стили
В том же окне, где копировали HTML-структуру Preloader, копируем CSS-стили для него
.sk-chase {
width: 40px;
height: 40px;
position: relative;
animation: sk-chase 2.5s infinite linear both;
}
.sk-chase-dot {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
animation: sk-chase-dot 2.0s infinite ease-in-out both;
}
.sk-chase-dot:before {
content: '';
display: block;
width: 25%;
height: 25%;
background-color: #fff;
border-radius: 100%;
animation: sk-chase-dot-before 2.0s infinite ease-in-out both;
}
.sk-chase-dot:nth-child(1) { animation-delay: -1.1s; }
.sk-chase-dot:nth-child(2) { animation-delay: -1.0s; }
.sk-chase-dot:nth-child(3) { animation-delay: -0.9s; }
.sk-chase-dot:nth-child(4) { animation-delay: -0.8s; }
.sk-chase-dot:nth-child(5) { animation-delay: -0.7s; }
.sk-chase-dot:nth-child(6) { animation-delay: -0.6s; }
.sk-chase-dot:nth-child(1):before { animation-delay: -1.1s; }
.sk-chase-dot:nth-child(2):before { animation-delay: -1.0s; }
.sk-chase-dot:nth-child(3):before { animation-delay: -0.9s; }
.sk-chase-dot:nth-child(4):before { animation-delay: -0.8s; }
.sk-chase-dot:nth-child(5):before { animation-delay: -0.7s; }
.sk-chase-dot:nth-child(6):before { animation-delay: -0.6s; }
@keyframes sk-chase {
100% { transform: rotate(360deg); }
}
@keyframes sk-chase-dot {
80%, 100% { transform: rotate(360deg); }
}
@keyframes sk-chase-dot-before {
50% {
transform: scale(0.4);
} 100%, 0% {
transform: scale(1.0);
}
}
Добавляем остальные стили
body {
background: #121212;
}
.images {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 32px;
gap: 32px;
padding: 32px;
}
.images__image {
border-radius: 8px;
overflow: hidden;
}
.images__image img {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
display: block;
}
/* Стили для основного блока Preloader */
.preloader {
/* Фиксируем блок на всю ширину и высоту окна, чтобы перекрывать все остальные элементы */
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 9999;
/* Центрируем анимацию Preloader */
display: flex;
align-items: center;
justify-content: center;
/* При загрузке страницы, Preloader сразу отображается */
opacity: 1;
visibility: visible;
/* Добавляем затемнение */
background: rgba(18,18,18,0.64);
/* Добавляем плавный переход */
transition: opacity 1s, visibility 0s 0s;
}
/* Класс для скрытия Preloader */
.preloader_hidden {
visibility: hidden;
opacity: 0;
transition: opacity 1s, visibility 0s 1s;
}
/* Скопированый код анимации Preloader */
.sk-chase {
width: 128px;
height: 128px;
position: relative;
-webkit-animation: sk-chase 2.5s infinite linear both;
animation: sk-chase 2.5s infinite linear both;
}
.sk-chase-dot {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
-webkit-animation: sk-chase-dot 2s infinite ease-in-out both;
animation: sk-chase-dot 2s infinite ease-in-out both;
}
.sk-chase-dot:before {
content: '';
display: block;
width: 25%;
height: 25%;
background-color: #3626a7;
border-radius: 100%;
-webkit-animation: sk-chase-dot-before 2s infinite ease-in-out both;
animation: sk-chase-dot-before 2s infinite ease-in-out both;
}
.sk-chase-dot:nth-child(1) {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.sk-chase-dot:nth-child(2) {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
.sk-chase-dot:nth-child(3) {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.sk-chase-dot:nth-child(4) {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
.sk-chase-dot:nth-child(5) {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
}
.sk-chase-dot:nth-child(6) {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s;
}
.sk-chase-dot:nth-child(1):before {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.sk-chase-dot:nth-child(2):before {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
.sk-chase-dot:nth-child(3):before {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.sk-chase-dot:nth-child(4):before {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
.sk-chase-dot:nth-child(5):before {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
}
.sk-chase-dot:nth-child(6):before {
-webkit-animation-delay: -0.6s;
animation-delay: -0.6s;
}
@-webkit-keyframes sk-chase {
100% {
transform: rotate(360deg);
}
}
@keyframes sk-chase {
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes sk-chase-dot {
80%, 100% {
transform: rotate(360deg);
}
}
@keyframes sk-chase-dot {
80%, 100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes sk-chase-dot-before {
50% {
transform: scale(0.4);
}
100%, 0% {
transform: scale(1);
}
}
@keyframes sk-chase-dot-before {
50% {
transform: scale(0.4);
}
100%, 0% {
transform: scale(1);
}
}
Пишем логику на JavaScript
Логика максимально простая - определяем, когда все ресурсы страницы будут загружены, ищем блок Preloader и добавляем ему класс для скрытия
window.addEventListener('load', () => { /* Страница загружена, включая все ресурсы */
const preloader = document.querySelector('.preloader') /* находим блок Preloader */
preloader.classList.add('preloader_hidden') /* добавляем ему класс для скрытия */
})
Итоги
Конечно, Preloader можно добавлять не только на событие загрузки страницы. Preloader часто добавляют также при AJAX-запросах в отдельных компонентах, не блокируя остальную часть сайта. Но об этом в другой раз :)
Буду рад, если статья оказалась полезной
Спасибо за ваше внимание и уделённое время!