Простая адаптация с помощью фоновых изображений CSS

Простая адаптация с помощью фоновых изображений CSS

От автора: Эта статья отображает лишь одно из многих решений проблемы адаптивных изображений. До выбора конкретного решения мы предлагаем вам рассмотреть разные подходы, включая эти два: Как избежать дублирования загрузки адаптивных изображений (How To Avoid Duplicate Downloads In Responsive Images ) и Выбор решения для адаптивных изображений (Choosing A Responsive Image Solution).

При разговорах о таких новых стандартах HTML5, как атрибут srcset и элемент picture, а также технологиях серверной стороны, таких как Адаптивный веб-дизайн +компоненты серверной стороны (Responsive Web Design + Server Side Components ) (RESS), простительно, если вы решите, что простые статические вебсайты сейчас не в состоянии поддерживать адаптивные изображения. Однако такое заключение может оказаться преждевременным. Фактически, существует легкий прямой способ доставки адаптивных изображений, поддерживаемых всеми современными веб-браузерами: фоновые изображения CSS.

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

В данной статье мы рассмотрим фоновый подход CSS в несколько этапов:

Сначала сделаем краткий обзор своих целей и требований к адаптивным изображениям.

Затем рассмотрим, как медиазапросы CSS помогают идентифицировать важные характеристики устройств наших пользователей.

Исследуем ключевое свойство CSS background-image, которое дает возможность отвечать этим характеристикам.

Посмотрим на стратегию оптимизации отдельных изображений, составляющих адаптивный набор.

Проэкзаменуем ограничения такого подхода; во многих случаях для их преодоления достаточно весьма простых методов.

И, наконец, опишем его проблемы, к которым не существует обходных путей.

Примечание: Этот подход требует четкого контроля над таблицами стилей вашего сайта, а также его разметки HTML. Если вебсайт зависит от системы управления контентом (CMS), надзор за этими аспектами может оказаться недостаточным.

Потребность в адаптивных изображениях

Адаптивные изображения – важная составляющая адаптивного веб-дизайна (RWD), дизайнерской стратегии, разработанной Итаном Маркоттом (Ethan Marcotte) для того, чтобы совладать с удивительной популярностью мобильных устройств для просмотра Сети. Итан признал, что предыдущая общепринятая практика — разработка отдельных вебсайтов для разных видов устройств — просто не смогла справиться с поразительным разнообразием устройств, применяемых пользователями для получения доступа к создаваемым нами вебсайтам.

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

В большинстве случаев этим адаптивный дизайн и ограничивается — простым регулированием разметки и представления. Однако, продумав только такие вопросы, мы не отдадим должного цели адаптивного дизайна и подведем своих пользователей.

Истинное соответствие контексту пользователя требует дизайна, который принял бы во внимание все аспекты его опыта взаимодействия, и зачастую сюда включаются и изображения. В качестве живого примера возьмите такой вебсайт, как contfont.net. У этого сайта, состоящего из единственной страницы, есть одно основное изображение и обычный набор HTML, таблиц стилей, шрифтов и файлов JavaScript.

Вебсайт великолепно смотрится на компьютерах с супервысоким разрешением экранов, потому что включает версию основного изображения в высоком разрешении. Доставка файла этого изображения, однако, обходится недешево; из размера 1940 × 1229 px после сжатия получается изображение в 446 KB.

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

На iPhone’е изображение 290 × 183 px размером 18 KB смотрится идентично изображению размером 452 KB и 1940 × 1229 px на MacBook Pro.

Что это означает для пользователя, просматривающего сайт, скажем, со смартфона предыдущего поколения? Для него изображение 290 × 183 px размером в 18 KB смотрится точно так же, как увеличенная версия. При отсутствии адаптивного подхода к изображениям вебсайт заставит пользователя скачать 429 KB дополнительных, абсолютно лишних данных. Такое превышение не просто непрактично; оно оказывает существенное влияние на время загрузки вебсайта. Возможно, пользователь смартфона заходит на сайт через обычное 3G-соединение на скорости 2 Mb/сек. Неподача адаптивного изображения увеличивает время загрузки с 1,3 секунд до целых 3 секунд, более чем вдвое!

Полноразмерному изображению для загрузки требуется 3,0 секунды через сеть 3G в сравнении с 1,3 секунды адаптивного изображения.

Основная цель адаптивного подхода к изображениям проста: доставляйте только те пиксели, которые реально могут использоваться устройством пользователя.

Определение окружения пользователя

Если наши вебсайты будут отвечать на устройство пользователя, то нам понадобится способ его идентификации. Сейчас CSS предлагает самый эффективный метод различения устройств. CSS дает нам ответы на два критических вопроса: каков размер дисплея пользователя? И поддерживает ли он изображения в стиле Retina?

Инструментом CSS, дающим нам такую информацию, является медиазапрос. Медиазапросы определяют набор свойств стилей CSS, применимых только к устройствам с определенными характеристиками. Изначально медиазапросы были ограничены медиатипами. Спецификация CSS определяет их большое количество, включая, например, braille (для Брайлевских устройств с тактильным откликом), speech (для синтезаторов речи), tty (только для устройств с моноширинным шрифтом, таких как телетайпы) и tv (для устройств телевизионного типа с низким разрешением и без возможности прокрутки). Сейчас два единственных медиатипа, поддерживаемых всеми браузерами – это print (для отпечатанного материала, разбитого на страницы) и screen (для экранов компьютеров).

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

Вот как медиазапросы могут помочь в решении дилеммы предыдущего раздела. У взятого в качестве примера 15-дюймового MacBook Pro ширина экрана равна 1440 px (здесь мы не принимаем во внимание наличие опции дисплея Retina). Для определения стилей, применимых к экранам такого размера (и более), можно написать себе такую таблицу стилей:

Любые определенные в этом блоке стили будут применяться, лишь когда пользователь заходит на веб-страницу с помощью устройства с размером экрана 1440 px. Однако тут кроется ловушка. Размер экрана не относится к аппаратному обеспечению устройства; скорее, он относится к области просмотра веб-браузера. Область просмотра – это размер окна браузера за вычетом всякого браузерного покрытия, такого как панели инструментов.

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

Медиазапрос состоит из двух частей. Первая, only screen, означает, что стили не нужно применять к распечатанным копиям страницы или прочим нестандартным устройствам. (Ключевое слово only на самом деле не влияет на медиазапрос; оно находится там исключительно для по-настоящему старых браузеров, не поддерживающих свойства медиазапросов. Так как эти браузеры не понимают синтаксиса only, то они просто полностью игнорируют весь блок стилей.) Вторая часть запроса, min-width: 1200px, определяет минимальную ширину экрана, при которой будут применяться эти стили. Соединение этих частей – and – означает, что для применения стилей они обе должны возвращать true.

Для назначения стилей книжной ориентации смартфонов можно применять подобную методику.

В данном случае мы можем продолжить и применить в запросе настоящий размер экрана устройства. Веб-браузеры в смартфонах всегда полноэкранной ширины.

Спецификации свойств min-width и max-width облегчают определение ширины устройства пользователя. К сожалению, не так уж легко идентифицировать дисплей Retina. Разные браузеры пользуются для этого разными синтаксисами, так что приходится прибегать к вендорным префиксам. Еще сильнее ухудшает положение вещей дефект в синтаксисе многих версий Firefox, из-за которого для браузеров Mozilla приходится применять синтаксис и fixed, и broken. В настоящее время рекомендуемый запрос для дисплеев Retina выглядит следующим образом.

Со временем все браузеры начнут поддерживать стандартную нотацию dots per pixel (точек на пиксель) (dppx) и можно будет опустить вендорные префиксы в таблицах стилей.

Свойство фонового изображения CSS

Раз CSS способен надежно определять контекст пользователя, вы можете решить, что поддерживать адаптивные изображения легко. Одним из кажущихся вполне логичными подходов могла бы стать установка display: none для тех изображений, которые не нужно скачивать. Вот проба строго на основе размера экрана. (Для краткости мы пропускаем рассмотрение Retina.)

Вышеприведенный код будет показывать нужное изображение на основе размера экрана; однако свойство display: none на самом деле не препятствует браузерам скачивать скрытые изображения. Браузеры смартфонов закачают большое изображение, хотя оно и не будет показано. К сожалению, этот очевидный подход не соответствует основной цели адаптивных изображений. Проблема возникает из-за того, что браузеры обрабатывают HTML отдельно от CSS. Разметка HTML требует два файла изображения, поэтому браузер исправно доставляет их оба. Впоследствии он анализирует стили CSS, обнаруживает при этом, что одно из изображений не отображается, но уже слишком поздно.

Наши медиазапросы CSS будут работать, только если мы сможем применять их строго к свойствам CSS, а не содержимому HTML. Это кажется невозможным, но существует хитрый способ пользоваться CSS только для группы изображений — свойство background-image. Вот как мы это делаем:

Не добавляйте в разметку HTML ссылки на какие-либо файлы изображений. Вместо этого просто применяйте пустые элементы div или span.

Поместите изображение в пустой div или span, установив его свойства background-image.

Применяйте медиазапросы для замещения соответствующих адаптивных изображений в зависимости от размера экрана и разрешения.

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

Это вкратце о том, как поддерживать адаптивные изображения с помощью фоновых изображений CSS. Любое реальное приложение потребует немного больше кода (например, нам нужен какой-либо способ обозначения размера изображения). Дополнительный код, тем не менее – это стандартный CSS без каких-либо ухищрений.

Создание адаптивных изображений

Имея представление о применении адаптивных изображений, следующий этап – само создание вариантов изображения. Исходное изображение должно быть в самом высоком разрешении из возможных, по меньшей мере таким, которое только сможет доставить ваш вебсайт. (В случае с contfont.net исходное изображение равно 3888 × 2592 px). Выбранная вами графическая программа должна быть способной изменить размеры этого исходного изображения так, чтобы оно вписывалось в контрольные точки вебсайта.

Во время работы в графической программе старайтесь как можно больше оптимизировать изображения даже в высоком разрешении, например, применив установки самого низкого качества, применимые к изображению. Даже пользователям экранов с высоким разрешением придется по вкусу ускорение времени загрузки страницы. Если изображение в формате JPEG, при его экспорте также можно включить опцию progressive. Она позволяет браузеру быстро отобразить низкокачественную версию, пока тот продолжает загрузку полного изображения.

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

Сначала определите изображение самого маленького разрешения, которое удобно доставлять на вебсайт. В случае с contfont.net самый маленький практичный размер окна просмотра – 320 px, соответствующий iPhone’у без экрана Retina в книжной ориентации. (Устройства с меньшими окнами просмотра существуют, и, вероятнее всего, будут существовать в будущем — умные часы, что угодно — но вебсайт с этих устройств вряд ли будет посещаться). На сайте contfont.net окна просмотра размером 320 px оставляет 290 px на ширину изображения, поэтому изображение с самым низким нужным нам разрешением – 290 × 183 px. Заставьте свою графическую программу изменить исходное изображение до этого размера.

Далее создайте для него простую тестовую страницу. Вот какую разметку использую я:

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

Теперь медленно измените размер окна браузера, увеличив его ширину. По мере ее изменения браузер автоматически интерполирует и изменяет размер изображения. По мере увеличения величины интерполяции страдает качество изображения, и в какой-то момент оно будет выглядеть недопустимо плохо. Заметьте, при какой ширине экрана это происходит, так как это станет вашей первой контрольной точкой.

Меняйте размер окна браузера, пока не достигнете ширины, при которой изображение будет выглядеть неприемлемо плохо. Эта ширина экрана станет вашей контрольной точкой.

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

К этому моменту у вас уже будут все контрольные точки и набор подходящих для них изображений. Для дисплеев Retina создайте дополнительные изображения двойного разрешения. Вот полный список изображений вебсайта contfont.net:

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

Преодоление ограничений

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

СДЕЛАТЬ ИЗОБРАЖЕНИЯ ДОСТУПНЫМИ

Стандартный тэг img поддерживает атрибут alt, который обеспечивает альтернативное текстовое описание изображения. Оно важно для доступности вебсайта, так как при описании изображения пользователи со скринридерами полагаются на содержимое alt. У фоновых изображений CSS нет тэга img и, таким образом – атрибута alt, но все же можно сделать их доступными пользователям с ослабленными зрительными возможностями. Для этого добавляем в свою разметку дополнительные атрибуты.

Первый дополнительный атрибут, role, дает скринридеру возможность знать, что div играет роль тэга img, даже если тот не представлен в разметке. Второй атрибут, aria-label, служит той же цели в качестве атрибута alt в img. С помощью этих двух добавлений скринридеры могут объявить пользователям, что данный элемент является изображением, и те смогут прочесть обеспеченное вами альтернативное текстовое описание.

МАСШТАБИРОВАНИЕ ИЗОБРАЖЕНИЙ В БРАУЗЕРЕ

Наш упрощенный подход не поддерживает еще одно полезное свойство тэга img: автоматическое изменение размера и масштабирование браузером. С помощью стандартного img можно просто установить ширину как процентное соотношение содержащего элемента и браузер автоматически подсчитывает ширину и пропорционально масштабирует высоту. Например, рассмотрите приведенный ниже фрагмент, показывающий файл изображения image.jpg, настоящие размеры которого равны 600 × 300 px.

Браузер автоматически подгоняет изображение в содержащий div, уменьшая его ширину с 600 до 400 px. Он также сохраняет его формат, одновременно масштабируя высоту с 300 до 200 px. В результате получается неискаженное изображение, идеально вписанное в страницу.

Благодаря подходу, впервые описанному Грейди Кунлайном (Grady Kuhnline), того же самого эффекта можно добиться с помощью фонового изображения CSS для современных браузеров. (Предупреждаю: описанный в этом подразделе подход не работает в Internet Explorer версии 8 и ниже, так как эти браузеры не поддерживают необходимых свойств CSS.)

Самое легкая задача – масштабирование ширины. Как в случае с тэгом img, можно установить свой элемент внутри div фиксированной ширины; нужно недвусмысленно обозначить, что фон должен заполнить этот div. Разметка HTML отличается не сильно.

Нужно скомбинировать несколько свойств CSS для установления ширины; давайте разберем их по одному:

Установите свойство display элемента #image на inline-block. Без этого свойства CSS будет отображать элемент span как inline, и мы не сможем назначить ему ширину или (через минуту) высоту.

Установите ширину width этого элемента на 100% с тем, чтобы наше изображение заполнило содержащий div.

Установите свойства font-size и line-height на 0 для того, чтобы никакое содержимое внутри span не отражалось на его размере.

Установите свойство vertical-align на middle, чтобы отцентрировать по вертикали элемент изображения в содержащем div.

Установите свойство background-size на 100% для того, чтобы изображение заполняло элемент image.

Установите свойство background-position на 50% 50% для выравнивания фонового изображения внутри элемента image.

Установите свойство background-repeat на no-repeat для того, чтобы браузер не разбивал изображение на мозаику по горизонтали или вертикали.

Получившийся в результате CSS устанавливает стили элемента изображения (элемент span с id элемента «image»).

Предприняв эти шаги, мы позаботились о том, чтобы назначить изображению ширину, но пока еще не затрагивали высоту. Ничто в вышеприведенной разметке или стилях не говорит браузеру о высоте элемента изображения. В результате высота будет по умолчанию своей обычной, что, увы, составляет ноль, потому что в span нет настоящего контента. К счастью, мы можем это исправить, сделав несколько мелких добавлений.

Сначала нужно добавить в разметку дополнительный элемент span. Он размещен внутри элемента изображения.

Теперь назначаем этому внутреннему span несколько свойств стилей.

Установите его свойство display на block с тем, чтобы у него были высота и ширина.

Установите его высоту height на 0, так как у него не имеется реального контента.

Добавьте свойство padding-top, определяя процентное соотношение, равное отношению высоты к ширине изображения.

Последний шаг – ключевой. Хотя span не наследует от своего контента высоту, padding-top заставляет элемент занять пространство по вертикали. Более того, свойство padding-top принимает значения в процентах, где процент относителен к ширине элемента. Наше изображение 970 × 614 px, поэтому мы применяем такое процентное значение: (614 ÷ 970) × 100%, или 63,3%. Теперь браузер гарантирует, что наше изображение при масштабировании сохраняет свой формат.

А теперь все вместе

Чтобы посмотреть, как сочетаются все эти составляющие, вот вам код сайта contfont.net, который мы использовали в качестве примера. Сначала разметка HTML, включающая основное изображение вебсайта.

В таблице стилей определены свойства, которые заставляют изображение пропорционально масштабироваться.

И, наконец, набор медиазапросов подбирает подходящий файл изображения на основании контекста пользователя. (Для краткости в нижеприведенном примере пропущены вендорные префиксы.)

Потенциальные проблемы

Сегодня фоновые изображения CSS – удобный способ доставки адаптивных изображений, но этот подход не идеален. По сути, он нарушает одну из фундаментальных философий стандартов современного Веба — отделение контента от его представления. Продвинутые версии этого подхода, кроме того, страдают от вопросов браузерной совместимости, и он не обращается к более глубоким проблемам адаптивных изображений в целом.

ОТДЕЛЕНИЕ СТИЛЕЙ И СОДЕРЖИМОГО

CSS разработан специально для отделения стилей от контента. В современной сети страницы HTML предоставляют все содержимое вебсайта, тогда как таблицы стилей влияют только на представление этого содержимого. Таблицы стилей не должны определять сам контент. Конечно, разделение стилей и содержимого уже нарушается свойствами CSS content-before и content-after, но они обычно применяются для улучшения презентации (например, путем добавления к элементу иконки).
Определение основных изображений вебсайта с помощью CSS – это совершенно другой уровень. Определяя основной контент в CSS, а не HTML, мы делаем свои вебсайты более сложными для выявления неисправностей, их сложнее поддерживать, а также создается барьер для тех систем, которые пытаются автоматически анализировать наши вебсайты.

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

БРАУЗЕРНАЯ ПОДДЕРЖКА МАСШТАБИРОВАННЫХ ИЗОБРАЖЕНИЙ

Как уже упоминалось, добавленные нами улучшения масштабированных изображений не станут работать в Internet Explorer’е версий 8 и ниже. Такие стандартизированные подходы, как srcset, могут быть обратно совместимы с такими браузерами, но, конечно, сам srcset сейчас недоступен в любых основных браузерах.

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

РЕАЛЬНАЯ ПРОБЛЕМА ПОЛЬЗОВАТЕЛЬСКОГО КОНТЕКСТА

Возможно, самая фундаментальная проблема этого подхода – проблема адаптивных изображений вообще. Для определения пользовательского контекста мы используем ширину экрана и пиксельную плотность, но не ясно, всегда ли соответствует такой подход . Представьте себе, например, пользователя ноутбука, которых выходит в сеть через Wi-Fi точку доступа смартфона.

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

Выходит, эту проблему действительно тяжело решить. Умные люди из веб-сообщества ее обсуждают, но пока никак не приходят к консенсусу по практическому ее решению. Сейчас самой лучшей из имеющихся методик является определение контекста на основе CSS.

Автор: Stephen Thomas

Источник: //mobile.smashingmagazine.com/

Редакция: Команда webformyself.

Метки: ,

Похожие статьи:

Комментарии Вконтакте:

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