background
Visual Mockup Before front-end development, the visual MM will give us a psd file, which is called a visual draft. For mobile terminal development, in order to achieve high-definition page effects, the specifications of visual drafts often follow the following two points:
question: For mobile phones with DPR=2, why can the HD problem be solved by ×2 the canvas size? For a 2x-sized visual draft, how can we restore the actual width and height of each block in the specific CSS code (i.e., layout problem)? With questions, read on... Some concepts Before conducting a specific analysis, you must first know the following key basic concepts (terms). Physical pixel A physical pixel is the smallest physical display unit on a display (mobile phone screen). Under the control of the operating system, each device pixel has its own color value and brightness value. Density-independent pixel Device independent pixel (also called density independent pixel) can be considered as a point in the computer coordinate system. This point represents a virtual pixel (for example: CSS pixel) that can be used by the program and then converted into physical pixels by the relevant system. Therefore, there is a certain correspondence between physical pixels and device-independent pixels, which is the device pixel ratio we will talk about next. Device pixel ratio The device pixel ratio (DPR) defines the correspondence between physical pixels and device-independent pixels. Its value can be obtained according to the following formula: Device pixel ratio = physical pixel / device independent pixel // in a certain direction, x direction or y direction In CSS, you can use -webkit-device-pixel-ratio, -webkit-min-device-pixel-ratio and -webkit-max-device-pixel-ratio to perform media queries and make some style adaptations for devices with different DPRs (here only for browsers and webviews with the WebKit kernel). In JavaScript, you can use window.devicePixelRatio to get the DPR of the current device. Combining the above concepts, let's take an example - take iPhone 6 as an example: The device width and height are 375×667, which can be understood as device-independent pixels (or CSS pixels). The dpr is 2. According to the above calculation formula, the physical pixels should be ×2, which is 750×1334. This is what I mean by a picture (forgive me for stealing the picture): As can be seen in the figure above, for such a CSS style:
On different screens (normal screen vs retina screen), the size (physical size) of CSS pixels is consistent, but the number of physical pixels corresponding to one CSS pixel is inconsistent. On a normal screen, 1 CSS pixel corresponds to 1 physical pixel (1:1). On a retina screen, 1 CSS pixel corresponds to 4 physical pixels (1:4). Bitmap pixels A bitmap pixel is the smallest data unit of a raster image (such as png, jpg, gif, etc.). Each bitmap pixel contains some display information of its own (such as display position, color value, transparency, etc.). Speaking of this, we have to talk about the display of pictures under retina? Theoretically, 1 bitmap pixel corresponds to 1 physical pixel, so the image can be displayed perfectly and clearly. There is no problem on a normal screen, but on a retina screen the bitmap pixels will not be enough, resulting in blurry images. Let’s use a picture to show this: As shown above: For a retina screen with DPR=2, 1 bitmap pixel corresponds to 4 physical pixels. Since a single bitmap pixel cannot be further divided, it can only pick the nearest color, resulting in a blurred image (note the above color values). Therefore, for the problem of high-definition images, a better solution is to use twice the image (@2x). For example, for a 200×300 (css pixel) img tag, you need to provide a 400×600 image. In this way, the number of bitmap pixels is four times the original number. Under the retina screen, the number of bitmap pixels can form a 1:1 ratio with the number of physical pixels, and the picture will naturally be clear (this also explains a question left before, why the canvas size of the visual draft should be ×2?). There is another question here. What will happen if twice as many pictures are used on a normal screen? Obviously, on a normal screen, the 200×300 (css pixel) img tag corresponds to 200×300 physical pixels, and the bitmap pixels of a double image are 200×300*4, so there is one physical pixel corresponding to four bitmap pixels. Therefore, its color can only be obtained through a certain algorithm (the displayed result is a picture with only one-fourth of the total number of pixels of the original image. We call this process downsampling). Although the picture does not look blurry to the naked eye, it will seem that the picture lacks some sharpness or has a little color difference (but it is still acceptable). Let’s use a picture to show this: In response to the above two questions, I made a demo. In the demo, a 100×100 image is placed in 100×100, 50×50, and 25×25 img containers, and the display effect on a retina screen. The bar chart shows the difference in the values of the boundary pixels through a magnifying glass:
Love word picture, you can tell whether the picture is blurry or clear by looking at the word "love" (if it is not obvious, please download the original picture). #p# A few questions Here are some classic problems you may encounter when developing H5 on mobile devices with different resolutions and screens. Problem with picture resolution under retina The solution to this problem has been introduced above: double the image (@2x), and then reduce the image container by 50%. Such as: picture size, 400×600; 1.img tag
2. Background Image
Such shortcomings are obvious, under ordinary screens:
So the best solution is to load pictures of different sizes under different DPR. It can be done through CSS media queries or JavaScript conditional judgments. So the question is, in this case, don’t we need to prepare two sets of pictures? (@1x and @2x) I think that any successful company will have such an image server, which can obtain parameters through the URL, control the image quality, and crop the image into different sizes. So we only need to upload large images (@2x), and the rest of the small images are handled by the image server. We only need to be responsible for splicing the URLs. For example, for an original image like this, you can crop the image like this: // 200×200
// 100×100
(ps: Of course, cropping is just a proportional cropping of the original image, so the image must be clear~) Border: 1px issue under retina This is probably the most sensitive and concerned issue for designers. First of all, why does border: 1px exist in retina? We write CSS normally, like border: 1px;, will there be any problems under retina screens? First, let’s take a look at the following picture: The two pictures above are the test results of iPhone 3gs (dpr=1) and iPhone 5 (dpr=2). In comparison, they are consistent in displaying 1px border. So what are the advantages of retina display? Why do designers think the lines on the HD screen (right picture) are thick? They are obviously the same as the left and right~ Let me explain it with a picture (forgive me for stealing the picture again): In the above picture, for a 1px wide straight line, their physical sizes on the screen (gray area) are indeed the same. The difference is actually the smallest physical display unit on the screen, that is, the physical pixel. So for a straight line, the minimum width that the iPhone 5 can display is actually the gray area circled by the red circle in the picture. Expressed in CSS, it is theoretically 0.5px. Therefore, the border: 1px; that the designer wants under retina is actually 1 physical pixel wide. For CSS, it can be considered as border: 0.5px;, which is the smallest unit that can be displayed under retina (dpr=2). However, not all mobile browsers can recognize border: 0.5px;. In iOS7 and other systems such as Android, 0.5px will be treated as 0px. So how to achieve this 0.5px? The simplest way to do this is this (element scale):
We write border-bottom: 1px solid #ddd; as usual, and then use transform: scaleY(.5) to scale it down by 0.5 times to achieve a 0.5px effect, but this hack is not universal enough (such as rounded corners, etc.) and is also difficult to write. Of course, there are many other hack methods, which can be searched online, but each has its pros and cons. The page scale solution is more recommended here, which is more general and can meet almost all scenarios. For iPhone 5 (dpr=2), add the following meta tag and set viewport (scale 0.5): In this way, all border: 1px in the page will be reduced by 0.5, thus achieving the effect of border: 0.5px;. Take a look at the comparison of the effect pictures after implementation (the right picture is optimized): However, page scale will inevitably bring some problems:
These two questions will be discussed later... #p# Multi-screen adaptation layout issues For mobile layout, in order to adapt to various large-screen mobile phones, the best solution at present is to use the relative unit rem. Based on the principle of rem, what we need to do is: dynamically change the font-size (baseline value) of the root node html according to different mobile phone screen sizes and DPR. Here we extract a formula (rem represents the reference value) rem = document.documentElement.clientWidth * dpr / 10 Multiplying by dpr is because the page may be scaled 1/dpr times to achieve a 1px border (if not, dpr=1).
So, the font-size of the HTML might look like this: iPhone3gs: 320px / 10 = 32px iPhone4/5: 320px * 2 / 10 = 64px iPhone6: 375px * 2 / 10 = 75px To dynamically change the font-size of the root node HTML, we can do it through CSS or JavaScript. The CSS method can change the font-size of HTML through media queries based on the device width: Disadvantages: Dynamically changing the rem base value through media queries such as device width ranges is not accurate enough. For example, mobile phones with a width of 360px and a width of 320px will be treated the same (same rem base value) because their screen widths are in the same range (<375px). In fact, their screen widths are not equal, and their layouts should be different. In the end, the conclusion is: this approach is not accurate enough, but it is enough. In JavaScript, the base value rem is calculated by the above formula, and then written into the style, which is roughly as follows (the code is referenced from Kimi's m-base module)
This method can accurately calculate the rem baseline value for different screens. The disadvantage is that you need to load such a piece of js code, but I personally think this is the best solution at present. Because this solution solves three problems at the same time:
When it comes to layout, we naturally have to answer the original question: How to restore the actual width and height of the visual draft in CSS coding? Prerequisites:
If there is a block measured in a psd file: a div with a width and height of 750×300px, how do you convert it into rem units? The formula is as follows: rem = px / base value; For a visual draft of an iPhone 6, its baseline value is 75 (mentioned before); Therefore, after determining the visual draft (that is, determining the benchmark value), we usually write a mixin using less, like this:
So, for a div with a width and height of 750×300px, we use less to write:
Converted to HTML, it looks like this:
Finally, because the DPR is 2 and the page is scaled by 0.5, the actual width and height displayed on the mobile screen should be 375×150px, which is just right. If the page does not have a scale of 0.5, our code would look like this:
We usually get this width and height like this:
Finally, here is a comparison chart without layout adaptation (above) and with rem layout adaptation (below): (The phones above are: iPhone3gs, iPhone5, iPhone6) It is obvious that the width and height of each block adapted by rem will change with the width of the mobile phone screen. The most obvious thing can be seen in the picture list part. The last picture visual draft requires only a little bit to appear. The rem layout displays well on any screen. Font size problem Since the above solution will make the page scale, we can rely on the high-definition visual draft for the width and height of the page blocks, because the visual draft is originally ×2, we can measure it directly, so how to deal with the font? Regarding the font scaling problem, the designer's original requirement was that the font size on any mobile phone screen should be uniform, so we will do the following for different resolutions (different DPR):
(Note that you cannot use rem for fonts, as the error is too large and it cannot satisfy the requirement of keeping the font size the same on all screens) For convenience, we will also write a mixin using less:
(Note: The data-dpr attribute of HTML is mentioned in the previous JS solution, so it is useful here) According to experience and testing, there are still some weird DPRs. Here we have unified compatibility~ When using it, it's like this:
Of course, for other CSS properties, if you also want them to be consistent under different DPRs, you can also do this, such as:
at last The above is a summary of some solutions and knowledge explanations for mobile H5 high-definition and multi-screen adaptation. Please point out any errors. |
<<: OS X 10.10.5 and iOS 8.4.1 routine updates
>>: Teach you step by step how to view nearby people
The famous technology website CNET wrote an artic...
After the WWDC2016 conference, Apple released fou...
Surprise check: Are you crossing your legs at thi...
If there is any product that has completely chang...
Razors can be said to be a blind spot in the know...
The essence of a simple side job to make money is...
In December, NIO delivered 15,815 new vehicles, a...
Today I want to share with you a project suitable...
In information flow promotion, "modeling&quo...
On June 6, according to foreign media reports, Ap...
With the popularity of TikTok, many businesses wa...
With the lifting of the ban on game consoles, nex...
Note: The cover image is a copyrighted image. Rep...
With the advent of the 5G era, there are more and...