For a while, I was struggling with compatibility with lower versions of Internet Explorer and thought I could put all that behind me in the Mobile era. But did not expect to the mobile era, in order to deal with the adaptation of each terminal and messy hands and feet. For the occasionally mixed communities, we often find that we take the H5 page of mobile taobao to discuss — how to achieve multi-terminal adaptation of the H5 page of hand Amoy?

So take advantage of this Amfe Ali wireless front end team double 11 technology serialization, with a real case to tell you, Amoy H5 page is how to achieve multi-terminal adaptation, I hope this article for everyone in the Mobile world can lead a more relaxed.

The target

Take a Mobile page of Double 11 as an example, for example, you implement an H5 page similar to the following:

The goal was clear: to make an H5 page like this.

DEMO

Please scan the qr code below with your mobile phone

Pain points

While the H5 page is much simpler than the PC Web page, we struggled to make it work on many different devices. Take a look at the picture below to see how painful this can be:

Click here for more terminal device parameters.

Let’s take a look at the terminal device data to be adapted to hand-washing H5:

See these data, whether dead heart have, or knead a sweat to come out.

The hand-shopping team ADAPTS to the collaborative mode

Early mobile terminal development, the adaptation of terminal devices only belongs to the Android series, but many designers often ignore the adaptation of Android, only a set of iOS platform design draft. But with the emergence of iPhone6, iPhone6+, from now on the terminal adaptation problem is no longer Android series, but also from this time to let the mobile end adaptation into the “miscellaneous screen” era.

The figure above comes frompaintcodeapp.com

What collaboration model should designers and front-end developers adopt to cope with such a terminal device? Maybe you’re interested in that too.

And the basic idea of adaptation and collaboration of the whole hand-washing designer and front-end development is:

  • Select a size as a design and development benchmark
  • Define a set of adaptation rules that automatically fit the remaining two sizes (not just those, you know)
  • Special fit effect gives the design effect

Let’s go back to the previous one, because a picture is worth a thousand words:

I will not elaborate further here. In the process of collaboration between Designers and front-end development: Designers of Mobile store often choose iPhone6 as the benchmark design size, and the design size delivered to the front-end is 750px * 1334px (the height will change with the amount of content). The front-end developer automatically ADAPTS to other sizes through a set of adaptation rules.

According to the above, the designer gave us a 750px by 1600px page:

Front-end development to complete terminal adaptation scheme

Once you get the design from the designer, it’s up to the front-end developer to do the rest. After years of exploration and combat, the mobile terminal is summed up a flexible solution.

How this scheme will be used in actual development is kept in suspense for the time being. Before continuing the detailed development implementation, we need to understand some basic concepts first.

Some basic concepts

Here are some basic concepts (terms) to understand before going into actual combat:

Windows viewport

Simply put, a viewport is strictly a browser window. In desktop browsers, a viewPort is the width and height of the browser window. But on mobile devices it’s a little more complicated.

Viewports on mobile are too narrow. In order to better serve CSS layouts, two viewports are provided: virtual ViewPortVisualViewPort and layout viewPortLayoutViewPort.

George Cummins explains these two basic concepts in detail on Stack Overflow.

In fact, viewport is a very complex knowledge, the above simple description may not help you better understand viewport, and if you want to know more about this, you can read the related tutorial written by PPK.

Physical Pixel

Physical pixel, also known as device pixel, is the tiniest physical component in the display device. Each pixel can be set to its own color and brightness depending on the operating system. It’s the tiny distance between the pixels on these devices that tricks us into seeing images.

Density independent Pixel

A device-independent pixel, also known as a density-independent pixel, can be thought of as a point in a computer coordinate system that represents a virtual pixel (such as a CSS pixel) that can be used by a program and then converted into a physical pixel by the relevant system.

CSS pixel

A CSS pixel is a unit of abstraction used primarily in browsers to accurately measure the content on a Web page. Typically, CSS pixels are called device-independent pixels, or DIPs for short.

The density of the screen

Screen density is the number of pixels that exist on the surface of a device, usually measured in pixels per inch (PPI).

Device Pixel Ratio

The device pixel ratio, or DPR for short, defines the relationship between physical pixels and device-independent pixels. Its value can be calculated by the following formula:

Device pixel ratio = physical pixels/device-independent pixelsCopy the code

In JavaScript, you can get the DPR of the current device using window.devicepixelRatio. In the CSS, media query can be performed using -webkit-device-pixel-ratio, -webkit-min-device-pixel-ratio, or -webkit-max-device-pixel-ratio. For devices with different DPR, Do some style adaptation (for webKit-kernel browsers and WebViews only).

Dip or DP (Device Independent Pixels) relates to screen density. Dip can be used to assist in differentiating between retinal and non-retinal devices.

Condense the above concepts and illustrate them with a picture:

The iPhone6 is known for its device width and height of 375pt by 667pt, which can be understood as the individual pixels of the device; And its DPR is 2. According to the formula above, we can easily know that its physical pixel is 750pt * 1334pt.

The CSS style for an element looks like this:

width: 2px; Height: 2 px;Copy the code

The physical size of CSS pixels is the same on different screens, but the number of physical pixels that CSS pixels correspond to is different. On a normal screen, one CSS pixel corresponds to one physical pixel. On a Retina screen, one CSS pixel corresponds to four physical pixels.

For more information, please click here.

See here, you can feel that in the mobile era screen adaptation in addition to Layout, but also consider the picture adaptation, because it directly affects the page display quality, for how to achieve picture adaptation, again do not do too much detail. Here is a stolen infographic translated by @Nangong Ruiyang from mir.aculo.us:

Meta tags

There are many kinds of tags, but the main one here is the Meta tag of viewPort, which tells the browser how to properly render the Web page, and you need to tell it how big the window is. To develop a mobile page, we need to set the meta tag as follows:


Copy the code

Code to display the width of the page screen defines the window width. The ratio and maximum ratio of web pages are set to 100%.

Stay in suspense, because the next solution will rely heavily on meta tags.

CSS unit rem

Rem is described in the W3C specification as follows:

font size of the root element.

Rem is calculated relative to the font size of the root element. In our scheme, the REM unit is used, which can easily calculate the box model size of elements according to the font size. And this feature is particularly beneficial to us.

Front-end implementation scheme

With some of the previous concepts in mind, let’s look at the actual solution. Across the Mobile Team, we have a library called Lib-Flexible that addresses H5 page terminal adaptation.

What is lib-flexible?

Lib-flexible is an open source library for making H5 adaptations. You can download the relevant files here to get the JavaScript and CSS files you need.

Of course you can use the Ali CDN directly:


Copy the code

Replace {{version}} in the code with the corresponding version number 0.3.4.

Method of use

Flexible_css. js,flexible.js files are added to the Web page:

The first method is to download the file to your project and add it via a relative path:



Copy the code

Or directly load the files of Ali CDN:


Copy the code

It is also strongly recommended that the JS be inlined and executed before all resources are loaded. After executing this JS, a data-dPR attribute is added to the element, along with a font-size style. JS will add a different data-DPR value, such as 2 or 3, depending on the device, and will add a corresponding font size to the HTML, such as 75px.

In this way, the elements on the page can be set in REM units. They do calculations based on the font size values of HTML elements to achieve screen adaptation.

In addition, you can manually set the meta to control the DPR value before introducing the lib-flexible JS that needs to be executed, such as:


Copy the code

Initial-dpr enforces the DPR to the given value. If you manually set the DPR, no matter what DPR the device has, it will be forced to assume that its DPR is the value you set. You are not advised to manually set the DPR. In Flexible, the DPR is determined only for iOS devices. For Android devices, the DPR is always set to 1.

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) {// In iOS, for 2 and 3 screens, use 2x solution, and for the rest, use 1x solution if (devicePixelRatio >= 3 && (! dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (! dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; }} else {// For other devices, use the same scheme DPR = 1; } scale = 1 / dpr; }Copy the code

The essence of the flexible

Flexible actually means to dynamically rewrite meta tags with JS, code like this:

var metaEl = doc.createElement('meta');
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
    document.documentElement.firstElementChild.appendChild(metaEl);
} else {
    var wrap = doc.createElement('div');
    wrap.appendChild(metaEl);
    documen.write(wrap.innerHTML);
}
Copy the code

In fact, he did a few things:

  • Dynamic rewriteThe label
  • toElement to adddata-dprProperty, and dynamically overwritedata-dprThe value of the
  • toElement to addfont-sizeProperty, and dynamically overwritefont-sizeThe value of the

Case of actual combat

With Flexible in mind, let’s go back to the beginning of this article. Our goal is to create an H5 page that works on all terminals. Not much else to say, to do it.

Creating an HTML template

Another waveCopy the code

As described earlier, the configuration required for Flexible is first loaded:


Copy the code

At this time, the corresponding HTML structure can be added to the HTML document according to the design requirements of the graph, such as:


       

  • {poductName}
    The double price of 11 Selections {price} ({preferential})
    {activityType}
    {activeName}
Copy the code

This is just a sample document, so you can write templates in your own style.

To better test the page, configure it with a bit of fake data:

//define data var pageData = { sections:[{ "brannerImag":"http://xxx.cdn.com/B1PNLZKXXXXXaTXXXXXXXXXXXX-750-481.jpg", items:[{ "itemLink": "##", "imgSrc": "Https://placeimg.com/350/350/people/grayscale", "poductName" : "Carter 's1 in grey long-sleeved conjoined climb clothes cotton clothing bag used for travel foot whale 115 g093 male infant children's clothing", "price" : "299.06", "preferential" : "400 100", "activityType" : "hit 5885 units 1 hour", "shopLink" : "# #", "activeName" : }....}]}Copy the code

The next job is to beautify. There are a few things you need to understand before you start writing your style.

Put the visual draft inpxConverted torem

At this point, you probably know that the next thing we need to do is to convert px into REM in visual art. Take a moment to explain.

First of all, in daily work, visual designers give front-end developers visual dimensions based on 640px, 750px and 1125px widths. Or even why? You get the idea (think Retina display).

As shown in the sample design at the beginning of this article, he designed it on a 750px basis. The question then arises, how do we convert px to REM for each element in the design.

I plant visual designers think very thoughtful, will help you to mark out the relevant information on the visual draft.

Currently Flexible will divide the visual draft into 100 copies (mainly for better compatibility with VH and VW in the future), and each copy is called a unit A. At the same time, a rem unit is identified as a 10A. According to our visual draft, we can calculate:

1a   = 7.5px
1rem = 75px 
Copy the code

Font size = 75px; font-size: 14px “> < span style =” font-size: 14px;

In this way, the original px value divided by the REM reference value is all that is needed for the element size conversion on the visual draft. For example, the visual image in this example is 176px by 176px, converted to 2.346667rem by 2.346667rem.

How to calculate quickly

In actual production, if every calculation of REM px conversion, it may feel very troublesome, and may directly affect the usual development efficiency. In order to make the transformation faster, the students in our team have written all kinds of small tools for REM px transformation.

CSSREM

CSSREM is a Sublime Text3 autocomplete for CONVERTING CSS PX values to REM values. This plugin was written by @Zhenglin. Let’s take a look at the plugin:

A tutorial on how to install and configure CSSREM can be found here.

CSS processor

In addition to using editor plug-ins, you can also use CSS processors to help you process. Processors like Sass, LESS, and PostCSS. Let’s briefly look at two examples.

Sass

If you use Sass, you can use Sass functions, mixing macros and other functions to achieve:

@function px2em($px, $base-font-size: 16px) {
    @if (unitless($px)) {
        @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you";
        @return px2em($px + 0px); // That may fail.
    } @else if (unit($px) == em) {
        @return $px;
    }
    @return ($px / $base-font-size) * 1em;
}
Copy the code

In addition to using Sass functions, you can also use Sass’s hybrid macros:

@mixin px2rem($property,$px-values,$baseline-px:16px,$support-for-ie:false){
    //Conver the baseline into rems
    $baseline-rem: $baseline-px / 1rem * 1;
    //Print the first line in pixel values
    @if $support-for-ie {
        #{$property}: $px-values;
    }
    //if there is only one (numeric) value, return the property/value line for it.
    @if type-of($px-values) == "number"{
        #{$property}: $px-values / $baseline-rem;
    }
    @else {
        //Create an empty list that we can dump values into
        $rem-values:();
        @each $value in $px-values{
            // If the value is zero or not a number, return it
            @if $value == 0 or type-of($value) != "number"{
                $rem-values: append($rem-values, $value / $baseline-rem);
            }
        }
        // Return the property and its list of converted values
        #{$property}: $rem-values;
    }
}
Copy the code

For more information, you can click here.

PostCSS(px2rem)

In addition to CSS processors like Sass, @Songqi from our team also developed a tool for NPM, PX2REM. Once pX2REM is installed, you can use it directly in your project. You can also use PostCSS. Using PostCSS plugin postCSS-px2rem:

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var px2rem = require('postcss-px2rem');

gulp.task('default', function() {
    var processors = [px2rem({remUnit: 75})];
    return gulp.src('./src/*.css')
        .pipe(postcss(processors))
        .pipe(gulp.dest('./dest'));
});
Copy the code

In addition to Gulp, you can also use other configuration methods. Click here for more information.

After the configuration is complete, you can use it as follows:

.selector {
    width: 150px;
    height: 64px; /*px*/
    font-size: 28px; /*px*/
    border: 1px solid #ddd; /*no*/
}
Copy the code

After pX2REM processing, it will become:

.selector {
    width: 2rem;
    border: 1px solid #ddd;
}
[data-dpr="1"] .selector {
    height: 32px;
    font-size: 14px;
}
[data-dpr="2"] .selector {
    height: 64px;
    font-size: 28px;
}
[data-dpr="3"] .selector {
    height: 96px;
    font-size: 42px;
}
Copy the code

With these tools in place throughout development, you don’t have to worry about changing px to REM.

Font size not usedrem

We’ve all seen how REM can be used for H5 adaptation. How will the text be adapted? Is it also using REM to do automatic adaptation.

Obviously, we expect to see the same text size underneath the Retina display on the iPhone3G and iPhone4. That said, we don’t want text to get smaller on Retina display, we want to see more text on larger phones, and most font files now come with some sort of dot matrix size, usually 16px and 24px, so we don’t want 13px and 15px.

As a result, rem is not appropriate for paragraph text on H5 pages. Therefore, in Flexible overall adaptation, consider using PX as the unit for text. Only the [data-dPR] attribute is used to distinguish between the text size under different DPR.

div { width: 1rem; Height: 0.4 rem; font-size: 12px; // fontSize} [data-dpr="2"] div {font: 24px; } [data-dpr="3"] div { font-size: 36px; }Copy the code

In order to better facilitate development, in actual development, we can customize a font DPR () Sass hybrid macro:

@mixin font-dpr($font-size){ font-size: $font-size; [data-dpr="2"] & { font-size: $font-size * 2; } [data-dpr="3"] & { font-size: $font-size * 3; }}Copy the code

With a hybrid macro like this, you can use it directly in development:

@include font-dpr(16px);
Copy the code

Of course, this is only for descriptive text, such as paragraph text. However, sometimes the text size also needs to be different from the scene. For example, in the project, there is a slogan that the business side hopes can be adapted to different terminals. For this scenario, REM can be used as the unit of measurement for the slogan.

CSS

Originally wanted to use this page CSS(or SCSS) posted, but considering the length is too long, and so simple page, I think we can easily fix. So I left it out. If you are interested, try Flexible to help you quickly complete H5 page terminal adaptation.

The effect

Finally, let’s take a look at the actual display. I captured the effects on two devices:

iPhone4

iPhone6+

conclusion

In fact, there are many kinds of H5 adaptation programs, there are many tutorials about this aspect on the Internet. Either method has its own advantages and disadvantages. This article focuses on how to use Flexible, a library, for terminal adaptation of H5 pages. Why is it recommended to use the Flexible library for H5 page terminal device adaptation? Mainly because this library has been used for nearly a year, and has reached a relatively stable state. Beyond that, you don’t need to worry about how to convert elements, you can just cut into them according to the corresponding visual draft.

Of course, if you have a better H5 page terminal adaptation solution, please share it with us in the comments below. If you have any problems using this library, please send us an Issue on Github. Our team will work hard to solve relevant Issues.

update

Students responded that they needed an online DEMO. So I spent some time writing a demo, hoping to help students who need it. Note: The DEMO has not been tested on all devices and may differ in details on some devices

DEMO

Please scan the qr code below with your mobile phone

Updated on January 13, 2016

First of all, heartfelt thanks to @Wanyan for helping to step on this pit. I recall that iOS has only stepped on at least one pit from 7 to 8, from 8 to 9. I am really drunk.

The flexible scheme of mobile shopping is temporarily upgraded as follows:

  • For the UA of OS 9_3, perform temporary processing and forcedprfor1, i.e.,scaleAlso for the1The HD scheme on these versions has been sacrificed, but that’s the only way to do it
  • This version is not intended to be released to CDN (nor TNPM), so it is best to manually copy the code inline to updatehtml, the specific code canClick here to download

If you want to reprint, please indicate the source: www.w3cplus.com/mobile/lib-…