Прелоад через CSS

27 Sep, 2005

Структурирую свою информацию - несколько способов избежания страшненьких джаваскриптов делающих прелоад картинок.

Проблема

Пускай у нас для какого-то элемента по наведению мыши меняется фоновая картинка, типа такого:
  1. a{
  2. background-image:url(default_img.gif)
  3. }
  4. a:hover{
  5. background-image:url(hover_img.gif)
  6. }
В результате когда страничка (и картинка default_img.gif) загрузится и пользователь наведет мышь на ссылку - броузер начнет грузить картинку hover_img.gif и пользователь сразу ничего не увидит. А если картинка немаленькая, то и пару секунд ничего видеть не будет.

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

1. Метод Pixy

Идея проста - что бы исключить прелоад нужно... исключить вторую картинку.

Помещаем обе картинки для HOVER и для DEFAULT в одно избражение и по наведению мышки просто меняем позицию фона:

  1. a {
  2. background: url("img.gif") no-repeat 0 0 ;
  3. }
  4. a:hover {
  5. background-position: 0 -40px;
  6. }
  7. a:active, a#here {
  8. background-position: 0 -80px;
  9. }
Конечно, это означает фиксированую высоту (или ширину) блока для которого мы делаем этот фон. Иначе фоны бы отображались более одного за раз, или еще как-нить криво.

ИЕ однако и тут выпендрился и решил что так как фон меняется, то надо че то дозагружать. Это так называемый flicker эффект - метод борьбы с ним прост - но не всегда реализуем - нужно задать фон для внешнего блока - и тогда ховер эффект реализовывать не смещением позиции фона - а просто его убиранием.
Таким образом в ИЕ можно избавиться от мигания и "дозагрузок" картинок.

Примерно так:

  1. #outer{
  2. background: url("hover_img.gif") no-repeat 0 0;
  3. }
  4. a{
  5. background: url("default_img.gif") no-repeat 0 0;
  6. }
  7. a:hover {
  8. background: none;
  9. }

2. Прелоад через a:link

Таким образом можно закэшировать hover_img.gif для элемента навигации. Селектор a:link "перебивает" просто a - поэтому визуально ничего не изменится, но броузер поместит файл в кэш:
  1. a{
  2. background-image: url("hover_img.gif");
  3. }
  4. a:link,a:visited{
  5. background-image: url("default_img.gif");
  6. }
  7. a:hover{
  8. background-image: url("hover_img.gif");
  9. }
Этот метод в принципе похож на четвертый, но для полноты я описал их отдельно.

3. "Дырявая" картинка

Суть такова - в качестве фоновой картинки берем "дырявую", то есть ГИФ с прозрачными областями. А собственно :hover эффект делаем сменой фонового цвета, а не картинки. Однако нам придется фиксировать высоту и ширину элемента, да и сам эффект будет состоять лишь в смене цвета определенной области - но тем не менее:
  1. a {
  2. background:#ccc url("img.gif") no-repeat 0 0;
  3. }
  4. a:hover {
  5. background-color:#c00;
  6. {
Впервые столь простую идею увидел на Simplebits с год-два назад - сейчас уже не смог найти линк.

К примеру: все следующие изображения сделаны с помощью одной и той же картинки - лишь сменой фонового цвета: *, *, *, *. Фоновый цвет "светит" через прозрачные дыры в картинке. Сама же картинка лишь белого цвета.

Идею можно применять не только для :hover эффектов, но и для многоразового юзания одной картинки в разных цветах.

4. Прелоад через указание фона для чего-нибудь

Можно поместить картинку для :hover в кэш браузера путем таких вот махинаций:
  1. h2 {
  2. background:url("hover_img.gif') no-repeat;
  3. background-position:-1000px -1000px;
  4. }
Отличается от номера 2 только тем, что тут фон прячут позицией, а не "перебиванием" более сильным селектором.

В конце

Все здесь описанное не претендует на оригинальность - скорее структурирую свои же знания - да и вдруг кому-то это окажется полезным. Почти все приемы просты до безобразия. Но в этом вся соль.

Как говорил один человек - я горжусь тем, что так много "украл" у других. :)

Кто знает еще какие-то способы - пишите в комменты. Думаю от этого выиграем мы все.

41 комментариев к “Прелоад через CSS”

1.besenok | 28 Sep, 2005
отлично. структурировать знания в одном месте никогда не помешает, а уж темболее знать несколько способов решить такую проблему - очень неплохо. спасибо, отличная статья! :)
2.ganges | 28 Sep, 2005
Спасибо за структуризацию. Почитав этот пост, вдруг понял как я стал далек от Ослов, ужас, так и CSS 3 можно по запарке начать использовать. :) ИМХО, наиболее эффективный и "безопасный" метод - это метод Pixy Прелоад через a:link с перебиванием - для меня новость, еще раз спасибо.
3.polch | 04 Oct, 2005
Мне кажется, что метод с “Дырявой” картинкой наиболее гибок и креативен. Спасибо.
4.Julik | 11 Oct, 2005
c :link это круто. Но метод Pixy еще очень хорошо применим и без фиксированной ширины. Просто надо сделать _большую_ картинку и (к примеру) поставить иконку кнопки в верхний левый угол, а иконку ролловера в нижний левый. Тогда при "полном" смещении фона еще останется запас на увеличение размера текста или увеличение ширины кнопки
5.VoSi | 12 Oct, 2005
а если с визибилити поиграЦа ?
6.akella | 30 Jan, 2006
Дык спроси - отвечу - это ведь не просто забытый репозиторий моих статей - это блог :) а я живой чувак.
7.beavja | 30 Jan, 2006
Не нашел тут того что мне надо, но прочитал все равно. И за это спасибо.
8.akella | 30 Jan, 2006
2VoSi: К сожалению визибилити мне не помог - не закачивает он (бр.) невидимые картинки
9.CGS | 07 Feb, 2006
Зделал как описано где убираеться flicker эффект для IE. И вправду убралось моргание. Но осталась вот такая значит ерунда: если делать по этому методу , то у нас получаеться, что есть фон нижний (показываем при наведении), сверху ложиться фон верхний (показываем в нормальном состоянии, и убираем при наведении). Так вот браузер всё равно делает запрос на сервер и грузит (или ещё что) картинку фона верхнего. Ни кто не в курсе как от этого избавиться ?
10.akella | 07 Feb, 2006
я так понял это тоьлко в ИЕ? значок загрузки? ну это скорее глюк броузера с фоном для ссылок :(
11.CGS | 08 Feb, 2006
Да только в IE. Про значёк загрузки не совсем понял ? Так что, решения пока ни у кого нет ? И ещё , с хостингом это как нить может быть связано , если да то как ?
12.akella | 08 Feb, 2006
покажи пример - ссылку на глючное место - что бы можно было точнее что то сказать... значок загрузки - это часики около курсора - иногда в ие появляются при наведении на ссылки с фоном...
13.CGS | 08 Feb, 2006
http://www.greenkey.ru Самое верхнее меню.
14.akella | 09 Feb, 2006
я смотрел в ИЕ по моему все отлично. Конечно он будет делать запрос - потому что фон этот нужен. Но загружается он до конца загрузки страницы - у меня по крайней мере.
15.Sergey | 19 Feb, 2006
Ни один из примеров не работает.. Можешь кинуть на мыло реально работающий код?
16.akella | 19 Feb, 2006
Как минимум вариант со смещением позиции фона и изменением цвета фона а не картинки очевидно работают - хоть и другие у меня так и не представилась возможность тестировать. Просто они работают не во всех броузерах одинаково насколько я понял.
17.W@D | 18 Mar, 2006
Я додумался до эффекта "дырявой картинки" сам не знаю каким образом. Но тестил сайт в основном "Оперой" (у которой кэш работает на ура), а IE только на машине и, как следствие, обнаружил дозагрузку картинки только потом. Спасибо за правильное понимание кода. Теперь картинки не подгружаются! Спасибо!!!
18.W@D | 18 Mar, 2006
Как всегда сначала написал потом почитал. Короче проблема дозагрузки с дырявой картинкой решается правильным указанием той части фона, которую следует менять при :hover или :link Вот так: A {background: #FFFFFF url(pic/rama_ot.gif);} A:hover {background-color: #DCDCDC;} Т.е. color - параметр обязательный! А если указать: background: #DCDCDC; то рисунок, даже если он дырявый "затмится" (не будет виден). Также не поможет сдесь повтор строки с указанием другого фона: A:hover {background: #FFFFFF url(pic/rama_ot.gif);} Тут картинка всё равно будет подгружаться. Речь идёт о IE. Спасибо за внимание.
19.Костя | 10 Feb, 2007
Если кому интересно, смотрите Ссылки и окна. Внешний вид и внутреннее содержание.(http://webdesign.site3k.net/conjuncture/append/d/links.html) Там описываются различные варианты оформления, предзагрузки и открытия.
20.kastorskiy | 21 Mar, 2007
Понравился метод с a:link тем, что прелоад и остальное описание ссылок находятся в "одном месте".
21.kastorskiy | 21 Mar, 2007
хм, только кажется метод с a:link не работает... или это я криво что-то сделал...
22.akella | 21 Mar, 2007
Они довольно капризны и сильно зависят от структуры ЦСС и прочего окружения. Рекомендую все же применять что то вроде идейного кеширования(последние методы). К сожалению по эффективности пока джаваскрипт далеко впереди ЦСС в этом вопросе =( Остается пробовать разные решения, посмотрите например последний комментарий вот тут
23.Виталий | 09 Apr, 2010
Спасибо!
24.Константин | 04 Jun, 2007
Поправим еще одну небольшую ошибочку в методе с убиранием фона. Сменим a:hover на а, дабы не смущать читателей... ) a {background: url(”default_img.gif”) no-repeat 0 0;}
25.Константин | 04 Jun, 2007
Поправим еще одну маленькую ошибочку в методе с убиранием фона. Сменим "a:hover" на "a", дабы не смущать начинающих читателей... ) a {background: url(”default_img.gif”) no-repeat 0 0;}
26.AndroNick | 12 Jun, 2007
Я лично пользовался JavaScript: function AddPicture(){ var p1=new Image(); i.src='my_img1.gif'; var p2=new Image(); i.src='my_img2.gif'; } во всех браузерах работает на ура...
27.AndroNick | 12 Jun, 2007
Может и не в тему, но я лично использовал JavaScript: var p1=new Image(); p1.src='my_img1.gif'; var p2=new Image(); p2.src='my_img2.gif'; ... во всех известных мне браузерах работает на ура.. рисунки подгружаются один раз а дальше просто:
28.AndroNick | 12 Jun, 2007
да блин... вечно обрезается... пишу еще раз:
29.AndroNick | 12 Jun, 2007
гы, теперь понял!! забыл теги убрать )) : IMG src="my_img1.gif" onMouseOver='this.src=p2.src;' onMouseOut='soft.src=soft_n.src;'
30.strix | 09 Jul, 2007
спасибо за хорошую статью. Хороший способ написать вначале цсс-файла фильтр: html { filter: expression(document.execCommand("BackgroundImageCache", false, true)); }
31.AleksandrIII | 05 Dec, 2007
А как сделать, без ява скрипта, замену фона без ссылки или так чтобы ссылка не отображалась?
32.Oleg A | 24 Mar, 2008
А как подгрузить картинку для предпросмотра в браузер при выборе ее в форме? Например: p1.src=’C:/Photo/my_img1.gif’' В IE5, IE6 получается, а в остальных (IE7, FireFox, Opera) - нет
33.Oleg A | 24 Mar, 2008
А как подгрузить картинку для предпросмотра в браузер при выборе ее в форме? Например: p1.src=’C:/Photo/my_img1.gif’' В IE5, IE6 получается, а в остальных (IE7, FireFox, Opera) - нет
34.Oleg A | 24 Mar, 2008
А как подгрузить картинку для предпросмотра в браузер при выборе ее в форме? Например: p1.src=’C:/Photo/my_img1.gif’' В IE5, IE6 получается, а в остальных (IE7, FireFox, Opera) - нет
35.oxyk | 31 Mar, 2008
что делать с прозрачными пингами??? не могу им фон дать, двигать тоже особо не получится из-за ие6 бага на пинги. и моргает в ие7 есть идеи какие-нибудь? (переделать их в другой формат не могу - фон под ними с градациями :(((
36.akella | 31 Mar, 2008
6му интернет эксплореру придется обойтись без прелоада. Только и всего. Всем остальным броузерам можно сделать полупрозрачные ПНГ и все будет загружаться единовременно.
37.евген | 05 Apr, 2009
Статья хорошая.Я вот хочу сделать страничку с наложенными друг на друга блоками div.Идея в том,что бы при наведении на видимую часть блока он всплывал в верх,а в нём информация разная,картинки.Подскажи как сделать.У меня не получилось.
38.cssing :: Архив :: Применение clip для PNG в ИЕ | 01 Oct, 2008
[...] нам использовать background-position. То есть вся крутость от прелоадов и спрайтов со всякими сдвиганиями фона [...]
39.kapaev | 11 Feb, 2009
вобщем поэксперементировал я с вашими способами... все работает, но с мелкими косяками в разных броузерах. т.е. в основном в плорере... основной косяк начинается именно с подменой-заменой или дозагрузкой ПНГ... в некоторых условиях (в ИЕ) фон или даже картинка не заменяется, а накладывается поверх, и в связи с этим ролловер выглядит крайне плохо... а еще заметил, что прозрачные области ПНГ не раегируют на маусовер )) - способ описанный тут http://cssing.org.ua/2008/10/01/clip-it-baby/ -
40.Paul | 22 Jul, 2010
У меня дилетантский вопрос - а как нужно написать ссылку в HTML коде? Нужно ли загружать свою картинку к ссылке HTML? Спасибо заранее. З.Ы. Статья - супер)
41.Flank | 20 Oct, 2011
Спасибо, пригодилось! Первые два метода кажутся наиболее дельными. Хотя мне больше нравится прелоад через javascript.