Why would you do that?

A CSS question often arises in front-end interviews, what are PX, REM, em? Or 1px on the phone? But actually for my front-end work, when the design is handed to you, no one ever cares whether you use PX or REM. What the company requires is to be able to restore the design and adapt it to more models. In fact, this is very similar to my understanding of the concept of front-end engineering, to take a design diagram and turn it into a usable tool, and then turn that usable tool into a better product.

Yes, it is very simple to say, but there will be many problems in the actual development. The first one is the design drawing. Most of the design drawing developed as H5 is similar to that of the APP terminal. The design is based on the iphone6, and we can get an iphone6 with the exact 375667 screen size on chrome.

Ok, so now that you want to convert your design to HTML + CSS, you need to make the values of your design simple, from 375 -> 750,667 -> 1334, as anyone who has gone to school should know, twice the relationship, that’s easy, Why don’t you just divide the value of the design by 2 and write it on the page? But if it’s so simple, isn’t it a little too low for the front end, isn’t the boss paying you a little too much? But if you really want to do this, you can. After all, every company has different requirements and the purpose of the page is different, so you can do it.

If you divide by 2, you’ll basically find that the page looks ok, but when you change a phone, like the iphoneX, you’ll find, why is it thinner? Using a regular Android, why is it so thick? If you are a most extreme front-end engineer, this is certainly not good, after all, the first task of the front-end is to run through the code, followed by more mobile phones, so, as some craftsman spirit of the front-end engineer, we must let this difference disappear, this is the embodiment of our value.

The theoretical knowledge

  • Why do different phones display different results?

This problem is very simple, because there are so many brands of mobile phones, and so many different brands of mobile phones, different prices, different prices with different screens, expensive and cheap, have. Then different prices will have different resolutions, different resolutions will have different pixels, the higher the resolution will be more clear, the lower the vice versa.

  • What are pixels in a phone?

Baidu’s explanation: all the pictures are composed of small dots, which are called pixels. The number of pixels on a square screen multiplied by the number of dots horizontally and vertically is the number of pixels on the screen (the same is true for digital cameras).

Physical pixel: A physical pixel is the smallest physical display unit on the display (mobile phone screen). Each device pixel has its own color value and brightness value under the scheduling of the operating system. Device-independent pixels: Device-independent pixels (also known as density-independent pixels) 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. Device pixel ratio: Device pixel ratio (DPR for short) defines the corresponding relationship between physical pixels and device independent pixels. Its value can be obtained according to the following formula:

// devicePixelRatio = physical pixels/device-independent pixels // in a certain direction, x or y // in javascript we can get window.devicePixelRatioCopy the code

Ok, how do the above three concepts relate to our development and design drawings?

Remember we talked about the 750 design and why it’s ok to divide by 2, that’s why it’s half that, but if you do that, what happens when you have a different DPR device, like an android phone with DPR =1, or an iphoneX with DPR =3, Page will appear problem, but really, if this is the time you are using the percentage of page, actually can also, because of the change of percentage unit is according to the elements, it was initially developed to you no problem, but if late a little bit change code, will recalculate, maintenance costs are relatively high, and too much trouble.

So, wouldn’t it be perfect if there was a way to calculate this number and change it to a different size depending on the PAGE’s DPR?

So let’s talk about units in CSS

  • PX

Px Pixel A unit of absolute length. Pixel PX is relative to the screen resolution of the monitor.

  • EM

Em is a unit of relative length. Font size relative to the text in the current object. If the current font size for inline text has not been manually set, it is relative to the browser’s default font size.

  • REM

Rem is a relative unit added to CSS3 (root EM).

What’s the difference between this unit and EM? The difference is that when REM is used to set the font size for the element, the font size is still relative, but relative only to the HTML root element. This unit combines the best of both relative and absolute size, allowing you to scale all font sizes by changing only the root element, while avoiding the cascading effect of font sizes being compounded layer by layer.

I’ll just write a demo

css

* {margin: 0;padding:0}
body{font-size: 16px;max-width:500px;margin:0 auto}
Copy the code

html

 <h2>px</h2>
    <div style="font-size:16px;">16px
        <div style="font-size:20px;">20px
            <div style="font-size:24px;">24px
                <div style="font-size:26px;">26px
                    <div style="font-size:32px;">32px</div>
                </div>
            </div>
        </div>
    </div>
    <hr>
    <h2>em</h2>
    <div style="The font - size: 1.2 em;">1.2 em<div style="The font - size: 1.2 em;">1.2 em<div style="The font - size: 1.2 em;">1.2 em<div style="The font - size: 1.2 em;">1.2 em<div style="The font - size: 1.2 em;">1.2 em</div>
                </div>
            </div>
        </div>
    </div>
    <hr>
    <h2>rem</h2>
    <div style="The font - size: 1.2 rem;">1.2 rem<div style="The font - size: 1.2 rem;">1.2 rem<div style="The font - size: 1.2 rem;">1.2 rem<div style="The font - size: 1.2 rem;">1.2 rem<div style="The font - size: 1.2 rem;">1.2 rem</div>
                </div>
            </div>
        </div>
    </div>
Copy the code

The printed page looks like this:

According to the definition, since PX is absolute and we can’t change it dynamically at any time, and EM is very close to the percentage, don’t you realize that rem is the unit we want? Each element can be shown as a px multiple of one element, so how do we convert px in a design into REM?

The first step is to set a root px value

According to rem’s definition, we need to set a px value for the root. Here I usually write one:

body{font-size:16px}
Copy the code

Presumably you basically operate in the same way, but may be based on their own needs to change the value.

Step two, start counting

So how do you get REM? Suppose a div is given 500px width in the design, then

500/16 = 31.25 remCopy the code

Ok, so that’s it, it’s really easy to calculate, and so we get a value for REM, but when we go over the wire, the design says, “We need to change the width of this div to 600px”. We need to find this div first, and then go to 31.25 REM, and then use 600/16 to get REM. If you are a developer, it’s ok. We all know it’s 31.25 after the switch, but if it were someone else, what would this be? What should I do? Is this changed or not? Well, it’s a hassle.

For the front-end of engineering development this kind of calculation is not very friendly to developers, if we can automatically transform in the development process is not happy, the development process is clear at a glance, simple maintenance, can greatly improve the efficiency of work and the cost of late maintenance.

Making the

I found a plugin on the Internet called PostCSS-pxtorem. It is very simple to use (it is developed in VUE by default).

  1. Create a rem.js file, change the font size of the root according to the DPR and add rem.js to main.js
/ Set the rem functionfunction setRem () {
    // 320 defaults to 16px; 320px = 20rem ; Each element px based on /16
    const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
    // Get the HTML Dom element
    const htmlDom = document.getElementsByTagName('html') [0];
    // Set the font size for the root element
    htmlDom.style.fontSize= htmlWidth/20 + 'px';
}
/ / initialization
setRem();
// Resets rem when changing the window size
window.onresize = function () {
    setRem();
};
Copy the code
  1. Install postcss – pxtorem
npm install postcss-pxtorem --save-dev
Copy the code
  1. Postcssrx.js > postcss.config.js; postcssrx.js; postcss.config.js; postcssrx.js;
module.exports = {
    plugins: {
      'autoprefixer': {
        browsers: ['Android > = 4.0'.'iOS >= 7']},'postcss-pxtorem': {
        rootValue: 32.// The result is: design element size /16, for example 320px width, the final page will be 20rem
        propList: [The '*']}}}Copy the code

Ok, now when we restart the project, we can still go to PX normally, but we have helped me change it to REM on the interface, so it is a perfect fit.

For a quick comparison, figure 1 shows the vscode compiler and figure 2 shows chrome.

Code heavy style:

Chrom: