“Stop Asking me questions about XX” series:
A,
Stop asking me about the orientation of this
Second,
Stop asking me cross-domain questions
The problem of mobile terminal adaptation, generally speaking, we will not go into depth, because this kind of thing is configured once no longer need to take care of, received the design drawing according to the ancestral routine. Step by step must only become active page writer, thorough research, in order to become a professional active page writer.
A tangled relationship
At the beginning of this article, we need to clarify the various relationships between pixels, viewports, and zooming.
pixel
Pixel we write a lot, is not px, why come out to say? Because a pixel is not just a PX.
- Equipment pixel
The device pixel, also known as the physical pixel, is determined by the screen of the device and is essentially the smallest unit on the screen that controls the display.
- Device independent pixel
Device-independent pixels are virtual pixels that can be controlled by programs, corresponding to CSS pixels in Web development.
- DPR
The relationship between device pixels and device independent pixels is DPR,Device pixel ratio = Device pixel/device independent pixel. And this is true only if the scaling ratio is 1, for reasons we’ll see when we talk about scaling. According to this relationship, if the device pixel is larger than the device pixel (DPR greater than 1, we often say high-definition or Retina display), there will be a device pixel corresponding to multiple device pixels:
viewport
In the past, when smart phones just came out, few websites specially adapted to the mobile terminal, but users can directly access the PC website from the mobile phone, so how to display a good website, whether the website is a PC website or a mobile website, is an urgent problem to be solved. So the mobile terminal three viewport layout viewport, visual viewport, ideal viewport suddenly emerged, become the basis of various mobile adaptation scheme.
- Layout viewport
Layout viewports are containers on top of HTML elements in which our pages “fit”.
Think of width:100%. What is this 100% based on? If you look it up, you’ll see:If an attribute is assigned a score, its calculated value is calculated from the element’s contain block.What is the contain block for an HTML element? That’s right, our layout viewport, which is the root of all CSS percentage calculations. If CSS is a paintbrush, then layout viewport is the canvas. The canvas has a default size (if the Meta ViewPort is not set manually), usually between 768px and 1024px, which can be passeddocument.documentElement.clientWidthTo obtain. In this way, the layout of web pages is no longer limited by device size, even on mobile devices with small screens can accommodate PC websites.
- Visual viewport
The visual viewport refers to the area that the user sees through the device screen. It can be scaled to change the size of the visual viewport and pass throughwindow.innerWidthTo obtain.
It is necessary to talk about scaling here. Scaling changes the size of CSS pixels. When you zoom in, CSS pixels increase, so that a CSS pixel can span more device pixels and the visual port becomes smaller. What? Magnification makes the visual orifice smaller, right? That’s right, because the visual viewport is also measured by CSS pixels, and zooming in means zooming in CSS pixels. Suppose you need 200 CSS pixels to fill the screen, but now you only need 100 CSS pixels to fill the screen, so the width of the visual viewport becomes 100px.
Although zooming changes the size of CSS pixels, zooming on mobile does not change the layout viewport, so zooming does not affect the layout, but it does affect the layout on PC. Is the most intuitive feelings, we usually double refers to zoom the web in the mobile end, there is no change the layout of the pages, you can drag to see through the different areas, but in the PC to zoom in, such as reading to text larger and enlarge page operation, when the word is enlarged, but the entire page layout will change. So if it’s not about layout viewports who else does it matter? The answer is the ideal viewport, which is calculated as follows:Zoom factor = ideal viewport width/visual viewport width
- Ideal viewport
The ideal viewport refers to the ideal size of a website on a mobile device, which is the screen size of the device. Why an ideal viewport? First, let’s look at how the current situation is not ideal. We are browsing a website without mobile adaptation, due to the layout viewport between 768 px – 1024 px, the whole site is “painting” in such a big “canvas,” but because the phone’s screen is smaller than the “canvas”, so you need to pass through narrow to plug into the phone’s screen, the result when we browse the website while see, But everything inside became so small that you had to zoom in to see it, and that’s just not ideal. It would be ideal if you could see it without having to zoom in. Think back to the unsatisfactory solution above, which was to shrink a large canvas onto a small screen. Assuming the canvas is the same size as the screen, wouldn’t it be appropriate to draw on the canvas?
Let’s connect them together
Know the Meta viewport
The
element provides meta information about the page that is not displayed on the page and can be used to tell the browser how to parse the page.
there are a lot of things you can set, but I’ll just focus on vieport, which is the foundation of all mobile adaptation schemes.
- Width: Set the layout viewport to a fixed value, such as 375px or device-width
- Initial-scale: Sets the initial scale of the page
- Minimum-scale: Sets the minimum reduction
- Maximum-scale: sets the maximum zoom level
- User-scalable: Disables scaling when set to no
Although there are only five values, there are a few points worth noting:
The impact of setting initial-scale
According to the formula, the scaling factor = ideal viewport width/viewport width. If initial-scale is set to 0.5, for example, then iPhone6, iPhone6’s device width is 375px, that is, the ideal viewport width is 375px. So visual viewport width = 375px (ideal viewport width) / 0.5 (zoom factor). Obviously setting initial-scale initializes the visual viewport and initializes the layout viewport to the value of that viewport.
Width and initial-scale coexist
Setting initial-scale initializes the viewport and layout viewport. Width specifies the size of the layout viewport.
Perform a console. The log (` layout viewport: ${document. DocumentElement. ClientWidth}; Visual viewport: ${window.innerWidth} ‘) gives you “Layout viewport: 400; Visual port: 400 “. At that time a rotating equipment, then turned into a 667 (w) * 375 (h), then perform up the console. The log (` layout viewport: ${document. DocumentElement. ClientWidth}; Visual viewport: ${window.innerWidth} ‘) gives you “Layout viewport: 667; Visual port: 667 “. The conclusion is that both width and initial-scale initialize the layout viewport, but the browser takes its maximum value.
Set up the ideal viewport
Width =device-width =1; initial-scale=1; initial-scale=1; Since some browsers set only one of them, there is no guarantee that the desired viewport size will change correctly as the screen rotates, so writing both together is just for compatibility purposes.
Comfortably restore the mobile design
There is a lot of theoretical knowledge above, but in fact, there is a solution to comfortably revert to the mobile design and make a page for mobile access.
Classic problem
- The picture
The problem with images here is that the hd /Retina display will be blurry. This is because most of the images we use are PNG and JPG images, which are called bitmaps. They are made up of pixels, and the zoom will be distorted. When we talked about pixels above, this HD /Retina display has a DPR greater than one, so one pixel spans multiple device pixels, and bitmap images need one pixel for each device pixel to be clear. So if a 100 x 100 image looks sharp on a normal screen, it will look blurry on a HD /Retina screen. That’s because a 100 x 100 image on a normal screen has pixels corresponding to device pixels, but on a HD /Retina screen, one pixel corresponds to multiple device pixels. This makes the picture look blurry.
As shown in the figure, if an image pixel corresponds to multiple device pixels, those device pixels can only be displayed in the same color as the image pixel, resulting in a blurred look.
Now that we know the cause of the problem, the solution is also simple. Bitmap images need one pixel for each device to be clear, so a 100 x 100 image will be clear on a DPR 1 screen and blurry on a DPR 2 screen. Let’s put a 200 x 200 graph on a DPR 2 screen, and we’ll have a one-to-one match.
- 1 px border
“You look at the design drawing this line is very thin, why you realize so thick, looks very inferior feeling.”
The size of the design is 1px and the size of the CSS is 1px. Generally, designers will draw a drawing according to a standard size. For example, drawing according to the size of iPhone6 is a 750px wide design drawing, which is actually the device pixel of iPhone6. The 1px measured in the design drawing is actually 1 device pixel<meta name=”viewport” content=”width=device-width, initial-scale=1″>, the layout viewport is equal to the ideal viewport is equal to 375px, and since the DPR of iPhone6 is 2, 1px when writing CSS corresponds to 2 device pixels, so it will look a bit thicker.
So just write 0.5px for 1 device pixel. Yes, that’s true, but many browsers don’t support the 0.5px method, so it won’t show up, but it doesn’t matter.
Restore design
Because the PC screen is generally larger than the size of the design drawing, you only need to fix a content area in the center to display the content of the design drawing, and leave the rest of the area blank. The mobile screen is large and small, and the design drawing is generally based on a model as the standard, such as the size of iPhone6. What problems will occur if the design drawing is opened without processing?
(From left to right, iPhone4, iPhone6, iPhone Plus)
You can see the design of the iPhone6 measured 350px x 350px elements written on the iPhone6width: 350px; height: 350px;
IPhone4 horizontal scroll bar is out, and plus left and right clearance is significantly larger than 10px, so that the effect of different sizes of screen out with the effect of the design will have different degrees of difference, which is not what we want, What we want is for the different sizes of the screen to look exactly like the scale of the design.
Since you want the proportions of the different screen sizes to be consistent with the design, the obvious fit isGeometric scaling.
(The following code is intended to explain the principle, without too much detail consideration and testing, should not be used in production environment)
- Viewport scheme
When you think about scaling, the first thing that comes to mind is initial-scale. Recall the role of initial-scale: setting initial-scale initializes the visual viewport and initializes the layout viewport to the value of that visual viewport. So can we scale the viewport equally based on the design to fit?
<script>
const scale = window.screen.width / 750
document.write(`<meta name="viewport" content="initial-scale=${scale}">`)
</script>Copy the code
The advantage of this method of adaptation is simple and crude, the disadvantage is too simple and crude, because the setting of viewport is global, so that although you can directly write the size of the design drawing to THE CSS, but if there are some places that do not need to scale and need to set a fixed size, For example, if you want to display fixed size text on different screen sizes, or if you introduce a library that has styles and you don’t know how they are adapted, then the global viewport scaling in your project may affect the display effect of the library.
- Rem solution
Unlike PX, which is a fixed size unit, REM is a relative unit, relative to the font size of the HTML tag. For example, if the font size of an HTML tag is 100px, then one rem equals 100px. We can do the same thing with rem relative units.
- This solution does not require scaling the viewport, so first we conventionally set the layout viewport equal to the ideal viewport:
<meta name="viewport" content="width=device-width, initial-scale=1">
- Again, iPhone6 device pixel as the standard design image, width is 750px, assuming that the design image as the standard HTML tag size is 100px, so 1rem = 100px, then the total width of the design image is 7.5rem
- Taking the design drawing with a total width of 7.5REM as the standard, the total width of different screen sizes should also be 7.5REM. Since the layout viewport is equal to the ideal viewport, the layout viewport of iPhone6 is 375px (i.e., the total width is 7.5REM). Now we just need to figure out how much font size to set for the HTML when the layout viewport is 375px. Font size = 50px HTML * 7.5 = 375
- Expand to other screens
Document. The documentElement. Style. FontSize = ` ${document. DocumentElement. ClientWidth / 7.5} px
` - Now we just need to measure the design. If the design has a 300px element, we will write the CSS as 3rem (1rem = 100px).
Using this solution, we only use REM for elements that need to be scaled equally, and use PX for those that require a fixed size. This gives us flexibility compared to the ViewPort solution and allows us to use it on demand rather than on a one-size-fits-all basis. However, this solution may not be as intuitive when writing CSS, the cost may be a little bit higher, but with the help of build tools or less/sass can be solved, after all, there should be very few projects that do not use these tools.
- Enhanced REM scheme
The enhanced REM solution mentioned here is actually the Flexible solution of Mobile Mobile (also similar to HD, multi-screen adaptation solution on mobile). What’s the enhanced solution? That is, solve the 1px border problem globally by setting the viewPort. Since we need to set the viewPort to solve the 1px border problem, there must be a trick to setting the viewport:
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) { 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
Document. write(‘
‘) Scaling the Viewport to 1 / DPR for Retina displays ends up with 1px CSS pixels exactly equal to 1px device pixels, thus solving the 1px border problem. So why zoom only on the iPhone? Please read damo’s article about the 1px solution for Retina. Other REM related configurations are similar to the REM scheme above, which is not explained here. The biggest advantage of this enhanced REM scheme is that it solves the 1px border problem, but it also does viewport scaling, which still faces some of the effects of the viewport scheme mentioned above, by setting data-DPR to the HTML
document.documentElement.setAttribute('data-dpr', dpr)Copy the code
Thus, the CSS can be fixed for different DPR sizes:
.test {
width: 1rem;
height: 2rem;
font-size: 12px;
}
[data-dpr="2"] .test {
font-size: 13px;
}
[data-dpr="3"] .test {
font-size: 14px;
}Copy the code
- Vw plans
Vw is also a relative unit to the layout viewport; 1vw is 1% of the layout viewport width. So the REM scheme is essentially emulating vw, so let’s see what we can do with VW.
- The familiar standard iPhone6 design is 750px wide. So 1vw = 1% viewport width, 100vw = 750px according to the design, 1vw = 7.5px.
- One element of the design is 100px, and CSS needs to be written as Xvw * 7.5 = 100, so X equals 13.3vw.
- The calculation is still left to the build tool, see more details about the adaptation of the mobile page
Rem has some advantages that VW has, and it’s not as confusing as REM, but it’s just not as compatible as REM, and in the long run VW will eventually take OVER REM as a major player in mobile adaptation, because that’s what vw was born to do.
It’s finally over
There are no silver bullets. Is the global ViewPort scaling scheme rude? But for less demanding and do not need to take into account the fixed size of the page, on the global scale, pick up the design can write code. Demanding and flexible, but also afraid to build a little trouble? Rem scheme goes. Compatibility does not need to be considered. Why not try vw’s straightforward and elegant scheme? There is no good or bad solution, only suitable or not. Finally, if something is wrong, please correct it.