Несмотря на то, что почти все зарубежные шаблоны используют прелоадеры, я противник их применения в таком виде как они подаются. А именно: у нас закрыт сайт, и что-то там прыгает, пока полностью не загрузится страница. Это потому что:
- Cайт не должен так долго грузится, и соотв. показывать загрузку на 1 секунду нет никакого смысла.
- Cайт может грузиться и минуту, если какие-то сторонние ресурсы (метрика, аналитика, различные апи) не отвечают, и соотв. пользователь не дождется окончания и уйдет.
Но этот подход может пригодится для лендингов или главных страниц сайта, где очень много скриптов, фотографий, присутствует модный слайдер с HD фото и т.д. В этом случае, чтобы посетитель не видел сборку страницы и не пугался этому процессу, можно ее закрыть и показать прелоадер. Это полезно еще в том случае, когда некоторые скрипты активируются после полной загрузки страницы.
Но и тут не стоит забывать, что если вы грузите что то с другого сайта, который недоступен, прелоадер может висеть минутами.
Создавая прелоадер нужно помнить, что красивый анимационный эффект может весить очень много, и в итоге посетитель сайта будет ждать пока загрузится он, а потом еще ждать когда вместо него покажется нужная ему информация.
Создание прелоадера:
Создается и работает все просто: мы создаем фиксированный слой на весь экран, на нем размещаем картинку или блок анимации, а после полной загрузки страницы все это убираем.
HTML:
1 2 3 |
<div class="preloader"> <!-- Элементы прелоадера --> </div> |
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.preloader { position: fixed; left: 0px; top: 0px; width: 100%; height: 100%; z-index: 999999; display: flex; align-items: center; justify-content: center; background: #fff; transition: all 0.5s; opacity: 1; } .preloader-remove { opacity: 0; z-index: -10; } |
JS:
1 2 3 |
window.onload = function() { document.querySelector('.preloader').classList.add("preloader-remove"); }; |
jQuery:
1 2 3 |
$(window).on('load', function () { $('.preloader').addClass("preloader-remove"); }); |
Класс preloader-remove
отвечает за удаление прелоадера. Его можно удалить, сдвинуть или сделать прозрачным, как в примере.
Можно использовать и альтернативный вариант, это закрывать не всю страницу сайта, а нужную область, например слайдер или галерею. Этот вариант рассмотрим позже.
Варианты оформления:
В центр страницы можно поместить обычную gif-картинку, но это не интересно, поэтому рассмотрим другие варианты:
Вариант 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div class="preloader-1"> <svg> <g> <path d="M 50,100 A 1,1 0 0 1 50,0"/> </g> <g> <path d="M 50,75 A 1,1 0 0 0 50,-25"/> </g> <defs> <linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" style="stop-color:#BFE2FF;stop-opacity:1" /> <stop offset="100%" style="stop-color:#337AB7;stop-opacity:1" /> </linearGradient> </defs> </svg> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
.preloader-1 svg { overflow: visible; width: 100px; height: 150px; } .preloader-1 svg g { animation: preloader-1-slide 2s linear infinite; } .preloader-1 svg g:nth-child(2) { animation-delay: 0.5s; } .preloader-1 svg g:nth-child(2) path { animation-delay: 0.5s; stroke-dasharray: 0px 158px; stroke-dashoffset: 1px; } .preloader-1 svg path { stroke: url(#gradient); stroke-width: 20px; stroke-linecap: round; fill: none; stroke-dasharray: 0 157px; stroke-dashoffset: 0; animation: preloader-1-escalade 2s cubic-bezier(0.8, 0, 0.2, 1) infinite; } @keyframes preloader-1-slide { 0% { transform: translateY(-50px); } 100% { transform: translateY(50px); } } @keyframes preloader-1-escalade { 0% { stroke-dasharray: 0 157px; stroke-dashoffset: 0; } 50% { stroke-dasharray: 156px 157px; stroke-dashoffset: 0; } 100% { stroke-dasharray: 156px 157px; stroke-dashoffset: -156px; } } |
Вариант 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<div class="preloader-2"> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
.preloader-2 { width: auto; height: auto; } .preloader-2 ul { list-style: none; display: grid; grid-template-columns: repeat(5, 1fr); animation: preloader-2-rot 16s linear infinite; } @keyframes preloader-2-rot { 100% { transform: rotate(360deg); } } .preloader-2 li { width: 40px; height: 40px; background: #337AB7; border-radius: 4px; animation: preloader-2-scale 0.8s linear alternate infinite; } @keyframes preloader-2-scale { 100% { transform: scale(0.1); opacity: 0; } } .preloader-2 li:nth-child(1) { z-index: 24; } .preloader-2 li:nth-child(2) { z-index: 23; } .preloader-2 li:nth-child(3) { z-index: 22; } .preloader-2 li:nth-child(4) { z-index: 21; } .preloader-2 li:nth-child(5) { z-index: 20; } .preloader-2 li:nth-child(6) { z-index: 19; } .preloader-2 li:nth-child(7) { z-index: 18; } .preloader-2 li:nth-child(8) { z-index: 17; } .preloader-2 li:nth-child(9) { z-index: 16; } .preloader-2 li:nth-child(10) { z-index: 15; } .preloader-2 li:nth-child(11) { z-index: 14; } .preloader-2 li:nth-child(12) { z-index: 13; } .preloader-2 li:nth-child(13) { z-index: 12; } .preloader-2 li:nth-child(14) { z-index: 11; } .preloader-2 li:nth-child(15) { z-index: 10; } .preloader-2 li:nth-child(16) { z-index: 9; } .preloader-2 li:nth-child(17) { z-index: 8; } .preloader-2 li:nth-child(18) { z-index: 7; } .preloader-2 li:nth-child(19) { z-index: 6; } .preloader-2 li:nth-child(20) { z-index: 5; } .preloader-2 li:nth-child(21) { z-index: 4; } .preloader-2 li:nth-child(22) { z-index: 3; } .preloader-2 li:nth-child(23) { z-index: 2; } .preloader-2 li:nth-child(24) { z-index: 1; } .preloader-2 li:nth-child(25) { z-index: 0; } .preloader-2 li:nth-child(1) { animation-delay: 0.1s; } .preloader-2 li:nth-child(7) { animation-delay: 0.3s; } .preloader-2 li:nth-child(13) { animation-delay: 0.5s; } .preloader-2 li:nth-child(19) { animation-delay: 0.7s; } .preloader-2 li:nth-child(24) { animation-delay: 0.9s; } .preloader-2 li:nth-child(2) { animation-delay: 0.2s; } .preloader-2 li:nth-child(8) { animation-delay: 0.4s; } .preloader-2 li:nth-child(14) { animation-delay: 0.6s; } .preloader-2 li:nth-child(20) { animation-delay: 0.8s; } .preloader-2 li:nth-child(3) { animation-delay: 0.3s; } .preloader-2 li:nth-child(9) { animation-delay: 0.5s; } .preloader-2 li:nth-child(15) { animation-delay: 0.7s; } .preloader-2 li:nth-child(4) { animation-delay: 0.4s; } .preloader-2 li:nth-child(10) { animation-delay: 0.6s; } .preloader-2 li:nth-child(5) { animation-delay: 0.5s; } .preloader-2 li:nth-child(1) { animation-delay: 0.1s; } .preloader-2 li:nth-child(6) { animation-delay: 0.2s; } .preloader-2 li:nth-child(11) { animation-delay: 0.3s; } .preloader-2 li:nth-child(16) { animation-delay: 0.4s; } .preloader-2 li:nth-child(21) { animation-delay: 0.5s; } .preloader-2 li:nth-child(7) { animation-delay: 0.3s; } .preloader-2 li:nth-child(12) { animation-delay: 0.4s; } .preloader-2 li:nth-child(17) { animation-delay: 0.5s; } .preloader-2 li:nth-child(22) { animation-delay: 0.6s; } .preloader-2 li:nth-child(13) { animation-delay: 0.5s; } .preloader-2 li:nth-child(18) { animation-delay: 0.6s; } .preloader-2 li:nth-child(23) { animation-delay: 0.7s; } .preloader-2 li:nth-child(19) { animation-delay: 0.7s; } .preloader-2 li:nth-child(24) { animation-delay: 0.8s; } .preloader-2 li:nth-child(25) { animation-delay: 0.9s; } |
Вариант 3
1 2 3 4 5 6 |
<div class="preloader-3"> <svg viewBox="-2000 -1000 4000 2000"> <path id="inf" d="M354-354A500 500 0 1 1 354 354L-354-354A500 500 0 1 0-354 354z"></path> <use xlink:href="#inf" stroke-dasharray="1570 5143" stroke-dashoffset="6713px"></use> </svg> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.preloader-3 svg { max-width: 25em; border-radius: 3px; background: #FFF; fill: none; stroke: #BFE2FF; stroke-linecap: round; stroke-width: 12% } .preloader-3 use { stroke: #337AB7; animation: preloader-3-a 2s linear infinite } @keyframes preloader-3-a { to { stroke-dashoffset: 0px } } |
Вариант 4
1 2 3 4 5 6 7 8 9 10 11 |
<div class="preloader-4"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
.preloader-4 { position: relative; display: grid; grid-template-columns: 33% 33% 33%; grid-gap: 2px; width: 100px; height: 100px; margin: 30px auto; } .preloader-4 > div { position: relative; width: 100%; height: 100%; background: #337AB7; transform: scale(0); transform-origin: center center; animation: preloader-4-anim 2s infinite linear; } .preloader-4 > div:nth-of-type(1), .preloader-4 > div:nth-of-type(5), .preloader-4 > div:nth-of-type(9) { animation-delay: 0.4s; } .preloader-4 > div:nth-of-type(4), .preloader-4 > div:nth-of-type(8) { animation-delay: 0.2s; } .preloader-4 > div:nth-of-type(2), .preloader-4 > div:nth-of-type(6) { animation-delay: 0.6s; } .preloader-4 > div:nth-of-type(3) { animation-delay: 0.8s; } @keyframes preloader-4-anim { 0% { transform: scale(0); } 40% { transform: scale(1); } 80% { transform: scale(1); } 100% { transform: scale(0); } } |
Вариант 5
1 |
<div class="preloader-5"></div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
.preloader-5 { display: block; position: relative; width: 150px; height: 150px; margin: 30px auto; border-radius: 50%; border: 3px solid transparent; border-top-color: #337AB7; animation: preloader-5-spin 2s linear infinite; } .preloader-5:before { content: ""; position: absolute; top: 5px; left: 5px; right: 5px; bottom: 5px; border-radius: 50%; border: 3px solid transparent; border-top-color: #BFE2FF; animation: preloader-5-spin 3s linear infinite; } .preloader-5:after { content: ""; position: absolute; top: 15px; left: 15px; right: 15px; bottom: 15px; border-radius: 50%; border: 3px solid transparent; border-top-color: #337AB7; animation: preloader-5-spin 1.5s linear infinite; } @keyframes preloader-5-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } |
Вариант 6
1 2 3 4 5 |
<div class="preloader-6"> <div class='circle'> <div class='inner'></div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
.preloader-6 .circle { width: 325px; height: 325px; display: block; background: #BFE2FF; border-radius: 100%; position: relative; border: 10px solid #337AB7; animation: preloader-6-rotation 2s linear infinite; } @keyframes preloader-6-rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .preloader-6 .circle .inner { width: 200px; height: 200px; background: #337AB7; position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); border-radius: 100%; box-shadow: 0 -130px 0 -75px #337AB7; animation: preloader-6-switch 8s ease-in-out infinite; } @keyframes preloader-6-switch { 0% { top: 50%; transform: translateX(-50%) translateY(-50%); width: 200px; height: 200px; box-shadow: 0 -130px 0 -75px #337AB7; } 25% { top: 50%; transform: translateX(-50%) translateY(-50%); width: 200px; height: 200px; box-shadow: 0 -130px 0 -75px #337AB7; } 50% { top: calc(100% - 55px); width: 50px; height: 50px; box-shadow: 0 -130px 0 75px #337AB7; transform: translateX(-50%) translateY(0); } 75% { top: calc(100% - 55px); width: 50px; height: 50px; box-shadow: 0 -130px 0 75px #337AB7; transform: translateX(-50%) translateY(0); } 100% { top: 50%; transform: translateX(-50%) translateY(-50%); width: 200px; height: 200px; box-shadow: 0 -130px 0 -75px #337AB7; } } |
Вариант 7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="preloader-7"> <div> <div> <div> <div> <div> <div> <div> <div> <div></div> </div> </div> </div> </div> </div> </div> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 |
.preloader-7 div { border: 14px inset #FFF; border-radius: 100%; padding: 4px; animation: preloader-7-spin 15s linear infinite; } @keyframes preloader-7-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } } |
Как Можно использовать и альтернативный вариант, это закрывать не всю страницу сайта, а нужную область, например слайдер или галерею. как сделать?
Сейчас контейнер прелоадера .preloader зафиксирован и перекрывает всю страницу, но им можно перекрыть любой другой блок, секцию или элемент.
Можете сделать пример если не сложно?
Вот например (пример 1)
Там полупрозрачный слой
перекрывает картинку. Точно также можно использовать прелоадер, только соотв. не прозрачный.
Слой перекрывает картинку или другой элемент, а после загрузки страницы он пропадает.
А вообще, куда вы это хотите приспособить?
Может просто путаете прелоадер с ленивой загрузкой или аяксом? (в них тоже иногда крутится иконка при загрузке)
Спасибо) возможно я не так преподношу) но вот есть допустим слайдер, при обновлении страницы идет загрузка а потом открывается слайдер. Или допустим товар на сайте, у всего блока идет загрузка потом показ блока.
Завтра сделаю статейку для элементов, чтобы наглядно было
Спасибо) огромное. Буду ждать)
Напишите в ВК мне или на почту.
Я так подумал, такой прелоадер не лучший вариант для того что вы хотите.
Столкнулся с проблемой. js код на для jquery на декстопе работает отлично. А в мобильном-яндекс браузере прелодер не отключается. Чистый js работает хорошо.
Такой прелоадер лучше вообще отключать через заданный промежуток времени.
На всякий случай, например, если что то загрузиться не может очень долго.
Этот код уберет его через 2 секунды.
Так нельзя делать
Прелоадер должен исчезать только в случае окончания заданного действия
Если это асинхронный код например fetch то удаление нажно ставить в .finally ( () => preloader.remove())
А ставить на таймер некорректно на удаление т.к. прелоадер на то и нужен для того чтобы пока погружаются данные пользователь видел статус
Можно выводить кнопку отмены действия внутри прелоадера по таймеру
Например для fetch abort()
Его в любом случае нужно скидывать по страховке, иначе посетитель может смотреть эту крутилку вечно, если зависнет какой нибудь сторонний скрипт, например, метрика.
Часто такое вижу, просматривая шаблоны.
А если страница не готова к показу спустя пару секунд, максимум 5, то нужно что то менять на сайте.
Ну а ставить кнопку сброса его, тоже сомнительное решение, что на ней написать - "Я тут заглючил, скинь прелоадер" ?