Адаптация мобильной страницы - мультисхемный анализ

внешний интерфейс CSS

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

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

Пиксели:

1. Физические пиксели (пиксели устройства)

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

2. Независимые от устройства пиксели

Аппаратно-независимый пиксель, также известный как пиксель, не зависящий от плотности, можно рассматривать как точку в компьютерной системе координат, представляющую виртуальный пиксель (скажем, пиксель CSS), который может использоваться программой, а затем преобразовываться в физический пиксель связанной системой.

3. Соотношение пикселей устройства

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

设备像素比 = 物理像素 / 设备独立像素
以iphone6为例:
iphone6的设备宽和高为375pt * 667pt,可以理解为设备的独立像素,而其设备像素比为2.固有设备像素为750pt * 1334pt

Получено через: window.devicePixelRatio.

Соотношение пикселей устройства является стандартом для определения того, является ли это экраном высокой четкости.Когда dpr больше 1, это экран высокой четкости.Как правило, dpr является целым числом, но некоторые модели Android не являются целыми числами.

4. css-пиксели

Единица длины, используемая в CSS и JS. единица пикселей

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

1、屏幕布局视口大小(下面会讲到)
2、屏幕的分辨率(物理像素)

Для экрана определяются его физические пиксели. Размер визуального окна просмотра наследуется от окна просмотра макета, а ширина в визуальном окне просмотра — это число пикселей CSS. Следовательно, связь между физическими пикселями и пикселями на экране — это связь между физическими пикселями и количеством пикселей в окне просмотра макета.

比如iphone6,期物理像素为750,如果没有设置布局视口时,viewport为980px
此时:1物理像素长度等于980/750px = 1.3067px的长度
由于像素都是点阵的,故1物理像素相当于1.3067px * 1.3067px方格。
当在meta中设置了如下配置时
<meta name="viewport" content="width=device-width">
相当于把布局视口设置为设备的宽度(即上面讲到的设备独立像素), 对于iphone6就是375px。
此时1物理像素长度等于375/750px = 0.5px的长度,故1物理像素相当于0.5px * 0.5px的方格。

Область просмотра:

1. Окно просмотра макета:

В HTML имя в метаданных обычно представляет собой поле области просмотра, которое представляет собой область просмотра макета элемента управления. Окно просмотра макета обычно задается производителем браузера. До популярности мобильного Интернета большинство страниц в Интернете делались для просмотра на компьютере, а адаптации под мобильный терминал вообще не было. С развитием мобильных терминалов просмотр компьютерных страниц на мобильных телефонах стал очень популярным явлением. С другой стороны, ширина страницы на стороне компьютера большая, а ширина на мобильной стороне ограничена.Если вы хотите увидеть всю веб-страницу, будет длинная полоса прокрутки, что выглядит очень хлопотно. Поэтому, чтобы пользователи могли хорошо отображать веб-страницы на маленьких экранах, производители браузеров устанавливают очень большое окно просмотра макета, обычно около 768 пикселей. Между 1024px наиболее распространенная ширина составляет 980. Это позволяет пользователю видеть большую часть содержимого и выбирать увеличение и уменьшение масштаба в зависимости от конкретного содержимого.

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

Доступ к видовым экранам макета можно получить через:

document.documentElement.clientWidth(clientHeight) // 布局视口的尺寸。
2. Визуальный вьюпорт:

Размер видимой области браузера, то есть площадь веб-страницы, которую видит пользователь. (ширина окна просмотра макета, от которой наследуется его ширина)

window.innerWidth(innerHeight)  // 视觉视口尺寸
3. Идеальное окно просмотра:

Хотя окно просмотра макета решает проблему просмотра веб-страницы на стороне ПК на мобильном терминале, оно полностью игнорирует размер самого мобильного телефона. Поэтому Apple представила идеальное окно просмотра, которое является наиболее идеальным окном просмотра макета для устройства, и пользователю не нужно масштабировать страницу, чтобы идеально отобразить всю страницу. Самый простой способ сделать это — изменить ширину области просмотра макета на ширину экрана.

Его можно получить через window.screen.width.

<meta name="viewport" content="width=device-width">

Как мобильный терминал адаптируется к разным экранам? Самый простой способ - установить окно просмотра следующим образом:

<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

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

масштабирование области просмотра

Для указанных выше настроек на разных экранах количество физических пикселей, соответствующих пикселям CSS, неодинаково.

При обычном экране, когда dpr=1,

1 длина CSS-пикселя соответствует 1 физическому пикселю, а 1 CSS-пиксель соответствует 1 физическому пикселю.

На экране Retina, если dpr=2,

1 длина CSS-пикселя соответствует 2 физическим пикселям, а 1 CSS-пиксель соответствует 4 физическим пикселям.

На данный момент, если вы пишете в css

border: 1px solid red; // 此时1px 对应的宽度是2物理像素的宽度。

Как правило, черновики дизайна мобильных терминалов основаны на дизайне iphone, и черновик обычно имеет размер 750px или 640px, что соответствует физическому пикселю iphone6 ​​и iphone5. В черновике дизайна, как правило, есть некоторые эффекты границы.В настоящее время ширина линии границы составляет 1 пиксель, что соответствует 1 физическому пикселю. Для iphone5 и iphone6, когда ширина = ширина устройства, 1 пиксель css отображается как 2 физических пикселя, поэтому кажется, что линия толще. Как это решить? На самом деле есть много хаков для эффекта границы 1px, один из которых — масштабирование окна просмотра.

Начальный масштаб предназначен для масштабирования видового экрана макета, а начальный масштаб относится к идеальному видовому экрану, то есть начальный масштаб=1 имеет тот же эффект, что и ширина=ширина устройства. Initial-scale=0,5 эквивалентно width=, умноженному на 2 ширины устройства, поэтому установка как Initial-scale, так и ширины может изменить размер области просмотра макета.

<meta name="viewport" content="width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">  

Для iphone6, после добавления вышеуказанных настроек, initial-scale=0.5, что означает, что страница уменьшается в 2 раза и равна ширине экрана.

布局视口width:
width / 2 = 375px; width = 750px;

Таким образом, окно просмотра макета в настоящее время составляет 750 пикселей, а 1 пиксель в настоящее время равен 1 физическому пикселю.

Схема адаптации:

Некоторые основные понятия описаны выше, а конкретная адаптация описана ниже.

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

Вариант первый:

Фиксированная высота, адаптивная ширина.

Эта схема является наиболее используемой схемой в настоящее время, а также относительно простой схемой реализации:

Этот метод использует идеальное окно просмотра:

<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

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

Вариант 2:

Фиксированная ширина области просмотра макета, используйте область просмотра для масштабирования

Такие как:Личи FM,Приложение Netease

Код личи:


if(/Android (\d+\.\d+)/.test(navigator.userAgent)){
  var version = parseFloat(RegExp.$1);
  if(version>2.3){
    var phoneScale = parseInt(window.screen.width)/640;
    if(/MZ-M571C/.test(navigator.userAgent)){
      document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
    }else if(/M571C/.test(navigator.userAgent)&&/LizhiFM/.test(navigator.userAgent)){
      document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
    }else{
      document.write('<meta name="viewport" content="width=640, minimum-scale = '+ phoneScale +', maximum-scale = '+ phoneScale +', target-densitydpi=device-dpi">');
    }
  }else{
    document.write('<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
  }
}else{
  document.write('<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">');
}
    

Область просмотра с фиксированным макетом, для ширины установлено фиксированное значение, общая ширина составляет 640 пикселей, а область просмотра создается динамически в соответствии с шириной экрана. (Черновик дизайна должен быть 640px)

<meta name="viewport" content="width=640, minimum-scale = 0.5625, maximum-scale = 0.5625, target-densitydpi=device-dpi">

Таким образом, ширина веб-страницы lychee FM всегда составляет 640 пикселей. Шкала масштабирования:

var scale = window.screen.width / 640

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

(window.screen.width * dpr) / 640   // 1px对应的物理像素
iphone5.png
iphone5.png
iphone6.png
iphone6.png

третье решение:

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

Такие какНовости NetEase:

<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

С черновиком дизайна 640 пикселей и визуальным эскизом 750 пикселей NetEase обработала это следующим образом:

var width = document.documentElement.clientWidth;   // 屏幕的布局视口宽度
var rem = width / 7.5;                              // 750px设计稿将布局视口分为7.5份
var rem = width / 6.4;                              // 640px设计稿将布局视口分为6.4份

Таким образом, будь то черновик дизайна 750 пикселей или эскиз дизайна 640 пикселей, 1rem равен 100 пикселям на черновике дизайна. Итак, когда px преобразует rem:

rem = px * 0.01;

На эскизе дизайна размером 750 пикселей:

75px 对应 0.75rem, 距离占设计稿的10%;

在ipone6上:
width = document.documentElement.clientWidth = 375px;
rem = 375px / 7.5 = 50px;
0.75rem = 37.5px;   (37.5/375=10%;占屏幕10%)
                     
在ipone5上:
width = document.documentElement.clientWidth = 320px;
rem = 320px / 7.5 = 42.667px;
0.75rem = 32px; (32/320=10%;占屏幕10%)

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

iphone5-2.png
iphone5-2.png
iphone6-2.png
iphone6-2.png

Вариант четвертый:

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

Установите размер шрифта в соответствии с установленным dpr. Такие как:

document.documentElement.style.fontSize = 50 * dpr;
// dpr 为设置的设备像素比。(注意不是设备自身的设备像素比,而是认为设置的dpr)

В этом случае, когда dpr = 1, 1rem = 50px;

1rem = 100px при dpr = 2;

Когда дизайн основан на iphone6 ​​и создается черновик дизайна 750px, dpr=2 в это время, поэтому 1rem равен 100px.Очень удобно преобразовать размер на картинке в rem, просто разделите его на 100 . код показывает, как показано ниже:

var scale             = 1.0;
var dpr             = 1;
var isAndroid         = window.navigator.appVersion.match(/android/gi);
var isIPhone          = window.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio  = window.devicePixelRatio;
// 此处只简单对ios做了伸缩处理,安卓没有做伸缩处理,统一dpr = 1
if ( isIPhone ) {
  scale /= devicePixelRatio;
  dpr *= devicePixelRatio;
}

var viewport        = document.getElementById('viewport');
var content         = 'initial-scale=' + scale + ', maximum-scale=' + scale + ',minimum-scale=' + scale + ', width=device-width, user-scalable=no';

viewport.setAttribute( 'content', content );
document.documentElement.style.fontSize = 50 * dpr + 'px';
document.documentElement.setAttribute('data-dpr', dpr);

Для этой программы

假设肉眼看到的宽度(视觉宽度):visualWidth,令dpr=1时,其1rem对应的宽度为50.

dpr = 1 时, 1rem = 50px, initial-scale=1, 缩放为1。
visualWidth = 50 * 1 = 50;

dpr = 2 时, 1rem = 100px, initial-scale=0.5, 缩放为0.5。
visualWidth = 100 * 0.5 = 50;

dpr = 3 时, 1rem = 150px, initial-scale=0.3333, 缩放为0.3333。
visualWidth = 150 * 0.3333 = 50;

Следовательно, в этом решении 1 бэр соответствует одному и тому же расстоянию до невооруженного глаза на всех экранах, поэтому общее количество бэр под разными экранами разное, общее количество бэр под большим экраном больше, чем под маленьким экраном. Например, под iphone6 ​​общая ширина 7,5рем, а под iphone5 общая ширина 6,4рем. Поэтому эта схема не может восстанавливать черновик дизайна по процентам.Поэтому при написании стилей, процентов, flex и других раскладок нужно использовать для больших элементов, а rem нельзя использовать напрямую.

Подробное руководство по этой программе можно найти в этой статье.портал

iphone5-3.png
iphone5-3.png
iphone6-3.png
iphone6-3.png

Вариант пятый:

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

Разделите экран на фиксированное количество блоков по 10:

var width = document.documentElement.clientWidth;   // 屏幕的布局视口宽度
var rem = width / 10;                               // 将布局视口分为10份

Таким образом под любым экраном общая длина 10рем. Значение, соответствующее 1rem, также не является фиксированным и связано с шириной области просмотра макета на экране.

Для динамически генерируемых видовых экранов их принципы аналогичны, а масштабирование задается в соответствии с dpr. Загляните на Таобао:

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale;
if (isIPhone) {
  if (devicePixelRatio >=3) {
    dpr = 3;
  } else if (devicePixelRatio >=2) {
    dpr = 2;
  } else {
    dpr = 1;
  }
} else {
  dpr = 1;
}
scale = 1 / dpr;

Taobao выполняет масштабирование только для iphone, для android все dpr=1, scale=1 означает отсутствие обработки масштабирования.

Эта схема похожа на схему 3, но просмотра просмотра масштабируется, что может восстановить проект дизайна в процентах.

iphone5-4.png
iphone5-4.png
iphone6-4.png
iphone6-4.png

Проблемы, которые необходимо решить при адаптации:

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

1. Для решения проблемы 1px на экранах высокой четкости на самом деле существует множество способов взлома, здесь мы говорим только о масштабировании области просмотра. Сначала установите область просмотра макета на физические пиксели экрана высокой четкости. Таким образом, 1 пиксель в CSS — это 1 физический пиксель, а линии, видимые таким образом, — это настоящий 1 пиксель. Но в это время ширина области просмотра больше ширины устройства, и появятся полосы прокрутки. Поэтому область просмотра масштабируется так, чтобы ширина области просмотра соответствовала ширине устройства.

У команды Taobao много проблем с масштабированием на стороне Android, поэтому dpr обрабатывается 1, поэтому сторона Android не решила проблему 1px.

2. На мобильном телефоне с большим экраном вы должны видеть больше текста абзаца в строке, чем на мобильном телефоне с маленьким экраном.

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

.selector { 
  color: red; 
  font-size: 14px; 
}

[data-dpr="2"] .selector { 
  font-size: 28px; // 14 * 2
} 

[data-dpr="3"] .selector { 
  font-size: 42px; // 14 * 3
}

Для схемы 4, независимо от случая, визуальная ширина, соответствующая 1rem, одинакова, а соответствующие широкоэкранные и мелкоэкранные мобильные телефоны имеют разную визуальную ширину, поэтому при установке шрифта в rem единицы также может удовлетворить потребности мобильных телефонов с большим экраном.В одной строке отображается больше шрифтов.

Сравнение пяти вариантов:

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

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

Схема 1 восстанавливает расчетную осадку в небольшой степени и не будет здесь объясняться.

Схема 2 выполняет процентную адаптацию, частично адаптацию на 1 пиксель и не адаптирует шрифт.

Схема 3 выполняет процентную адаптацию, не адаптацию 1px, а адаптацию размера шрифта.

Схема 4 не делает 100% адаптацию, макет использует 100% и гибкую верстку, и выполняется адаптация 1px, а для текста абзаца rem может использоваться как единица напрямую, и никакой адаптации не требуется.

Схема 5 выполняет процентную адаптацию с адаптацией 1px и адаптацией размера шрифта.

Проблемы, возникшие в проекте:

Вариант 4 и вариант 5 были использованы в нашем проекте.

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

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

На самом деле адаптация 1px очень хороша со стороны Apple, Со стороны Android телефоны разных производителей очень разные, и проблем с адаптацией много. Вот почему в большинстве решений отказываются от адаптации 1px на стороне Android. Однако недавно я увидел, что многие веб-сайты используют закрытый атрибут Android для совместимости с некоторыми моделями Android. Система Андроид.

Здесь г-н Мо пересмотрел гибкую схему, которая совместима с эффектом 1px большего количества моделей Android. статьяпортал

Он дал сжатую версию плана.Я посмотрел исходники и написал заново.Не знаю, есть ли проблема, но эффект тот же.

var dpr, scale, timer, rem;
var style = document.createElement('style');

dpr = window.devicePixelRatio || 1;
scale = 1 / dpr;

document.documentElement.setAttribute('data-dpr', dpr);
var metaEl = document.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'target-densitydpi=device-dpi, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
document.documentElement.firstElementChild.appendChild(metaEl);
document.documentElement.firstElementChild.appendChild(style);
if (980 === document.documentElement.clientWidth) {
  metaEl.setAttribute('content', 'target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1');
}

function refreshRem () {
  var c = '}';
  var width = document.documentElement.clientWidth;
  var isPhone = window.navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i);
  if (!isPhone && width > 1024) {
    width = 640;
    c = 'max-width:' + width + 'px;margin-right:auto!important;margin-left:auto!important;}';
  }
  window.rem = rem = width / 16;
  style.innerHTML = 'html{font-size:' + rem + 'px!important;}body{font-size:' + parseInt(12 * (width / 320)) + 'px;' + c;;
}

refreshRem();

window.addEventListener('resize', function () {
  clearTimeout(timer);
  timer = setTimeout(refreshRem, 300);
}, false);

window.addEventListener('pageshow', function (e) {
  if (e.persisted) {
    clearTimeout(timer);
    timer = setTimeout(refreshRem, 300);
  }
}, false);

Эти решения предназначены только для подавляющего большинства моделей, а некоторые специальные модели в проекте могут иметь особые проблемы и требовать особого обращения. Например, в этой статье автор использует гибкий инструмент для устранения проблем с Xiaomi Max и Honor 8, что требует специальных хаков.портал, у меня нет этого телефона, и я не проверял его.

Для вышеперечисленных пяти схем схема пять кажется наиболее подходящей, но когда в проект внедряется сторонний плагин, может потребоваться его адаптация по одному, например: вводится форматированный текст, а размер шрифта обычно устанавливается в px, вам нужно преобразовать его в rem один за другим. Для схемы 2 вы можете напрямую использовать px в качестве единицы для восстановления проекта проекта на 100%, и вам не нужно адаптировать представленный плагин. Поэтому какую схему использовать в конкретном проекте - это не только выбор фронтенда, но и обсуждение с дизайнером для удовлетворения потребностей дизайна и выбора наиболее подходящей схемы для проекта.

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

Справочная статья:

Глубокое понимание области просмотра в мобильной фронтенд-разработке

Поговорим о решении 1px под Retina

Использование Flexible для реализации терминальной адаптации страниц H5 Taobao

Решение для адаптации мобильного терминала (часть 1)

Анатомия окон просмотра