25 августа 2014 в 14:54

Как заставить background-size работать в старых IE из песочницы

Всем нам, иногда, хочется сделать красивый фоновый рисунок, в той или иной области сайта.
Еще чаще, в этом случае, нам хочется, чтобы фон не искажался при изменении размеров окна браузера.
Иногда это можно сделать с помощью img, у которого одно из измерений (ширина или высота) заданы в %, иногда нужно более гибкое решение (хотя бы потому, что фон это фон, а на картинке, без специальных приемов, содержимое не разместить).

На ум приходит использование свойства CSS background-image, которое устанавливает фоновое изображение для элемента. Однако, без дополнительных тегов, изображение привязано к левому верхнему углу и обрезается, в случае если размер элемента меньше изображения, и, появляются белые области справа и снизу, если размер элемента больше.

Следующее, что приходит на ум, это поиск дополнительных свойств CSS, которые помогут настроить фон. Ими являются background-repeat, background-position и background-size.
Вот здесь и начинаются проблемы, точнее, с background-size, так как это свойство не поддерживается IE8 и, даже, IE9 в quirks mode.

Есть два решения этой проблемы:
  • Правильное (воспользоваться костылями).
  • Быстрое (оставить пользователей XP, с их последним доступным IE8, без красивого фона).


Если вы выбрали правильное решение, то вот, что есть на просторах Интернет:

1. Родные костыли для IE

Иногда допустимо растягивание и сжатие фонового рисунка, так как пользователь не заметит разницы (градиент в однопиксельную полоску может растянуться на всю ширину страницы и отлично выглядеть)
Для этого добавляем в качестве CSS свойств следующее:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/logo.gif', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/logo.gif', sizingMethod='scale')";

images/logo.gif это путь к фоновой картинке.
Эти свойства понимаются только IE и не навредят нормальным браузерам.

2. jquery.backgroundSize.js

Данный плагин помечен автором, как устаревший, тем не менее, он работает.
Преимущества:
  • Работает для IE6, IE7, IE8.
  • Отключается, если браузер поддерживает свойство background-size.

Недостатки:
  • Подменяет фон либо для всех браузеров (даже поддерживающих background-size), либо не работает в IE9 в quirks mode (а он тоже не поддерживает background-size). Связано со способом подключения через условный комментарий.
  • Не поддерживает обновление рисунка при смене размера элементом (без смены размера окна).
  • Поддерживает только свойства cover и contain.
  • Задавать свойство background-size нужно с помощью jQuery.
  • Требует jQuery для работы.


Чтобы воспользоваться этим решением, необходимо подключить его к странице так:
<!-- The flag should be inserted before loading the script -->
<script>$.debugBGS = true;</script>
<!--[if lt IE 9]> <script src="/path/to/jquery.backgroundSize.min.js"></script> <![endif]-->

И задавать свойство background-size для элементов так:
$(elem).css( "background-size", "cover" );


3. background-size-polyfill

Является развитием решения № 2.
Преимущества:
  • Для работы не нужны внешние библиотеки.
  • Задание свойства background-size происходит почти привычным образом (нужно добавлять -ms-behavior: url(/backgroundsize.min.htc);).
  • Поддерживает и другие значения background-size, помимо cover и contain.

Недостатки:
  • Позиционирует себя как решение для IE8, однако, кое-как, работает с IE7 и не работает в IE6.
  • Не работает в IE8 в quirks mode.
  • Не поддерживает обновление рисунка при смене размера элементом (без смены размера окна).
  • Нет проверки на версию браузера, поэтому вставляет div с img во все элементы с background-size и -ms-behavior, даже если браузер поддерживает это свойство.


Чтобы воспользоваться этим решением, необходимо поместить файл .htaccess, взятый с сайта этого решения, в корень сайта, а backgroundsize.min.htc куда захочется.
При задании свойств CSS для элемента, вместе с background-size нужно задавать свойство -ms-behavior: url(путь_к_вашему_куда_захочется/backgroundsize.min.htc);

4. background-size-emu

Решение базируется на идеях решения № 3.
Преимущества:
  • Для работы не нужны внешние библиотеки.
  • Задание свойства background-size происходит привычным образом (не нужно ничего никуда добавлять).
  • Поддерживает и другие значения background-size, помимо cover и contain.
  • Работает в IE6, IE7, IE8, IE9 в quirks mode.
  • Отключается, если браузер поддерживает свойство background-size.
  • Поддерживает обновление картинки, при смене размера элементом, без смены размера окна браузера.

Недостатки:
  • Обновляет рисунки с полусекундной задержкой, в случае их динамического добавления на страницу и мгновенно — при изменениях размера.
  • Немного грузит старые IE, так как раз в 500 миллисекунд сканирует все элементы DOM на странице и определяет, что нужно обновлять, а что нет.
  • Не может подменять фон для элемента TR.


Чтобы воспользоваться этим решением, необходимо просто подключить скрипт к странице.


Общие проблемы

Решения №2, №3 и №4 вставляют в элемент, для которого задан background-size, абсолютно позиционированный div с img внутри и меняют размер картинки в зависимости от размера элемента.

Так как это тот еще костыль, всеми решениями не поддерживается:
  • Несколько фоновых картинок.
  • 4-х значный синтаксис background-position.
  • background-repeat (нет никаких повторений).
  • Нестандартные значения для background-[clip/origin/attachment/scroll] (если поменять значения, то это ни на что не повлияет).
  • Подмена фона для элементов, в которых не может быть вложенных элементов.


На последок

Все вышеперечисленные библиотеки доступны на GitHub.
@Metafalica
карма
4,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (37)

  • +8
    Старые IE давно надо зарывать, а не писать кучу хаков для них. Microsoft уже и те не поддерживают старые версии.
    • +2
      Есть много причин, по которым могут понадобиться такие хаки.
      При разработках софта, даже сейчас, рабочесть программы под XP — само собой разумеющееся.
      А если программа отображает html страницы в себе? Компонент WebBrowser для .net, к примеру. Там от IE сложно куда-то деться. Только решать еще большие проблемы с интеграцией WebKit.
      • 0
        При таких ограничениях толку от background-size нет. Проще либо сгенерить нужную картинку, либо как максимум соответствующим образом стилизовать обычный <img>. Предлагаемые решения требовательны к ресурсам и банально тормозят, а ведь старый браузер не только медленен, но и скорее всего работает на старой медленной машине. Подобные решения попросту неоправданы. Наилучшим выходом будет плавная деградация, когда оставляется лишь минимально необходимая функциональность.
        • –1
          Я тестил это дело на своем старом ноуте, у которого постоянно перегревается проц и снижается его частота.
          Результат приемлимый и тормозов не заметил. Да, использование проца выше, чем обычно, но что поделаешь.
          Есть проблема, есть решение, какое-никакое, но есть.
          • +1
            вы тестировали это изолировано или в составе веб-приложения?
            • –1
              Тестировал на одной html странице со 127 элементами в body. Фон подменялся для 4 элементов.
  • 0
    Катастрофически не хватает ссылок на репозитории на гитхабе.
    • 0
      Я автор одной из либ… Ссылки на собственные сайты тут нельзя оставлять, а я хочу, чтоб решение проблемы было в соответствующей теме, а не в разделе «Я пиарюсь».

      Интересно, а в комментарии можно ссылки оставить?
      • +1
        Репозиторий на гитхабе — не сайт.
        • 0
          Понял. Добавил.
  • 0
    [deleted]
  • +1
    В данном случае второе быстрое решение — оно же и правильное.
  • 0
    Не тыкайте палочкой, пусть остынет.

    Если действительно нужна поддержка старых браузеров, то тут вариант использовать верстку «старой школы» и применять Progressive Enhancement / Graceful Degradation, вместо навешивания десятков костылей.

    Metafalica, а как себя ведут данные библиотеки с PNG (с прозрачностью) и соответственно с хаками на прозрачность?

    Я лично выбрал для себя IE9.js
    code.google.com/p/ie7-js/
    Он устраняет (субъективно) порядка 95% проблем IE6-9, а то что не устраняет — решается в несколько строк CSS и Graceful Degradation.
    • 0
      Увы, я не знаю о чем ты спрашиваешь, насчет прозрачности.
      PNG прозрачные в качестве фона так и остаются прозрачными при их подмене. Про хаки я ничего не знаю…
      Я не веб разработчик. Лишь нелегкая заставила меня влезть в эту тему и запрогать одну из либ.

      Не всегда деградация приемлима. Вот есть у нас в организации отдел дизайнеров, они рисуют интерфейс для обучающих курсов. Потом этот интерфейс одобряется заказчиком. Потом надо сделать курс именно таким. Ни о какой деградации и речи идти не может, иначе сразу посыпятся жалобы, мол «вы не сделали то», «вы не сделали это».
      • 0
        > PNG прозрачные в качестве фона так и остаются прозрачными при их подмене.
        В ie6?!?!?!

        > Потом надо сделать курс именно таким
        Я вот не могу придумать зачем надо было бы делать background-size для ie6-8.
        Покажите хоть один реальный пример.

        В 99.99% случаев достаточно заранее подготовить кадрированный как надо фон. И для ie6-8 подключить отдельный стилевой файл. Это избавит от проблем описанных в статье и не будет неприятных сюрпризов.

        Ваш же неви(е)данный случай подпадает под тот 0.01%, который мне не известен. Раскройте тайну, покажите пример.

        Единственное с чем нельзя спорить — удобство использования. Но накладывает кучу ограничений.
        Почти во всех описанных хаках есть недочет «Не поддерживает обновление рисунка при смене размера элементом (без смены размера окна)». Вы будете заказчика/клиента просить изменить размер окна?

        Про хак с таймингов выше уже писали замечание.
        Другие проблемы думаю и разбирать не стоит.

        > Ни о какой деградации и речи идти не может, иначе сразу посыпятся жалобы
        Если про жалобы от заказчика, то думаю это надо заранее оговаривать. Если от клиентов, то читаем выше.

        ЗЫ На всякий случай предупрежу.
        Своими комментариями я не осуждаю и тем более не пытаюсь заставить кого-то отказаться от данных хаков. Я, как выше уже писал, и сам пользуюсь ie9.js.
        Я хочу понять целесообразность использования, насколько это оправдано. Особенно во времена, когда ie6-8 существуют за счет «аппарата искусственного дыхания».
        • 0
          Я прогер и делаю софтину для быстрой сборки курсов на основе блоков html (типа хтмл редактор, который оперирует виджетами (меню, панель с картинкой и надписью, галлерея, вопрос с множественным выбором, флеш вопрос и т.д. и т.п.))
          Предназначен он для нулей в хтмл и js. Там просто девочки сидят и мышкой таскают виджеты, даже не зная что такое CSS.

          Курсы должны пахать на XP в IE8. Мне, как прогеру, вовсе не интересно писать кучу говнокода, чтоб мой софт генерил еще более большую кучу говно-js-кода и разметки под разные браузеры.

          Вот пример логотипа одного из курсов.
          То, что нарисовали дизайнеры: filebeam.com/86c29e37ea955ddb60b437042adc99fd.jpg
          То, что можно слепить в моем редакторе за несколько минут вообще не зная html и css, руководствуясь лишь правилами размещения «то в этот контейнер, это в тот»: filebeam.com/639881785d12f2d021f90aeead93d662.jpg
          Курсы должны быть адаптивными и нормально смотреться на смартфонах, планшетах и компах с разными разрешениями, но… бутстрап тут не поможет. Очень уж любят разукрашивать курсы графикой некоторые фантазеры, и все переносы на новые строки, это не то.
          Тем не менее, благодаря background-size: contain все картинки сжимаются и сохраняют пропорции. Не парюсь ни я, ни девочки курсоделы: filebeam.com/c125a5b374322c2c1296c76c6fac5785.jpg

          Если же мне делать это не фоном, а картинкой? Ставим ширину в 100%, тогда для сохранения пропорций, она увеличится и в высоту, что приведет к появлению скролла. Это же приведет уже к неправильному размеру боковых картинок. Получится кака, в общем, а этого нам надо избегать… пережитки другой софтины, замену которой я делаю.

          С background-size все очень просто и для меня, и для курсоделов.

          IE6 я тестил только на правильность растягивания, а не на поддержку PNG. Даже не знал, что там какие-то проблемы. Сейчас нет под рукой, уже обновил до IE7, для тестов. Потом переставлю XP на гляну что будет.
          • 0
            Под логотипом вы подразумеваете заголовок?
            И нас сильно беспокоят градиенты по краям, да? Но при этом остальные косяки мы не видим? Решается, в общем-то, первым вариантом (через фильтры) и его более чем достаточно.

            Что касается всех остальных картинок, то тут решается всё позиционированием. И использовать основной контент, чем являются остальные картинки, это говнокод ещё тот.

            > Мне, как прогеру, вовсе не интересно писать кучу говнокода, чтоб мой софт генерил еще более большую кучу говно-js-кода и разметки под разные браузеры.

            Но при этом ударим говнокодом, чтобы мало не показалось!

            В общем, этот пример не лезет в 0.01%, ибо это элементарные незнания темы (верстки) и непродуманная структура работы приложения.

            Да и приведенный пример дизайна очень сильно отличается от результата.
            • 0
              > Что касается всех остальных картинок, то тут решается всё позиционированием. И использовать основной контент, чем являются остальные картинки, это говнокод ещё тот.

              Ваш вариант в уме проще и короче, чем сгенерить "<div style = 'width = 100%; height: 100%; background-image: instruments.png; background-position: center center; background-repeat: no-repeat; background-size: contain;'">? Речь идет о картинке с инструментами.

              То что пример дизайна отличается от результата, это да. Редактор все еще в разработке.
          • 0
            Зачем делать самописную прогу?
            Есть же CourseLab, Articulate StoryLine и другие.
            Второй точно поддерживает мобайл и в нём можно получить прекрасные интерактивные курсы.
            Или вы не нашли подходящего варианта на рынке?
            • 0
              У тех нет нужных возможностей.
              У меня будут сетевые курсы, для работы в классе. Тогда курсы являются клиентами, а у препода сервер, который контролирует какой раздел прочитал студент и т.д. Препод может заставить клиента показать какую-то инфу… Сбор отчетов о тесте.
              Планирую встраивать java applet в курсы, чтоб он общался по сети с кем надо.
              • 0
                А как же всякие СДО (LMS)?
                Уже есть поддержка SCORM и различные выгрузки отчётов с правами и разными сотрудниками.
                Можете поставить демку WebTutor и посмотреть насколько прост и дружелюбен интерфейс + можно еще свой функционал допилить (проверено — делал).
                • 0
                  Экспорт в SCORM тоже будет из моего редактора, но начальству реально нужны сетевые версии для классов. Это их основной продукт и ничто другое не дает таких возможностей.

                  Но демку все же заценю, на всякий случай :)
                  Стоп, это ж курс лаб… я его уже видел.
                  • 0
                    Я про что вам и говорю: это клиент-серверное приложение. На сервак закачиваете курсы, админ или преподавать может из списка в БД выбрать и назначить студенту какой-то курса, количество попыток и прочее. Все достижения сотрудника складываются в базу.
                    Есть встроенные опросы, форумы, права доступа, группы.
                    Я не рекламирую, но чего еще вам не хватает чтобы пилить свою систему?
                    • 0
                      Начальству еще очень важно, чтобы сразу над одним курсом могли работать много челов.
                      Как в нынешней ихней проге Hyperservice, сделанной ими самими.
                      Челов 5 открывает один и тот же проект и делают его.

                      В курс лабе так нельзя, мы даже связывались с ними, могут ли они сделать такую возможность для нас, но они отказались.
        • 0
          А может быть дело в том, что я не шарю в html и css и не знаю, как сделать аналогичные вещи, проще чем с background-size для меня и тех, кто будет эти курсы делать.
          Нелегкая очень непредсказуемая штука…
          • 0
            Может тогда стоит изучить эту область, а не делать очередной WYSIWYG редактор начала 2000х годов, не разобравшись чего он штампует на выходе?
            • 0
              На разработку софтины год, некогда изучать. Пошел наиболее удобным способом.
              То что он штампует на выходе нравится начальству. В конечном счете, юзера получат курсы, и им неважно как они были сделаны, если они есть и работают.
              • 0
                Надеюсь немного будет курсов, как ранее представленный, а то не дай бог на выходе получится тоже что и у Вас… без рук и ног :)
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Тем не менее ответа на поставленный ранее вопрос это не даёт :)
            • 0
              Проверил png в IE6: filebeam.com/f2b50fa52d9a49c4e4277c7d415a8d7c.jpg
              Фон дива зеленый
              У картинки фон бурый с прозрачными квадратами, которые оказались вовсе не прозрачными.
              • 0
                Это без хаков на прозрачность, а как с ними — не знаю, ибо не пользуюсь.
                • 0
                  C хаками прозрачность пашет, а вот background-size — нет. Неважно что установлено, фон растягивается на 100% 100% и искажается при смене размера окна.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      Не, хаки это либа, используемая здесь: ie7-js.googlecode.com/svn/test/png-background.html, чтобы исправлять ошибки ie6.

                      Инфу по твоей ссылке я прочитал и понял, однако, для чистоты эксперимента тестил png-24
  • 0
    [deleted]
  • 0
    Где же были эти либы лет пять назад… кучу нервов сэкономил бы.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.