In the interview, it was found that many people are not very clear about the principle of REM layout, and only stay at the stage of knowing how to use it, or their understanding is completely wrong. This paper will clearly explain the principle of REM layout, its use scheme and other knowledge

What is a Rem

It is easy to confuse REM and EM, in fact, they are both units of CSS, and they are both relative units, the existing EM, CSS3 only introduced REM, before introducing REM, let’s first understand EM

When em is used as the unit of font-size, it represents the font size of the parent element. When EM is used as the unit of other attributes, it represents its own font size — MDN

< span style = “box-sizing: border-box; color: RGB (0, 0, 0); font-family: arial, sans-serif, sans-serif, sans-serif

<div class="p1">
	<div class="s1">1</div>
  	<div class="s2">1</div>
</div>
<div class="p2">
	<div class="s5">1</div>
  	<div class="s6">1</div>
</div>
Copy the code

.p1 {font-size: 16px; line-height: 32px; }
.s1 {font-size: 2em; }
.s1 {font-size: 2em; line-height: 2em; }

.p2 {font-size: 16px; line-height: 2; }
.s5 {font-size: 2em; }
.s5 {font-size: 2em; line-height: 2em; }
Copy the code

Em can make our pages more flexible and robust. Instead of writing dead px values everywhere, EM seems to have more tension. By changing the font size of the parent element, the child element will be proportionally changed, and the possibilities are seemingly endless

Added: Some people suggest using EM for elastic layout page, but its complicated calculation is criticized, even some people made a px and EM calculator, different node pixel value corresponding to em value, O

The disadvantage of em flexible layout is that once the font size of a node changes, then its descendants must be recalcalculated, X: X

When REM is applied to non-root elements, font size relative to root elements; When REM is applied to the font size of the root element, it is relative to its initial font size — MDN

Rem values are divided into two cases, when set on the root element and when set on the non-root element, for example

/* Apply to the root element, relative to the original size (16px), so the HTML's font-size is 32px*/
html {font-size: 2rem}

/* for non-root elements, the font size is 64px */ relative to the root element
p {font-size: 2rem}
Copy the code

Rem has its advantages, and EM has its advantages. I have never thought that technology is not right or wrong, but only suitable or not. What is right or wrong is the person who uses the technology

I’ve always thought that em was made for fonts and row heights. Sometimes the child element font should be relative to the parent element, and the element row height should be relative to the font size. The thing about REM is that it has a unified frame of reference

Rem layout principle

What is the essence of REM layout? It’s a question I’ve asked a lot of people, and I’ve never gotten a good answer.

In fact, the essence of REM layout is proportional scaling, usually based on width. Imagine how wonderful it would be if UE diagrams could be scaled in equal proportion

Let’s say we divide the width of the screen into 100 portions equally. The width of each portion is denoted by x, and x is equal to the width of the screen / 100. If we use x as units, the value before x represents the percentage of the screen width

p {width: 50x} /* 50% of the screen width */ 
Copy the code

If we want the page elements to vary equally with the width of the screen, we need the x units above. Unfortunately, CSS does not have such units. Fortunately, CSS has REM

From the introduction to REM above, it can be seen that if a child element sets the rem unit attribute, the actual size of the child element can be changed by changing the font size of the HTML element

html {font-size: 16px}
p {width: 2rem} /* 32px*/

html {font-size: 32px}
p {width: 2rem} /*64px*/
Copy the code

If the font size of an HTML element is equal to 1/100 of the screen width, then 1rem is equivalent to 1x

html {fons-size: width / 100}
p {width: 50rem} /* 50rem = 50x = 50% of the screen width */ 
Copy the code

How do you keep your HTML font size equal to 1/100th of your screen width? This can be set via js, usually in the page DOM Ready, resize, and screen rotation Settings

document.documentElement.style.fontSize = document.documentElement.clientWidth / 100 + 'px'; 
Copy the code

Then how to convert the value of pixel units obtained in UE graph to the value in rem? The formula is element width/UE graph width *100. Let’s take an example. Suppose the UE graph size is 640px and the width of an element in the UE graph is 100px, according to formula 100/640*100 = 15.625

p {width: 15.625rem}
Copy the code

Let’s verify that the above calculation is correct. The following table is the width of the elements in the UE graph

| | UE figure width width | UE diagram elements

| —– | ——– |

| 640px | 100px |

| 480px | 75px |

| 320px | 50px |

The table below shows the calculated values for our elements at different screen widths

| | HTML page width font size | | p element width

| —– | ————— | —————- |

640 px | | 640/100 = 6.4 px 15.625 * 6.4 = 100 px | |

480 px | | 480/100 = 4.8 px 15.625 * 4.8 = 75 px | |

320 px | | 320/100 = 3.2 px 50 px | | * 3.2 = 15.625

It can be found that when the UE graph width is the same as the screen width, the element width obtained on both sides is the same

The above calculation process is a bit tedious, which can be simplified by preprocessing function. The following is an example of Sass, similar to less

$ue-width: 640; /* the width of the ue graph */

@function px2rem($px) {
  @return #{$px/$ue-width*100}rem;
}

p {
  width: px2rem(100);
}
Copy the code

The above code compiles as follows

p {width: 15.625rem} 
Copy the code

In fact, once you have postCSS, this process should be put into postCSS. The source code is as follows

p {width: 100px2rem} 
Copy the code

Postcss will process px2REM. The result is as follows. If you are interested, write a postCSS plug-in for px2REM

p {width: 15.625rem} 
Copy the code

A better solution than Rem

As mentioned above, if you want the page elements to change with the page width, you need a new unit, x, which is equal to one hundredth of the screen width. Css3 brings in REM as well as VW and VH

Vw — 1/100 of viewport width; Vh — 1/100 of viewport height — MDN

And if you’re smart enough to say, well, isn’t that the unit x? Yes, by definition, 1vw is equal to 1x, and with vw we can completely bypass the rem intermediary, and the two solutions are equivalent, you can see that VW is easier than REM, because REM is supposed to implement VW

/* rem solution */
html {fons-size: width / 100}
p {width: 15.625rem}

/* vw scheme */
p {width: 15.625vw}
Copy the code

Vw can also be combined with rem schemes so that YOU do not need JS to calculate HTML font sizes

html {fons-size: 1vw} /* 1vw = width / 100 */
p {width: 15.625rem}
Copy the code

Although VW has various advantages, VW also has disadvantages. First of all, THE compatibility of VW is not as good as THAT of REM, so we should have a look before using it

| | compatibility Ios | android |

| —- | —- | —- |

| rem 4.1 + 2.1 + | | |

| vw 4.4 + 6.1 + | | |

In addition, when using elastic layout, the maximum width will be limited. For example, when viewing our page on the PC, VW will not be able to exert itself at this time, because there are no other units except max-width, while REM can easily solve this problem by controlling the maximum font-size of THE HTML root element

Rem is not a silver bullet

Rem is an implementation method of elastic layout. Elastic layout can be counted as a kind of responsive layout, but responsive layout is not elastic layout. Elastic layout emphasizes geometric scaling and 100% restoration. Responsive layouts emphasize different displays on different screens, such as media queries

There are two starting points for users to choose a large screen. Some people want bigger fonts and bigger pictures, such as my presbyopia. Some people want more content and don’t want a bigger icon; Some people want a mirror… – YanHai mirror

In my opinion, REM is not suitable for general content-based websites, because large-screen users can choose whether to use larger fonts or more content. Once REM is used, it will deprive users of their freedom. For example, Baidu knows that it has no experience in using REM layout. Rem is more suitable for apps, ICONS and pictures, such as Taobao and activity pages, because the size of ICONS cannot be increased when the font is enlarged

Rem can achieve 100% reduction degree, but the production cost of REM is also higher, and there are still some problems when REM is used, which are listed as follows:

Firstly, the font size cannot be rem. There is no linear relationship between font size and font width, so rem cannot be used for font size. Because the font size is set for the root element, it affects all elements that do not have font sizes set, because font sizes are inherited.

We can change the font size on the body, for example, to 16px, but if the user sets the font size to a larger size, the user’s Settings will be invalid. For example, it is reasonable to set it to the user’s default font size

html {fons-size: width / 100}
body {font-size: 16px} 
Copy the code

So how do you make the font size responsive? You can do this by changing the size of the body font, and all the font sizes are set in em units, yes em, because only EM can do this, synchronous change, I said em is for fonts

@media screen and (min-width: 320px) {
	body {font-size: 16px}
}
@media screen and (min-width: 481px) and (max-width:640px) {
	body {font-size: 18px}
}
@media screen and (min-width: 641px) {
	body {font-size: 20px}
}

p {font-size: 1.2 em}
p a {font-size: 1.2 em}
Copy the code

Second, what if the user is browsing on the PC and the page is too wide? Generally, we set a maximum width, and if it’s larger than that, the page will be centered with white space on both sides

var clientWidth = document.documentElement.clientWidth;
clientWidth = clientWidth < 780 ? clientWidth : 780;
document.documentElement.style.fontSize = clientWidth / 100 + 'px';
Copy the code

Set the body width to 100rem and center it horizontally

body { margin: auto; width: 100rem } 
Copy the code

Third, how to break if the user disables JS? In fact, there are not many such users, or give up…

You can first add a noscript tag to prompt the user

<noscript>Turn on JavaScript for a better experience</noscript> 
Copy the code

Add a default font size of 320 to the HTML so that the page can be displayed

HTML {fons - size: 3.2 px}Copy the code

If you want a better experience, add a media query

@media screen and (min-width: 320px) {
	html {font-size: 3.2 px.}
}
@media screen and (min-width: 481px) and (max-width:640px) {
	html {font-size: 4.8 px.}
}
@media screen and (min-width: 641px) {
	html {font-size: 6.4 px.}
}
Copy the code

Rem is not a silver bullet, and there is no silver bullet in this world. Every plan has its advantages and disadvantages. Learn to make choices and compromise

Rem layout scheme

From the above, it can be found that the best flexible layout is rem+ JS, and it also has to solve the noscript problem, solve the font problem, and solve the screen width problem

The problem with the above solution is that if you split it into 100 pieces, suppose the screen width is 320 and the HTML size is 3.2px, but the minimum font size supported by the browser is 12px. Well, let’s split it 10 ways, just replace all the 100’s with 10’s

Here’s a complete example of how CSS computes without using a preprocessor, which is simple

The HTML code looks like this


        
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <title>Rem layout</title>
</head>
<body>
    <noscript>Turn on JavaScript for a better experience</noscript>

    <div class="p1">The width is 50% of the screen width and the font size is 1.2em<div class="s1">Font size 1.2.em</div>
    </div>

    <div class="p2">The width is 40% of the screen width, and the font size is default<div class="s2">Font size: 1.2em</div>
    </div>
</body>
</html>
Copy the code

The CSS code is as follows

html {
    font-size: 32px; / * * / 320/10
}
body {
    font-size: 16px; /* Modify font size */
    /* Prevent pages from being too wide */
    margin: auto;
    padding: 0;
    width: 10rem;
    /* Prevent pages from being too wide */
    outline: 1px dashed green;
}

/* js Deprecated rollback scheme */
@media screen and (min-width: 320px) {
    html {font-size: 32px}
    body {font-size: 16px; }
}
@media screen and (min-width: 481px) and (max-width:640px) {
    html {font-size: 48px}
    body {font-size: 18px; }
}
@media screen and (min-width: 641px) {
    html {font-size: 64px}
    body {font-size: 20px; }
}

noscript {
    display: block;
    border: 1px solid #d6e9c6;
    padding: 3px 5px;
    background: #dff0d8;
    color: #3c763d;
}
/* js Deprecated rollback scheme */

.p1. .p2 {
    border: 1px solid red;
    margin: 10px 0;
}

.p1 {
    width: 5rem;
    height: 5rem;

    font-size: 1.2 em; /* Use em */ for font
}

.s1 {
    font-size: 1.2 em; /* Use em */ for font
}

.p2 {
    width: 4rem;
    height: 4rem;
}
.s2 {
    font-size: 1.2 em /* Use em */ for font
}
Copy the code

The js code looks like this

var documentElement = document.documentElement;

function callback(a) {
    var clientWidth = documentElement.clientWidth;
    // Screen width greater than 780, not zooming in
    clientWidth = clientWidth < 780 ? clientWidth : 780;
    documentElement.style.fontSize = clientWidth / 10 + 'px';
}

document.addEventListener('DOMContentLoaded'. callback);
window.addEventListener('orientationchange' in window ? 'orientationchange' : 'resize'. callback);
Copy the code

The page looks like this, and the full example is here

conclusion

If you have any questions about this article, please leave a comment. If you found this article helpful, then appreciate it

The relevant data

  • Use CSS3 REM and VW to create a convenient workflow for proportionally responsive pages
  • Thinking of front-end design draft and workflow from the font-size of netease and Taobao
  • Rem for mobile Web
  • Use REM to provide consistent font size

The original web site: http://yanhaijing.com/css/2017/09/29/principle-of-rem-layout/

Welcome to subscribe to my wechat public account, only push the original text. Scan code or search: Yan Hai Mirror