“This is the third day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.
DevicePixelRatio introduction
Window. devicePixelRatio is a double precision floating point value that indicates the ratio of the physical pixel resolution of the display to the CSS pixel resolution. In simple terms, it tells the browser how many screen physical pixels should be used to draw a single CSS pixel.
This is useful when dealing with the difference between a standard display and a HiDPI or Retina display, which uses more of the screen’s physical pixels to draw the same object, resulting ina sharper image.
A window. DevicePixelRatio of 1 indicates a classic 96 DPI display (72 DPI on some platforms), while 2 is expected for HiDPI/Retina displays. Other values may be returned in unusually low-resolution displays or, more commonly, when the pixel depth of the screen is more than double the standard resolution of 96 or 72 DPI.
Correct resolution in <canvas>
The
HTML
<canvas id="canvas"></canvas>
Copy the code
JavaScript
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// Set the display size (CSS px)
const size = 200
canvas.style.width = `${size}px`
canvas.style.height = `${size}px`
// Set the actual size (zoom to take into account the extra pixel density)
const scale = window.devicePixelRatio // Change to 1 on the screen to see the blurred canvas
canvas.width = Math.floor(size * scale)
canvas.height = Math.floor(size * scale)
// Normalize coordinate systems to use CSS pixels
ctx.scale(scale, scale)
ctx.fillStyle = '#bada55'
ctx.fillRect(10.10.300.300)
ctx.fillStyle = '#ffffff'
ctx.font = '36px Arial'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillText('I love MDN', size / 2, size / 2)
Copy the code
Monitor changes in screen resolution or zoom level
You can use window.matchmedia () to check if the value of devicePixelRatio has changed
In this example, we will set up a media query and watch it to see when the device resolution changes so that we can check the value of devicePixelRatio to handle any required updates.
The JavaScript code creates a media query to monitor the device resolution and check the value of devicePixelRatio every time it changes.
let pixelRatioBox = document.querySelector(".pixel-ratio");
let mqString = `(resolution: The ${window.devicePixelRatio}dppx)`;
const updatePixelRatio = () = > {
let pr = window.devicePixelRatio;
let prString = (pr * 100).toFixed(0);
pixelRatioBox.innerText = `${prString}% (${pr.toFixed(2)}) `;
}
updatePixelRatio();
matchMedia(mqString).addListener(updatePixelRatio);
Copy the code
The string mqString is set to the media query itself. Media queries start with (Resolution: 1dPPx) (for standard displays) or (Resolution: 2dPPx) (for Retina/HiDPI displays) and check whether the current display resolution matches the actual device pixel point for each pixel px.
The updatePixelRatio() function gets the current value of devicePixelRatio, and then sets the innerText of the pixelRatioBox to a string that displays both the percentage and the ratio of the original decimal value, up to two decimal places.
The updatePixelRatio() function is then called once to display the starting value, and matchMedia() and addEventListener() are used to set updatePixelRatio() as the handler for the change event.
HTML will create a box that contains instructions and a Pixel-ratio box that will display the current pixel ratio information.
<div class="container">
<div class="inner-container">
<p>This example demonstrates the effect of zooming the page in
and out (or moving it to a screen with a different scaling
factor) on the value of the property <code>Window.devicePixelRatio</code>.
Try it and watch what happens!</p>
</div>
<div class="pixel-ratio"></div>
</div>
Copy the code
body {
font: 22px arial, sans-serif;
}
.container {
top: 2em;
width: 22em;
height: 14em;
border: 2px solid #22d;
margin: 0 auto;
padding: 0;
background-color: #a9f;
}
.inner-container {
padding: 1em 2em;
text-align: justify;
text-justify: auto;
}
.pixel-ratio {
position: relative;
margin: auto;
height: 1.2 em;
text-align: right;
bottom: 0;
right: 1em;
font-weight: bold;
}
Copy the code
Viewport in-depth understanding
In the reconstruction or development of web pages on mobile devices, the first thing to understand is the viewport on mobile devices. Only by understanding the concept of viewport and making clear the use of meta tags related to viewport can we better adapt our web pages to or respond to mobile devices of different resolutions.
The concept of the viewport
Generally speaking, a viewport on a mobile device is the part of the screen on the device that can be used to display our web page. In particular, it is the part of the browser (or maybe a Webview in an app) that can display the web page. But a viewport is not limited to the size of the browser’s viewport. It may be larger or smaller than the viewable area of the browser. By default, viewPorts on mobile devices are generally larger than the viewport area of the browser. This is because mobile devices have a smaller resolution than desktop computers, so in order to display traditional web sites designed for desktop browsers properly on mobile devices, Browsers on mobile devices will set their default viewPort to 980px or 1024px (or any other value, depending on the device), but the result will be a horizontal scroll bar because the width of the browser’s viewport is smaller than the default viewPort width. The following figure lists the default viewPort widths for browsers on some devices.
1px in the CSS is not equal to 1px in the device
In CSS, we usually use PX as the unit. In desktop browser, a pixel of CSS usually corresponds to a physical pixel of the computer screen, which may cause the illusion that the pixel in CSS is the physical pixel of the device. However, this is not the case. A CSS pixel is an abstract unit, and the 1px in the CSS represents different physical pixels on different devices or in different environments. We don’t have to worry about this when designing a web page for a desktop browser, but on a mobile device, it’s important to understand. In earlier mobile devices, screen pixel density was low, such as the iphone3, which had a resolution of 320×480. On the iphone3, one CSS pixel was indeed equal to one physical pixel on the screen. Later, with the development of technology, the pixel density of the screen of mobile devices became higher and higher. Starting from iphone4, Apple introduced the so-called Retina screen, with the resolution doubled to 640×960, but the screen size remained unchanged, which meant that the pixels on the same size screen were doubled. At this time, One CSS pixel is equal to two physical pixels. The same goes for other brands of mobile devices. For example, Android devices can be divided into LDPI, MDPI, HDPI, XHDPI and other different levels according to the pixel density of the screen. The resolution is also varied. How many physical pixels of a CSS pixel on an Android device is equivalent to? Another factor that can cause px changes in CSS is user scaling. For example, when a user doubles the size of a page, the number of physical pixels represented by 1px in the CSS doubles. Conversely, doubling the size of the page will reduce the number of physical pixels represented by 1px in the CSS by twice as much. More on this later in the article. In mobile browsers and some desktop browsers, the Window object has a devicePixelRatio property, which is officially defined as the ratio of device physical pixels to device independent pixels, i.e., devicePixelRatio = physical pixels/individual pixels. The PX in the CSS can be regarded as an independent pixel of the device, so by using devicePixelRatio, we can know how many physical pixels a CSS pixel on the device represents. For example, on a Retina iPhone, devicePixelRatio is 2, meaning that one CSS pixel equals two physical pixels. Note, however, that devicePixelRatio has some compatibility issues across browsers, so we can’t trust it completely just yet.
PPK’s theory of three viewports
PPK has a lot of research on viewport on mobile devices (the first, second, third), interested students can have a look, a lot of data and views in this paper are also from there. According to PPK, there are three viewports on mobile devices.
First, browsers on mobile devices think they must be able to make all web sites display correctly, even those not designed for mobile devices. However, if you use the viewport area of the browser as the viewport, because the screen of mobile devices is not very wide, so those websites designed for desktop browser display on mobile devices will inevitably be crowded because of the mobile device viewport is too narrow, and even the layout will be messed up. Some may ask, aren’t there many phones with very large resolutions, such as 768×1024 or 1080×1920, that are fine for displaying websites designed for desktop browsers? As we’ve already said, 1px in CSS is not 1px on the screen, the bigger your resolution, the more physical pixels in CSS 1px is, and the bigger the devicePixelRatio is, which makes sense because you’re increasing the resolution, but the screen size isn’t that much bigger, The 1px in CSS must represent more physical pixels, so that 1px objects will be the same size on the screen as those on lower-resolution devices, or they will be too small to see. So on devices like 1080×1920, by default you might just have to set the width of a div to 300-plus pixels (depending on the devicePixelRatio) to get a full screen. To get back to the point, if the browser’s viewport area is set to viewPort on mobile devices, some websites will display a messy viewPort that is too narrow, so those browsers decide to default to a wider viewport, such as 980px. That way, even websites designed for the desktop will work on mobile browsers. PPK calls this browser’s default viewPort a Layout ViewPort. The layout of the viewport width can be through the document. The documentElement. ClientWidth to obtain.
However, the layout viewPort is larger than the viewport of the browser, so we need a viewport to represent the viewport size of the browser. PPK calls this viewPort a Visual ViewPort. The width of the Visual ViewPort can be obtained using window.innerWidth, but not in Android 2, Oprea Mini, or UC 8.
We now have two viewPorts: Layout ViewPort and Visual ViewPort. But browsers don’t think that’s enough, because more and more websites are individually designed for mobile devices and must have a viewport that works perfectly for mobile devices. Perfect fit means that, first of all, the user does not need to zoom and horizontal scrollbars to see all the content of the site; Second, the size of the text displayed is appropriate. For example, a 14px text will not be too small to be seen on a high-density screen. Ideally, this 14px text will be displayed in the same size regardless of the screen density and resolution. Of course, not just text, but other elements like images. PPK calls this viewport ideal ViewPort, which is the third viewport — the ideal viewport for mobile devices.
There is no fixed size for the Ideal ViewPort, different devices have different Ideal Viewports. The Ideal ViewPort for all iphones is 320px, whether the screen width is 320 or 640, that is, in the iPhone CSS 320px represents the width of the iPhone screen.
But it’s a little bit more complicated for Android devices, 320px, 360px, 384px and so on, how wide the Ideal Viewport is for different devices, you can go toCheck it out at viewportsizes.com, which has a collection of ideal widths for many devices.To sum up: PPK divides viewports on mobile devices into layout Viewport, Visual ViewPort and Ideal Viewport, among which ideal Viewport is the most suitable viewport for mobile devices. The ideal ViewPort width is equal to the screen width of the mobile device. As long as you set the width of an element in CSS to the ideal Viewport width (in px), that element is the screen width of the device. The idea of the Ideal ViewPort is that sites designed for the Ideal ViewPort can be presented to the user at any screen resolution without manual scaling or horizontal scrollbars.
Use meta tags to control viewport
The default viewPort for mobile devices is a Layout ViewPort, which is wider than the screen, but for mobile site development we need the Ideal ViewPort. So how do you get the Ideal ViewPort? This is where meta tags come in. One of the most common things we do when developing websites for mobile devices is to copy the following into our head tag:
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
Copy the code
This meta tag makes the width of the current viewPort equal to the width of the device, and does not allow the user to manually scale. You may or may not allow the user to zoom in and out depending on the site, but having the viewPort width equal to the width of the device should be what everyone wants. If you don’t, you’ll use the default viewPort that is wider than the screen, which means a horizontal scroll bar will appear. What does the meta tag named Viewport have and what does it do? The Meta ViewPort tag was first introduced by Apple in its Safari browser to solve the viewport problem on mobile devices. Android and other browser vendors followed suit and introduced support for Meta ViewPort, which proved to be very useful. In the Apple specification, the Meta ViewPort has six properties (let’s call those things in content individual properties and values for now), as follows:
These attributes can be used together, individually, or in combination, separated by commas. In addition, android also supports target-densitydPI as a private property, which indicates the density level of the target device and determines how many physical pixels are represented by 1px in the CSS
In particular, when target-denSitydpi =device-dpi, 1px in CSS is equal to 1px in physical pixels. Since this property is only supported by Android, and Android has decided to deprecate target-densitydpi, we should avoid using this property.
Set the current viewPort width to the ideal ViewPort width
To get the Ideal ViewPort, you must set the default Layout ViewPort width to the screen width of your mobile device. Since width in the Meta ViewPort controls the width of the Layout ViewPort, we only need to set width to the special value width-device.
<meta name="viewport" content="width=device-width">
Copy the code
Here’s how this code works on mobile browsers:You can see that by width=device-width, all browsers can change the current viewPort width to the ideal Viewport width, but it’s important to note that on iPhone and iPad, whether it’s portrait or landscape, The width is the width of the Ideal ViewPort in portrait. Sure, when we’re developing web pages for mobile devices, whether you know what a viewport is or not, this is probably all you need. But you don’t know that
<meta name="viewport" content="initial-scale=1">
Copy the code
This code can also achieve the same effect as the previous one, and can also change the current viewport to the Ideal Viewport.
In theory, all this code does is not scale the current page, i.e. the page should be as big as it should be. Width =device-width?
And to figure that out, first you have to figure out what the scaling is relative to, because the scaling here is 1, which means it’s not scaled, but it achieves the Ideal Viewport, so there’s only one answer, the scaling is relative to the Ideal Viewport, When you scale the Ideal ViewPort 100%, that’s 1, you get the Ideal ViewPort. As it turns out, it is. Below is the browser Settings for each mobile terminal<meta name="viewport" content="initial-scale=1">
Can change the current viewPort width to the ideal ViewPort width.
Test results show that initial-scale=1 also changes the viewPort width to the ideal ViewPort width, But this time it’s Internet Explorer on Windows Phone that sets the width of the Ideal ViewPort for portrait and landscape. But that little flaw doesn’t matter anymore. But what if width and initial-scale=1 are both present and there is a conflict? Such as:
<meta name="viewport" content="width=400, initial-scale=1">
Copy the code
Width =400 sets the current viewport width to 400px and initial-scale=1 sets the current viewport width to the ideal Viewport width. Is it the one that’s written on the back? It isn’t. When this happens, the browser takes the larger of the two. For example, when width=400 and ideal ViewPort width is 320, select 400; When width=400 and the ideal Viewport width is 480, the ideal Viewport width is taken. In UC9, when initial-scale=1, the width of the viewPort will always be the width of the ideal ViewPort regardless of the width property value. To set the current viewport width to the ideal viewport width, you can set width=device-width or initial-scale=1. The ideal ViewPort width of the vertical screen prevails. Initial-scale =1; width=device-width =1; width=device-width =1;
<meta name="viewport" content="width=device-width, initial-scale=1">
Copy the code
More on Meta ViewPort
Default values for scaling and initial-scale
First let’s talk about scaling. As mentioned earlier, scaling is relative to the Ideal ViewPort. The larger the scaling value is, the smaller the viewPort width is, and vice versa. For example, in the iPhone, the ideal Viewport is 320px. If we set it to initial-scale=2, the viewport will be 160px. However, changing 1px to 2px does not change 320px to 640px. Instead, 1px becomes the same length as 2px without changing the actual width. Therefore, doubling the size of 1px takes 160px to fill a width that used to be 320px. Therefore, we can derive a formula:
Visual ViewPort width = Ideal ViewPort width/Visual ViewPort widthCopy the code
Ps: The width of the Visual ViewPort refers to the width of the browser’s viewable area. Most browsers fit this theory, but native browsers on Android and Internet Explorer have some problems. Android’s webKit browser works only when initial-Scale = 1 and width is not set, which means this theory is basically useless on android. Internet Explorer doesn’t reject initial-scale at all. No matter what you set it to, the effect of initial-scale is 1. Okay, now the default value for initial-scale, if I don’t write this property, what’s the default value for initial-scale? It’s obviously not going to be 1, because when initial-scale = 1, the viewPort width is set to the ideal ViewPort width. The default layout viewPort width is 980. 1024, 800, etc., none of which is the ideal Viewport width to start with, so initial-scale is definitely not 1 by default. There seems to be no way to get the initial-scale default on Android devices, or it doesn’t have a default at all. It’s only going to work if you write it out. We’ll leave it there, but we’ll focus on the initial-scale default on iPhone and iPad. Based on our tests on the iPhone and iPad, the iPhone and iPad automatically calculate initial-scale whenever you set a layout viewPor width without specifying an initial scale. To ensure that the width of the current Layout ViewPort is the width of the browser’s viewable area when scaled, that is, there is no horizontal scroll bar. For example, on the iPhone, we don’t set any viewPort meta tags, and the layout ViewPort is 980px wide, but we can see that the browser doesn’t have a horizontal scroll bar, and the browser shrinks the page by default. According to the formula above, the current scale = ideal ViewPort width/Visual ViewPort width, we can say: the current scale = 320/980 (the current initial-scale default should be 0.33). When you specify an initial-scale value, this default value will not work. Just remember this conclusion: On the iPhone and iPad, no matter how wide you make the ViewPort, if you don’t specify a default zoom value, the iPhone and iPad will automatically calculate the zoom value so that the current page doesn’t have a horizontal scroll bar (or the width of the viewPort is the width of the screen).
Dynamically change the Meta ViewPort tag
The first method can use document.write to dynamically output meta ViewPort tags, for example:
document.write('<meta name="viewport" content="width=device-width,initial-scale=1">')
Copy the code
The second method is changed by setAttribute
<meta id="testViewport" name="viewport" content="width = 380">
<script>
var mvp = document.getElementById('testViewport');
mvp.setAttribute('content'.'width=480');
</script>
Copy the code
There is a bug in android 2.3’s built-in browser
<meta name="viewport" content="width=device-width">
<script type="text/javascript">
alert(document.documentElement.clientWidth); // Pop up 600, normally 320
</script>
<meta name="viewport" content="width=600">
<script type="text/javascript">
alert(document.documentElement.clientWidth); // Eject 320, normally eject 600
</script>
Copy the code
The ideal ViewPort is 320px. The first pop-up value is 600, and the second pop-up value is 320. So overwriting or changing the Meta ViewPort tag in the native browser of Android 2.3(and perhaps all 2.x versions) can produce very confusing results.
conclusion
After all this nonsense, it’s worth summarizing something useful at last. First of all, if you don’t set the Meta ViewPort tag, the default browser width on mobile devices is 800px, 980px, 1024px, etc., which is larger than the screen width. The width unit px is the CSS px, which is not the same as the actual pixels on the screen. Second, every mobile device browser has an ideal width. This ideal width refers to the CSS width, regardless of the physical width of the device. In CSS, this width is equal to 100% of the width represented. We can use the meta tag to set the viewport width to the desired width. If we don’t know what the desired width of the device is, we can use the device-width special value. And initial-scale=1 also sets the viewport width to the desired width. So, we can use
<meta name="viewport" content="width=device-width, initial-scale=1">
Copy the code
To get an ideal viewPort. Why do you need an ideal viewport? For example, the ideal viewport width for a 320×480 phone is 320px, and the ideal viewport width for a 640×960 phone with the same screen size is 320px. So why should the ideal width of the high resolution phone be the same as the ideal width of the low resolution phone? That’s because it’s the only way to ensure that the same site looks the same or similar on different resolutions. In fact, although there are so many mobile phones of different types and brands with different resolutions in the market, their ideal viewport widths can be summed up as no more than 320, 360, 384, 400, etc., which are very similar. A similar ideal width means that a site designed for one device’s ideal viewport will not behave very differently or even the same on other devices.