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

Хорошие новости состоят в том, что соседского кота можно спасти, также как и ваш компьютер — в этой статье мы рассмотрим основные подводные камни отзывчивого дизайна:

  1. Неожиданные изменения размера шрифта.
  2. Нежелательные стили форм.
  3. Ошибки эмулятора в браузере, сообщающие о проблемах, которых нет.
  4. Медленная анимация на мобильных устройствах
  5. Неверная обработка координат касания.

Приступим!

Базовые требования для понимания материала.

Чтение этой статьи требует от вас базовых знаний об отзывчивой веб-разработке. Их можно почерпнуть, например, из этой статьи.

1. Неожиданные изменения размера шрифта

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

Просто вставьте следующую строчку кода CSS:

html {
    /* Prevent font scaling in landscape while allowing user zoom */
    -webkit-text-size-adjust: 100%;
}

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

Проблема решена.

2. Нежелательные стили форм

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

input[type=text], button, select, textarea{
    -webkit-appearance: none;
    -moz-appearance: none;
    border-radius: 0px;
}

Вы можете спокойно изменять его с учетом используемых вами типов форм и применяемых стилей. Например, если вам надо сбросить стили для всех типов инпутов, измените input[type=text] на input. Но будьте готовы к тому, что такой сброс также повлияет и на чекбоксы с радиокнопками, всегда выбирайте селектор правильно.

3. Ошибки эмулятора, сообщающие о проблемах, которых нет.

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

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

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

4. Медленная анимация на мобильных устройствах

Если вы используете анимации на мобильных устройствах, вам стоит больше внимания уделять их производительности. Собственно, браузеры эффективно анимируют следующие 4 свойства: translate, scale, rotate и opacity. Вот как это может выглядеть:

transform: translate(15px, 40px); /* shift left 15px and down 40px */
transform: scale(2); /* scale to 2 times original size */
transform: rotate(30deg); /* rotate 30 degrees */
opacity: 0.5; /* set opacity at 0.5 */

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

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

Чтобы добиться максимальной кроссбраузерности ваших анимаций, особенно на устройствах Apple, добавьте префикс -webkit- к свойствам трансформации. Например:

-webkit-transform: rotate(30deg);
transform: rotate(30deg)

Более подробные сведения о поддержке анимации свойства transform есть на caniuse.

В качестве дополнения отмечу, что наличие теней (box-shadow) может иногда существенно замедлять анимацию на мобильных устройствах, в зависимости от количества анимаций и общего веса страницы. И в случае с тенями я рекомендую тщательно тестировать производительность анимаций.

5. Неверная обработка координат касания.

Получение координат касания может быть сложным потому, что разные устройства могут хранить эти координаты в разных местах. На некоторых устройствах (IOS) координаты будут там же где и координаты клика, а на других ( Android) их надо искать в других местах. Хорошие новости состоят в том, что координаты касания могут быть найдены в специализированных данных о событиях касания любого мобильного устройства, которое вам надо поддерживать.

Для событий касания надо использовать e.touches[0].pageX вместо e.pageX, чтобы получить правильные координаты касания; то же самое относится и к координатам для Y. Вот несколько примеров, чтобы вы могли оценить, как этот код выглядит на практике.

Координаты клика мышкой вы получаете обычно так:

document.onclick = function(e){
    var x = e.pageX; // get x coordinate of click
    var y = e.pageY; // get y coordinate of click
    console.log('x = ' + x + ', y = ' + y); // show coordinates in console
}

А для получения координат касания нужен следующий код:

document.ontouchstart = function(e){
    var x = e.touches[0].pageX; // get x coordinate of touch
    var y = e.touches[0].pageY; // get y coordinate of touch
    console.log('x = ' + x + ', y = ' + y); // show coordinates in console
}

Если на устройствах не работают e.pageX и e.pageY, они будут по прежнему доступны, но их значением для событий касания будет 0. Я упомянул это потому, что простая проверка их существования в браузере не означает их нормальную работу.

Если вы забыли, где искать координаты события, вы можете найти их с помощью консоли. Я предпочитаю мобильный эмулятор Chrome, потому что он показывает объекты JavaScript в читаемом виде. Вот код, позволяющий узнать какие данные доступны в событии ontouchstart:

document.ontouchstart = function(e){
    console.log(e); // show data from ontouchstart event
}

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

$(document).on('touchstart', function(ev){
    console.log(ev); // jQuery version of event data
    console.log(ev.originalEvent); // native JavaScript version of event data
});

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

Заключение

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