Подробное объяснение адаптации мобильного терминала (краткая версия)

Примечания

предыстория истории

Недавно при разработке проекта мобильного терминала к продукту было выдвинуто требование «пользовательской страницы».DevToolsЭто было гладко и плавно, пока я не отправил его в тестовую среду для доступа к странице с разными реальными машинами, но обнаружил очень серьезную проблему: когда экран с большим увеличением Android отображает пользовательский интервал между компонентами страницы, он будет намного больше чем iPhone. (расстояние между компонентами определяетсяjsкодовое управлениеstyleстили), в то время как стили внутри компонентов не сильно отличаются между ними (стили внутри компонентов определяютсяcssкодовое управление), это волшебство! Начинайте восхождение.

Схема адаптации стиля нашего мобильного проекта используетlib-flexibleсхема, поэтому используется при использовании js для управления стилемlib-flexibleимущественный методpx2rem, поэтому при работе с расстоянием между компонентами используются следующие методы обработки:

const { margin: { top = 0, right = 0, bottom = 0, left = 0 } } = data
// left和right表示内边距,使用padding-*进行设置;
// top和bottom表示外边距,使用margin-*或[top|bottom](吸顶|吸底布局)进行设置
const _px2rem = (pxValue) => {
  const dpr = window.lib.flexible.dpr
  return window.lib.flexible.px2rem(pxValue / 1 * dpr)
}
this.style['padding-left'] = `${_px2rem(left)}rem`
this.style['padding-right'] = `${_px2rem(right)}rem`
if (this.fixed) {
  if (this.fixed.type === 'top') {
    this.style.top = `${_px2rem(top)}rem`
  } else {
    this.style.bottom = `${_px2rem(bottom)}rem`
  }
} else {
  this.style['margin-top'] = `${_px2rem(top)}rem`
  this.style['margin-bottom'] = `${_px2rem(bottom)}rem`
}

верить правильноlib-flexibleУчащиеся, знающие исходный код, могут сразу увидеть проблему:

    const dpr = window.lib.flexible.dpr
    return window.lib.flexible.px2rem(pxValue / 1 * dpr)

lib-flexibleВ исходниках есть такой раздел для получения и установкиwindow.lib.flexible.dpr,который:

if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

Очевидно,lib-flexibleВозьмите наши мобильные телефоны Android с мощным экраном в качестве// 其他设备下,仍旧使用1倍的方案. Схема модификации очень проста, то есть при оценке модели мобильного телефона добавляем еще и Android-устройство:if (isIPhone || isAndroid) { ... }, после модификации «магическое явление» выше «вернулось в норму» сразу.

Так как я давно занимаюсь разработкойjava webпроект, поэтому я редко сталкиваюсь с разработкой мобильных проектов.Хотя я занимаюсь разработкой мобильных проектов уже некоторое время, есть еще много вещей, которые я не знаю о мобильных проектах, таких какlib-flexibleЭта яма также незабываема после того, как на нее ступишь.

Итак, я воспользовался этой возможностью, чтобы ступить на яму и решил понять.lib-flexibleреализация и移动端适配Это загадочно и загадочно для меня神秘力量. Так что я проверил много отличных статей и сопутствующих материалов об адаптации мобильных терминалов в Интернете.Потратив много времени, я наконец-то понял основные идеи адаптации мобильных терминалов и принципы реализации различных решений.Отдельное спасибо здесь.@ConardLiбольшой пареньЧто нужно знать о мобильной адаптацииЭта статья заставила меня шагнуть в новый мир «адаптации мобильного терминала».

Эта статья находится вЧто нужно знать о мобильной адаптацииНа основе этой статьи были сделаны более подробные дополнения и расширения, чтобы глубже изучить фундаментальные принципы «адаптации мобильного терминала» и попытаться прояснить те, которые, казалось бы, не связаны, но имеют.千丝万缕Различные концепции отношений.

Содержание статьи больше текста, терпеливо прочитайте ее, возможно, у вас есть разные приобретения и чудесные открытия, надеюсь, эта статья сможет вам помочь!

один дюйм

Обычно мы используем физическую единицу измерения дюйма (дюйм) для описания физического размера экрана, например, 17 дюймов для компьютерных мониторов, 6,3 дюйма для дисплеев мобильных телефонов и так далее.
Следует отметить, что этот размер относится к длине диагонали экрана.

尺寸示意图

где единицы преобразования дюймов и сантиметров:1英寸 = 2.54厘米

2. Разрешение

Разрешение обычно делится на разрешение экрана и разрешение изображения.

  1. Разрешение экрана (разрешение экрана) — это точность изображения на экране, определяющая, сколько пикселей может отображать монитор.
  2. Разрешение изображения — это количество пикселей, содержащихся в единице дюйма.
    ppi(пикселей на дюйм) иdpi(точек на дюйм) — это две единицы измерения, которые мы чаще всего используем для описания разрешения;ppiа такжеdpiЧасто встречается смешанное использование. Но есть и различия в полях, которые они используют. С технической точки зрения «пиксели» существуют только в области компьютерного дисплея, а «точки» появляются только в области печати или печати.
    Здесь мы в основном говорим о «пикселях» в области компьютерного дисплея.

2,1 пикселя

Пиксель, маленький квадрат, имеет два свойства: положение и цвет.
Электронные экраны (мобильные телефоны, компьютеры) состоят из нескольких квадратов с определенным положением и цветом.


Картинка на картинке — это увеличенная картинка, а каждый квадратик — это то, что мы называем пикселем

2.2 Физические пиксели

  1. Физические пиксели эквивалентны пикселям устройства (dp:device pixel), как следует из названия, экран дисплея состоит из физических пикселей, и экран может отображать различные изображения, управляя цветом каждого пикселя.pt
  2. Среди них разрешение экрана, о котором мы обычно говорим, относится к разрешению, установленному рабочим столом, а не к физическому разрешению дисплея.

2.3 Пиксели, не зависящие от устройства

На заре смартфонов плотность экрана мобильных устройств была очень низкой, напримерiPhone3, его разрешение320x480,существуетiPhone3На экране то, что мы видим, «настоящее»,1px = 1px,iPhone3На экране может отображаться не более одного320pxширокий элемент. Но если присмотреться, тоiPhone3Обнаружено, что на экране фотоаппарата имеется множество мелких светоизлучающих точек, которые часто называют «зернистостью» Эти светоизлучающие точки представляют собой упомянутые выше реальные физические единицы пикселей, то есть физические пиксели.
С быстрым развитием технологий изменения экрана также меняются с каждым днем. Вскоре появились экраны с более высоким разрешением, написал Джобс 8 июня 2010 г.iPhone4, его разрешение640*960, точноiPhone3дважды. ОднакоiPhone4а такжеiPhone3оба одинакового размера3.5英寸, то в случае одного и того же физического размераiPhone4Как вы использовали удвоенное разрешение на этом фрагменте?3.5英寸на экране?

iPhone3和iPhone4对比

Теоретически изображения и текст одинакового размера на белом телефоне будут масштабироваться в два раза больше на черном телефоне, потому что его разрешение удваивается. Таким образом, не появятся ли позже мобильные телефоны с более высоким разрешением, а элементы страницы будут становиться все меньше и меньше?
Однако это не так: пропорции интерфейса, отображаемого на смартфонах, которые мы используем сегодня, в основном одинаковы, независимо от того, насколько высокое разрешение. ДжобсiPhone4впервые представлен наRetina Display(экран Retina), он решает вышеуказанные проблемы, что также делает его мобильным телефоном разных поколений.


существуетiPhone4Используя экран Retina, поместите2x2Каждый пиксель используется как 1 пиксель, что делает экран более изысканным, но размер элемента не меняется.


Если черный телефон использует технологию экрана Retina, результат отображения должен быть следующим, например, ширина списка составляет 300 пикселей, тогда на горизонтальной линии белый телефон будет использовать 300 физических пикселей для его отображения, а черный телефон на самом деле рендерит, он будет использовать 600 физических пикселей для рендеринга. Мы должны использовать единицу измерения, чтобы одновременно сообщать о различных разрешениях мобильных телефонов, каков размер элементов, которые они отображают в интерфейсе, это единица измерения, независимая от устройства (Device Independent Pixels) для краткости.DIPилиDP. Выше мы сказали, что ширина списка составляет 300 пикселей, на самом деле мы можем сказать: ширина списка составляет 300 независимых от устройства пикселей.


Откройте инструменты разработчика Chrome, мы можем имитировать отображение каждой модели мобильного телефона, каждая модель будет отображать размер, напримерiPhone XОтображаемый размер375x812,действительныйiPhone Xбудет намного выше, чем это, здесь показаны независимые от устройства пиксели

2.3 Соотношение пикселей устройства (dpr)

соотношение пикселей устройстваdevice pixel ratioкороткое имяdpr, что представляет собой отношение физических пикселей к аппаратно-независимым пикселям.

В Интернете браузеры предоставляют намwindow.devicePixelRatioчтобы помочь нам получитьdpr. В css вы можете использовать медиа-запросыmin-device-pixel-ratio,различатьdpr:

@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }

На самом деле понятие соотношения пикселей устройства появилось только после того, как Apple предложила экран Retina, ведь до этого мобильные устройства использовали физические пиксели непосредственно для отображения. Незамедлительно после,AndroidИспользуются и другие технические решения для достиженияDPRбольше, чем1экран, но принцип тот же. из-заAndroidСуществует много размеров экрана, и диапазон разрешений очень велик, в отличие от Apple, у которой есть только несколько фиксированных устройств и собственных размеров. Поэтому, чтобы обеспечить эффект отображения различных устройств,AndroidУстройство разделено на несколько интервалов в зависимости от плотности пикселей устройства:

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

2,4 CSS-пикселя (PX)

Пиксель CSS — это своего рода виртуальный пиксель, который можно понимать как «интуитивный» пиксель, абстрактная единица, используемая CSS и JS. Все длины в браузере указаны в пикселях CSS.px.

В спецификации CSS единицы длины можно разделить на две категории: абсолютные единицы и относительные единицы. px — это относительная единица относительно пикселей устройства (device pixel).

  1. На одном и том же устройстве можно изменить физический пиксель, представленный каждым пикселем CSS (то есть относительность первого аспекта пикселей CSS);
  2. Между различными устройствами физический пиксель, представленный каждым пикселем CSS, может быть изменен (то есть относительность второго аспекта пикселей CSS);

В предыдущем разделе мы видели, что в мобильных браузерах и некоторых настольных браузерахwindowобъект имеетdevicePixelRatio(соотношение пикселей устройства), а его официальное определение: соотношение физических пикселей устройства и независимых от устройства пикселей, поэтому мы можем получить формулу:dpr = dp / dips.

  1. dp(пиксели устройства): физические пиксели устройства;
  2. dips(независимые от устройства пиксели): независимые от устройств пиксели,dips = css像素 / scale(缩放比例)

Тогда без масштабирования 1 пиксель CSS эквивалентен одному независимому от устройства пикселю.

Пиксели CSS можно легко изменить визуально. Например, изменение масштаба страницы браузера — это измененный пиксель CSS. При удвоении пиксель CSS будет покрывать два независимых от устройства пикселя в горизонтальном или вертикальном направлении. например ширина100px, когда размер страницы удваивается, она будет занимать не 100 аппаратно-независимых пикселей по горизонтали, а 200 аппаратно-независимых пикселей; если уменьшить масштаб, она будет занимать только 50 аппаратно-независимых пикселей.


Описание иллюстрации:

  1. Независимые от устройства пиксели (темно-синий фон), пиксели CSS (полупрозрачный фон).
  2. Изображение слева показывает, что когда пользователь уменьшает масштаб, независимый от устройства пиксель покрывает несколько пикселей CSS.
  3. Изображение справа показывает, что когда пользователь увеличивает масштаб, пиксель CSS покрывает несколько независимых от устройства пикселей.

Неважно, уменьшаются или увеличиваются пиксели CSS, количество пикселей одинаково, например100px, независимо от масштаба, он остается100px, но аппаратно-независимые пиксели, которые он занимает, изменились (изменился объем и изменился визуальный размер).

3. Окно просмотра

Область просмотра, переведенная на китайский язык, может называться «окном» или «областью просмотра», что представляет собой видимый диапазон веб-страницы пользователя (имеется в виду диапазон, в котором страница может быть просмотрена).

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

3.1 Три окна просмотра

ppk god для мобильных устройствviewportЕсть много исследований (Сказка о двух видовых экранах — часть первая,Сказка о двух видовых экранах — часть вторая,Meta viewport), ppk считает, что на мобильных устройствах есть триviewport.

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

Если вы установите область просмотра браузера на мобильном устройстве наviewport, некоторые веб-сайты будутviewportслишком узкий и загроможденный, поэтому эти браузеры решилиviewportУстановите более широкое значение, например980px, чтобы даже веб-сайты, предназначенные для настольных компьютеров, корректно отображались в мобильных браузерах. ppk вызывает область просмотра по умолчанию для этого браузера какlayout viewport(Вьюпорт макета).
layout viewportШирина может быть передана черезdocument.documentElement.clientWidthчтобы получить.

Однако,layout viewportШирина больше, чем ширина видимой области браузера, поэтому нам также нуженviewportЧтобы представить размер видимой области браузера, ppk помещает этоviewportназываетсяvisual viewport(визуальный вьюпорт).
visual viewportШирина может быть передана черезwindow.innerWidthчтобы получить.

Джордж Камминс объясняет основную концепцию переполнения стека:

Будуlayout viewportДумайте об этом как о большом изображении, которое не меняет размер или форму. Теперь представьте, что у вас есть рамка меньшего размера, через которую вы можете видеть эту большую картину. Маленькая рамка сделана из непрозрачного материала, через который видна только часть большего изображения, эта часть называетсяvisual viewport.Вы можете держать эту рамку и изображение на определенном расстоянии (уменьшить масштаб), чтобы увидеть изображение целиком, или вы можете приблизиться к изображению (увеличить масштаб), чтобы увидеть его часть. Вы также можете изменить ориентацию этого кадра, но это изображение (layout viewport) никогда не изменится в размере и форме.

ps: visual viewporШирина t относится к ширине видимой области браузера.

Теперь у нас есть два окна просмотра:layout viewportа такжеvisual viewport.

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

  1. Прежде всего, вы можете просматривать все содержимое веб-сайта в обычном режиме без необходимости для пользователей масштабировать и использовать горизонтальные полосы прокрутки;
  2. Размер отображаемого текста подходит, например, абзац14pxразмер текста, который не слишком мал, чтобы его можно было прочитать на экране с высокой плотностью пикселей, в идеале этот абзац14pxНезависимо от плотности или разрешения экрана отображаемый текст имеет примерно одинаковый размер. Разумеется, не только текст, но и другие элементы вроде картинок.

пк поставь этоviewportназываетсяideal viewport(идеальное окно просмотра), которое является третьимviewport- Идеально подходит для мобильных устройствviewport.
ideal viewportдоступныйwindow.screen.widthПолучать.

ideal viewportФиксированного размера нет, разные устройства имеют разныеideal viewport.

Просто установите ширину элемента в css наideal viewportширина (в единицахpx), то ширина этого элемента - ширина экрана устройства, то есть ширина100%Эффект

deal viewportСмысл в том, что независимо от того, какое разрешение экрана, теideal viewportРазработанный веб-сайт не требует от пользователей ручного масштабирования, а также не требует горизонтальных полос прокрутки, которые могут быть идеально представлены пользователям.

3.2 Некоторые подробности о видовом экране макета

  1. макеты css, особенно ширина в процентах, относятся кlayout viewportВычисляется ширина (то есть адаптивная ширина элемента html верхнего уровня страницы (илиwidth: 100%), система отсчетаlayout viewportширина), он меньше, чемvisual viewportнамного шире
  2. layout viewportа такжеvisual viewportвсе измеряются пикселями css, ноvisual viewportразмер будет меняться с увеличением (если вы увеличите масштаб, на экране будет отображаться меньше пикселей css), в то время какlayout viewportразмер останется прежним. (В противном случае ваша страница будет постоянно переформатироваться и пересчитываться в процентах, чего мы не хотим видеть)
  3. Большинство мобильных браузеров изначально отображают всю страницу на одном экране (в режиме полного уменьшения масштаба), что означает, что эти браузеры будут использовать настройки по умолчанию.layout viewportразмер так, чтобы он полностью покрывал экран в полностью уменьшенном режиме, поэтомуlayout viewportа такжеvisual viewportтот же размер
  4. layout viewportШирина и высота равны ширине и высоте содержимого, отображаемого на экране в режиме максимального уменьшения, когда пользователь увеличивает и уменьшает масштаб,layout viewportразмер остался прежним
  5. Минимальный размер области просмотра для ядра Android webkit и IE составляет320px, поэтому, когда вы даетеlayout viewportУстановить меньше320значение, браузер автоматически сбрасывается наideal viewportширина
  6. layout viewportМаксимальная ширина10000px
  7. layout viewportМинимальная ширина примерноideal viewportодна десятая часть ширины

3.3 Meta Viewport

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

3.3.1 Инструкции

<meta>Элемент можно установить, установив егоnameдляviewport, Затем этоcontentУстановите разные инструкции, чтобы вы могли добиться контроляviewportцель.

правильноcontentСинтаксис команды настройки следующий:
<meta name="viewport" content="name=value,name=value">

Каждая пара ключ-значение является инструкцией, а Meta Viewport имеет в общей сложности 6 групп инструкций:

  1. width, задайте ширину области просмотра макета, положительное целое число или ключевое словоdevice-width
  2. initial-scale, установите начальное значение масштаба страницы в виде десятичной дроби больше 0
  3. minimum-scale, минимальное значение масштаба, разрешенное для пользователя, в виде десятичной дроби больше 0
  4. maximum-scale, максимальное значение масштабирования, разрешенное пользователем, в виде десятичной дроби больше 0
  5. height,настраиватьlayout viewportВысота , обладает этим свойством, но, кажется, никто не поддерживает его.
  6. user-scalable, разрешить ли пользователю масштабирование, значение равноyesилиno

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

3.3.2 Что я могу сказать об идеальном окне просмотра

layout viewportможно установить наideal viewport, установивwidth=device-widthЭтот набор инструкций подойдет (но учтите, что вiphoneа такжеipad, будь то портрет или пейзаж,device-widthкогда экран вертикальныйideal viewportширина. )

initial-scale=1Также можно использовать текущийlayout viewportсталиideal viewport,Почему это?

Чтобы понять это, сначала вы должны выяснить, к чему относится масштабирование, потому что значение масштабирования здесь равно1, то есть без масштабирования, но достигаяideal viewportэффекта, поэтому ответ только один,масштабирование относительноideal viewportувеличить, когда правильноideal viewportпровести100%Масштабирование , то есть значение масштабирования равно1когда ты не получаешьideal viewport? Оказывается, это действительно так:


Результаты теста показываютinitial-scale=1также текущийviewportширина становитсяideal viewport, но на этот раз настала очередь IE на Windows Phone. Будь то книжная или альбомная, ширина устанавливается на портретную.ideal viewportширина.

но еслиwidthа такжеinitial-scale=1При этом и есть конфликт?

Например:<meta name="viewport" content="width=400, initial-scale=1">

width=400выражатьlayout viewportширина установлена ​​на400px,initial-scale=1значитlayout viewportширина установлена ​​наideal viewportширина (не обязательно400px), так какой же команде должен подчиняться браузер?

layour viewportЗначение ширины будет принимать значение ширины, заданное параметрами width иideal viewportЗначение ширины проходит через (initial-scaleКратность указанного значения) максимальное значение масштабируемого значения ширины!

Например, вideal viewportширина320под предпосылкой, когдаwidth=400,initial-scale=1когда, в это времяlayout viewportвозьмет400px(потому что400 > 320 / 1) как значение ширины; когдаwidth=400,initial-scale=0.5когда, в это времяlayout viewportвозьмет640px(потому что320 / 0.5 > 400,320 / 0.5 = 640) в качестве значения ширины.

Как показано на рисунке, вiPhoneXсередина,ideal viewportширина иdevice-widthобе375px, затем установитеinitial-scaleдля0.5, то в это времяvisual viewportширина375 / 0.5 = 750. Поэтому из рисунка видноvisual viewport(window.innerWidth)Да750px,в то же времяlayout viewport(document.documentElement.clientWidth) возьмет375pxа также750pxмаксимальное значение в750pxкак значение ширины.

Наконец, подводя итог, возьмем текущуюviewportширина установлена ​​наideal viewportширину, вы можете либо установитьwidth=device-width, вы также можете установитьinitial-scale=1, но у каждого из них есть небольшой дефект, то есть iphone, ipad и IE не будут различать горизонтальный и вертикальный экраны, все они вертикальные экраны.ideal viewportПреобладает ширина. Следовательно, самый совершенный способ написать это должен состоять в том, чтобы написать и то, и другое, например:initial-scale=1Решены проблемы iphone и ipad,width=device-widthТогда решите проблему IE.

3.3.3 О масштабировании и значении по умолчанию для начального масштаба

Как упоминалось ранее, масштабирование зависит отideal viewportдля масштабирования, чем больше значение масштабирования, темviewportШирина будет меньше, и наоборот.

Например, вiphone4середина,ideal viewportШирина320px, если мы установимinitial-scale=2,В настоящее времяviewportширина станет только160pxТеперь понятно, это дубль, это оригинал1pxчто-то становится2px, но1pxстали2pxне оригинал320pxстали640px, но с неизменной фактической шириной,1pxстать таким же, как оригинал2pxДлина одинаковая, поэтому через 2 раза больше нужно оригинала320pxШирина, которую можно только заполнить, теперь требуется только160pxТолько что сделал это. Таким образом, мы можем вывести формулу:

visual viewportширина =ideal viewportширина / текущее значение масштабирования

текущее значение масштаба =ideal viewportширина /visual viewportширина

Теперь давай поговоримinitial-scaleЗначение проблемы по умолчанию заключается в том, что если это свойство не записано, каким будет его значение по умолчанию?

Явно не 1, потому что когдаinitial-scale = 1время, текущийlayout viewportширина будет установлена ​​наideal viewportширина, но, как упоминалось ранее, по умолчанию для каждого браузераlayout viewportШирина, как правило,980px,1024px,800pxждать этих значений, ни одно изideal viewportширина, такinitial-scaleЗначение по умолчанию определенно не равно 1. на андроид устройствахinitial-scaleПохоже, что нет способа получить значение по умолчанию, или для него нет значения по умолчанию. Отказinitial-scaleПо умолчанию.

По тесту можем получить вывод по iphone и ipad:

на iphone и ipad, что бы вы ни далиviewportКакова установленная ширина? Если значение масштаба по умолчанию не указано, iphone и ipad автоматически рассчитают значение масштаба, чтобы на текущей странице не отображались горизонтальные полосы прокрутки (илиviewportширина - ширина экрана).

3.4 Обзор области просмотра

Сначала, если не установленоmeta viewportlabel, то ширина браузера по умолчанию на мобильных устройствах равна800px,980px,1024pxИ так далее, короче, больше ширины экрана. Единица px, используемая здесь для ширины, относится к csspx, за которым следует представление фактических физических пикселей экранаpxНе то же самое.

Во-вторых, у каждого браузера мобильного устройства есть идеальная ширина. Эта идеальная ширина относится к ширине в CSS, которая не имеет ничего общего с физической шириной устройства. В CSS эта ширина эквивалентна100%представленная ширина. мы можем использоватьmetaручка этикеткиviewportШирина устройства установлена ​​на идеальную ширину.Если вы не знаете, какова идеальная ширина этого устройства, то используйтеdevice-widthЭто специальное значение подойдет, и в то же времяinitial-scale=1Также естьviewportШирина функции установлена ​​на идеальную ширину. Итак, мы можем использовать<meta name="viewport" content="width=device-width, initial-scale=1">получить идеалviewport(то есть, как упоминалось ранееideal viewport).

4. Адаптация мобильного терминала

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

4.1 гибкое решение

flexibleРешение представляет собой решение для адаптации мобильных терминалов, исходный код которого был открыт Alibaba в первые дни.flexibleПосле этого используем единообразно на страницеremк макету.

Его основной код очень прост:

// set 1rem = viewWidth / 10
function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
}
setRemUnit();

В приведенном выше коде узел htmlfont-sizeустановить как страницуclientWidth1/10 часть (вьюпорт макета), т.е.1remэквивалентно области просмотра макета страницы1/10,Это означает, что мы будем использоватьremрассчитываются в соответствии с соотношением страниц..

remотносительноhtmlузлаfont-sizeсделать расчет.

Мы устанавливаемdocument.documentElement.style.fontSizeВы можете унифицировать стандарт макета всей страницы.

Возьмите iPhone6 ​​в качестве примера: окно просмотра макета375px,но1rem = 37.5px, то пользовательский интерфейс предоставляет элемент шириной75px(независимые от устройства пиксели), нам просто нужно установить его на75 / 37.5 = 2rem. Конечно, вычислять каждый макет очень громоздко, мы можем использоватьPostCSSизpx2remплагины, которые помогут нам в этом процессе.

давайте внимательно прочитаемlib-flexibleВ исходном коде мы обнаружим, что есть такой раздел для настройкиviewportиз:

var metaEL= doc.querySelector('meta[name="viewport"]');
var dpr = window.devicePixelRatio;
var scale = 1 / dpr
metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

Код прост и понятен, но знаете ли вы, почему он работает? В сочетании с точками знаний, связанными с пикселями и окнами просмотра, которые мы представили выше,Вы поняли, как работает этот код?

Давайте углубимся в причины, по которым этот код написан именно так:

Мобильные браузеры нам не подходят<meta name="viewport"/>В сценарии настройки он полностью отобразит контент страницы на экране в режиме полностью увеличенного выхода по умолчанию.layout viewportа такжеvisual viewportодинакового размера (обычно980px,1024pxд., поведение каждого браузера по умолчанию отличается). Поэтому нам нужно<meta name="viewport"/>сделать настройки, изменитьviewportЭто ширина по умолчанию, чтобы разные экраны устройств могли быть установлены по-разномуlayout viewportа такжеvisual viewportразмер.

вwidth=device-widthДиректива делает ширину окна просмотра макета равной ширине устройства (то есть ширине идеального окна просмотра), однако, как мы упоминали ранее, еслиviewportтакже появляется в настройкахwidth=xxxа такжеinitial-scale=xx, браузер примет максимальное значение какlayout viewportширина.

Вернемся снова к приведенному выше сводному пункту 3.3.3 «О масштабировании и значении начального масштаба по умолчанию», найдем формулу:

ширина визуального окна просмотра = идеальная ширина окна просмотра / текущее значение масштабирования

Это означает, что если мы установим его на устройстве с dpr больше 1initial-scaleдесятичная дробь меньше 1, тоvisual viewportширина становится больше (по сравнению сideal viewportширина), в это время,layout viewportБудет вdevice-widthа такжеvisual viewportВозьмите максимальное значение из значения ширины , как его значение ширины,очевидноvisual viewportЗначение ширины больше!

В то же время произошло еще одно явление:visual viewportЗначение ширины воли иlayout viewportШирина осталась прежней,То есть то, что мы видим на экране окна, должно быть полнымlayout viewportсодержание включено!, что объясняет, почему мы можем видеть содержимое всей страницы без горизонтальной полосы прокрутки.

Это здесь? Если вы используете реальную машину для посещения этой страницы в это время, вы обнаружите, что страница находится в другомdprНа устройстве реализована адаптация стиля, то есть мы написали80px,160px«Правильный» ответ отображается на экране дисплея реальной машины.Например, то, что мы написали в коде, относится к машине Android с dpr, равным 1.80px, в то время как на iPhone 6160px, на iPhoneX есть240px(эти знают, что пропорциональное увеличение — это заслуга rem, мы пока не будем это обсуждать), дело в том, что отображаемые на экране элементы имеют примерно одинаковый размер.

Это значит, что мы достигли цели экранизации! Мы сделали это! , но если мы подумаем над следующим вопросом, то увидим, что он здесь не заканчивается:

Когда мы разрабатываем мобильные страницы, мы обычно следуемiPhone6Размерный чертеж восстанавливается и разрабатывается (т.е. ширина расчетного чертежа составляет750px), и где750pxсерединаpxСоответствует пикселям устройства, то есть физическим пикселям, но в нашем кодеpx(будь то css или js) элементы управления — это css пиксели, то есть логические пиксели.

То есть максимальное значение ширины блочного элемента в нашем коде может быть только375px(в качестве примера возьмем iPhone6), в противном случае больше, чем375pxПоявится горизонтальная полоса прокрутки (потому что аппаратно-независимый пиксель iPhone 6 равен 375), я так испугался, что быстро попробовал и обнаружил, что страница по-прежнему нормально отображается на устройствах с разными dprs, а ширина была полной , и не было горизонтальной полосы прокрутки. ! Почему это? Это не имеет смысла в теории.

В сочетании с приведенной выше сводкой «2,4 пикселя css»在没有缩放的情况下,1个css像素等同于一个设备独立像素а такжеdpr = dp / dips, мы, наконец, знаем ответ:

фактически,initial-scaleУстановка его в десятичное число меньше 1 имеет еще один эффект, заключающийся в уменьшенииcssпиксель иdipsПропорциональное отношение между, т. е. после операции уменьшения, одному аппаратно-независимому пикселю соответствует несколькоcssПиксели, поэтому ответ также уменьшается в n раз с точки зрения физических пикселей и, наконец, достигается «увеличение окна просмотра при создании1物理像素 = 1css像素цель и результат.(На основе:dips = css像素 / scale,dpr = dp / dips)

4.2 vh, схема vw

vh、vwСхема о визуальной ширине вьюпортаwindow.innerWidthи визуальная высота области просмотраwindow.innerHeightРазделить на 100

  • vw(Viewport's width):1vwРавно 1% визуального окна просмотра
  • vh(Viewport's height) :1vh1% от высоты визуального окна просмотра
  • vmin : vwа такжеvhменьшее значение в
  • vmax: Выбратьvwа такжеvhмаксимальное значение в

Если визуальное окно просмотра375px,Так1vw = 3.75px, то пользовательский интерфейс предоставляет элемент шириной75px(независимые от устройства пиксели), нам просто нужно установить его на75 / 3.75 = 20vw.

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

Конечно, идеальных решений не бывает, да и у vw есть определенные недостатки:

  • pxПеревести вvwНе обязательно полностью делится, поэтому есть определенная разница в пикселях;
  • при использовании контейнераvw,marginиспользоватьpx, легко привести к тому, что общая ширина превысит100vw, что влияет на эффект макета. Конечно, мы также можем избежать этого, например, используяpaddingзаменятьmargin, в сочетании сcalc()использование функций и т. д.

5. Безопасная зона

существуетiPhoneXПосле релиза многие производители выпустили телефоны с боковыми экранами.

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

5.1 viewport-fit

viewport-fitЭто атрибут, специально созданный для адаптации к iPhoneX, который используется для ограничения отображения веб-страниц в безопасной зоне.

contain: визуальное окно полностью содержит веб-контент

cover: веб-контент полностью закрывает видимое окно

По умолчанию или установленоautoа такжеcontainТот же эффект.

5.2 env, постоянная

Нам нужно разумно поместить верх и низ в безопасную зону iOS11 добавляет две новые функции CSS.env,constant, который используется для установки расстояния между безопасной зоной и границей. Внутри функции может быть четыре константы:

  • safe-area-inset-left: Расстояние от безопасной зоны до левой границы
  • safe-area-inset-right: Расстояние между безопасной зоной и правой границей
  • safe-area-inset-top: Расстояние от безопасной зоны до верхней границы
  • safe-area-inset-bottom: Расстояние от безопасной зоны до нижней границы

Примечание: мы должны указатьviweport-fitЗатем вы можете использовать эти две функции:

<meta name="viewport" content="viewport-fit=cover">

constantсуществуетiOS < 11.2действует в версии ,envсуществуетiOS >= 11.2, что означает, что нам часто приходится устанавливать их одновременно, чтобы ограничить страницу безопасной областью:

body {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

6. Часто задаваемые вопросы

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

Что касается «UI отлично адаптируется к экранам разных размеров», мы можем использоватьlib-flexibleилиvw、vhрешение решить.

Здесь мы в основном объясняем1pxПроблема и проблема «отображение изображения на экране высокой четкости размыто».

6.1 Проблема с 1 пикселем

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

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

решение:

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

Достоинства: просто, понятно
Недостатки: плохая совместимость, в настоящее время поддерживается только IOS8+, в IOS7 и ниже отображается система Android.0px.

  • IOS8+ уже поддерживает значения px с десятичными знаками,media queryвести перепискуdevicePixelRatioЕсть значение запроса-webkit-min-device-pixel-ratio;
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}
  1. border-imageстроить планы

Недостатки: нужно делать снимки, закругленные углы могут показаться размытыми

.border-image-1px {
    border-width: 1px 0px;
    -webkit-border-image: url("border.png") 2 0 stretch;
    border-image: url("border.png") 2 0 stretch;
}
  • border-width: Укажите ширину границы, можно установить четыре значения соответственно вверху справа внизу слеваborder-width: top right bottom left;
  • border-image: Этот пример означает: от верхней части изображения2px(Нет единиц измерения для значения свойства) Обрезать изображение границы как верхнюю границу, нижнюю2pxОбрезать как нижнюю границу. Обрезка картинки на расстоянии 0 пикселей слева и справа означает, что границ нет, и она отображается в растянутом виде.
  1. background-imageстроить планы
.border_1px{
        @media only screen and (-webkit-min-device-pixel-ratio:2){
            .border_1px{
                background: url(../img/1pxline.png) repeat-x left bottom;
                background-size: 100% 1px;
            }
        }

Недостатки: нужно делать снимки, закругленные углы могут показаться размытыми

  1. box-shadowстроить планы
    Это также может быть достигнуто с помощью теней.Преимущество в том, что нет проблемы со скругленными углами.Недостаток в том, что цвет не так просто контролировать.
div {
    -webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
  • box-shadowИспользование атрибута:box-shadow: h-shadow v-shadow [blur] [spread] [color] [inset]
  • Параметры представляют собой: положение тени по горизонтали, положение тени по вертикали, расстояние размытия, размер тени, цвет тени, изменение внешней тени на внутреннюю тень, последние четыре являются необязательными;
  • Почему в этом примере для размера тени задано отрицательное число? установлен в-1pxзаключается в том, чтобы сделать размер тени немного меньше, чемdivРазмер элемента, чтобы тени с левой и правой стороны не были видны, чтобы тень была только у нижней стороны. Для достижения эффекта линии разделения (односторонней границы).
  1. viewport + rem

Сделайте пиксели CSS равными реальным физическим пикселям, установив масштабирование.
Например: когда соотношение пикселей устройства равно 3, мы масштабируем страницу1/3раз, на этот раз1pxРавен одному реальному пикселю экрана.

const scale = 1 / window.devicePixelRatio;
    const viewport = document.querySelector('meta[name="viewport"]');
    if (!viewport) {
        viewport = document.createElement('meta');
        viewport.setAttribute('name', 'viewport');
        window.document.head.appendChild(viewport);
    }
    viewport.setAttribute('content', 'width=device-width,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);

На самом деле вышеприведенная схема является более раннейflexibleсхема принята.

  1. псевдокласс +transformстроить планы
.border_1px:before{
          content: '';
          position: absolute;
          top: 0;
          height: 1px;
          width: 100%;
          background-color: #000;
          transform-origin: 50% 0%;
        }
        @media only screen and (-webkit-min-device-pixel-ratio:2){
            .border_1px:before{
                transform: scaleY(0.5);
            }
        }
        @media only screen and (-webkit-min-device-pixel-ratio:3){
            .border_1px:before{
                transform: scaleY(0.33);
            }
        }

Этот метод может встречаться в различных сценариях, если вам нужно соблюсти закругленные углы, вам нужно только добавить псевдоклассы.border-radiusТолько что

  1. svg

над намиborder-imageа такжеbackground-imageможно смоделировать1pxГраницы, но все они используют растровые изображения и должны импортироваться извне. с помощьюPostCSSизpostcss-write-svgмы можем напрямую использоватьborder-imageа такжеbackground-imageСоздать svg1pxРамка:

@svg border_1px { 
  height: 2px; 
  @rect { 
    fill: var(--color, black); 
    width: 100%; 
    height: 50%; 
    } 
  } 
.example { border: 1px solid transparent; border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; }

После компиляции:

.example { border: 1px solid transparent; border-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E") 2 2 stretch; }

6.2 Проблема с размытием изображения

6.2.1 Причины

Большинство изображений, которые мы обычно используем, относятся к растровым изображениям (png, jpg...), растровые изображения состоят из пикселей, каждый пиксель имеет определенное положение и значение цвета:

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

пока вdpr > 1На экране растрового изображения пиксель растрового изображения может быть представлен несколькими физическими пикселями, однако этим физическим пикселям нельзя точно присвоить цвет соответствующего пикселя растрового изображения, и их можно только аппроксимировать, поэтому одно и то же изображение вdpr > 1будет размыто на экране:

6.2.2 Решения

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

например: вdpr=2дважды отображает изображение на экране(@2x),существуетdpr=3на экране(@3x).

  1. медиа-запрос
.avatar{
            background-image: url(conardLi_1x.png);
        }
        @media only screen and (-webkit-min-device-pixel-ratio:2){
            .avatar{
                background-image: url(conardLi_2x.png);
            }
        }
        @media only screen and (-webkit-min-device-pixel-ratio:3){
            .avatar{
                background-image: url(conardLi_3x.png);
            }
        }

Только для фоновых изображений

  1. image-set
.avatar {
    background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );
}

Только для фоновых изображений

  1. исходный набор использоватьimgпомеченsrcsetсвойство, браузер автоматически подберет лучшее отображаемое изображение на основе плотности пикселей:
<img src="conardLi_1x.png"
     srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">
  1. использовать SVG
    SVG的Полное название — Масштабируемая векторная графика (Scalable Vector Graphics). В отличие от растровых изображений, основанных на пикселях,SVGОн относится к описанию формы изображения, поэтому по сути является текстовым файлом небольшого размера и не будет искажаться, сколько бы раз его не увеличивали.
<img src="conardLi.svg">

<img src="data:image/svg+xml;base64,[data]">

.avatar {
  background: url(conardLi.svg);
}

Ссылаться на