Rem + js layout

As we all know, REM changes according to the size of the root element, and the essence of REM is proportional scaling. Let’s start with REM compatibility

Browser support is good,

  • Android Browser2.1+, iOS Safari4.1+ (iOS Safari 5.0-5.1 supports REM, but does not support media query)
  • IE 9 and IE 10 do not support REM units when used in font properties (the entire declaration is ignored) or on pseudo-elements
$width: $blocks; // $px: $width: $blocks; The width of the element // rem corresponds to px, 1 rem representative set of HTML font in JS - size values (width of a piece of) $p $rem -- -- -- -- -- -- -- -- -- -- -- -- -- = = = -- -- -- -- -- -- -- -- -- -- -- - $design width $$rem = $p/blocks $design-width * $blocksCopy the code

steps

$block = 3.75; $block = 3.75

document.documentElement.style.fontSize = document.documentElement.clientWidth/3.75 = 100
Copy the code

It’s not a rule to divide by 3.75, but it’s also a rule to divide by 100, just to divide it by the width, so 3.75 is divided by 3.75, and 100 is divided by 100. There are also people who don’t use JS to dynamically evaluate root elements and use media queries (which will be discussed later)

one

models The width of the Root element size
iphone5 320 85.33
Iphone6/7/8, iphone X 375 100
IPhone 6/7/8 Plus, iPhone XR, iPhone XR Max 414 110.4

So this is one rem at different sizes is equal to different sizes of PX

2. Px becomes REM

We can’t convert px to REM every time we write, so we need to convert PX to REM. Let’s say we have a 300px element, and rem is 300/375×3.75 = 1.5rem. So the actual sizes for elements 320, 375, and 414 are: the size of the root element times the size of REM = 255.99px, 300px, 331.2px

  • Postcss plugin – px2rem plug-in
npm i --save postcss-plugin-px2rem

Copy the code

Used in WebPack 3.x

 const webpack = require("webpack");
 const px2rem = require("postcss-plugin-px2rem");
  plugins: [
    new webpack.LoaderOptionsPlugin({
      vue: {
        postcss: [
          px2rem({
            rootValue: 100.exclude: /(node_module)/})]}})]Copy the code

Used in vuE-CLI3. x

css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    require('postcss-plugin-px2rem')({}),]}}Copy the code

This section describes pX2REM parameters

3. Learn the code from a website

This is how they calculate the font size of HTML by first listening for window change events (orientationChange events are triggered when the device changes orientation), then dividing the screen width by the minimum width multiplied by 20, and rounded fontSize. Font size is always set to 20px for PC, and fontSize for dynamic calculation is used on mobile

var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
    var clientWidth = docEl.clientWidth;
    if(! clientWidth)return;
    var fontSize = 20 * (clientWidth / 320);
    fontSize = (fontSize > 54)?54: fontSize;

    if(~~fontSize ! == fontSize) { fontSize = ~~fontSize// ~~ is equivalent to -(x+1) +1.
    }

    // For PC access
    if(!/windows phone|iphone|android/ig.test(window.navigator.userAgent)) {
        fontSize = 20;
    }

    docEl.REM2PX = 20;  // I don't understand
    docEl.style.fontSize = fontSize + 'px';
    var dpi =  window.devicePixelRatio;
   
    docEl.setAttribute('data-dpi',dpi); // Set the custom data-dpi attribute for HTML

if(! doc.addEventListener)return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
recalc();
Copy the code

Rem + media query

Javascript dynamically sets the font size of the HTML to a media query. Media query feels very difficult to determine boundaries, especially note that iOS Safari 5.0-5.1 does not support media query, but now updated to 14, this is not important

@media screen and (max-width: 320px) {
  html {
    font-size: 14px; }}@media only screen and (max-width: 414px) and (min-width: 360px) {
  html {
    font-size: 16px; }}@media only screen and (max-width: 640px) and (min-width: 414px) {
  html {
    font-size: 18px; }}@media only screen and (max-width: 768px) and (min-width: 640px) {
  html {
    font-size: 20px; }}@media only screen and (min-width: 768px) {
  html {
    font-size: 22px; }}Copy the code

Vw layout

compatibility

  • Part of IE9 support refers to support for “VM” rather than “Vmin”
  • IE10 partial support means that “Vmax” units are not supported.
  • Part of the support in iOS7 is due to the bad behavior of the “vh “unit.

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

/* the width of the window is 100vw. $vw is the corresponding wide accounted for more than $p $$px vw -- -- -- -- -- -- -- -- -- -- -- -- -- = = = -- -- -- -- -- -- -- -- -- -- -- - $design width 100 vw * / $vw = ($p / $design - width) * 100 vwCopy the code

vw+rem

This combination is usually HTML font size with VW, others rem

  • Root element Settings
/* Width of mobile page design draft */
$design-width: 750;
/* DPR reference value of mobile terminal page design draft */
$design-dpr: 2;
/* Split the mobile page into 10 pieces */
$blocks: 10;
/* Scale the supported minimum width of the device */
$min-device-width: 320px;
/* Scale the maximum width of supported devices */
$max-device-width: 540px;

/* The font-size definition of the HTML root element, which simply divides the page into $blocks for easy calculation */
@mixin root-font-size() {
    font-size: 100vw / $blocks;

    body {
        @include container-min-width();
    }

    /* Minimum width definition */
    @media screen and (max-width: $min-device-width) {
        font-size: $min-device-width / $blocks;
    }

    /* Maximum width definition */
    &[data-content-max] {  / / forbody[data-content-max] { @include container-max-width(); } @media screen and (min-width: $max-device-width) { font-size: $max-device-width / $blocks; }}}/* Sets the minimum width of the container to be stretched */
@mixin container-min-width() {
    margin-right: auto;
    margin-left: auto;
    min-width: $min-device-width;
}

/* Sets the maximum width of the container to be stretched */
@mixin container-max-width() {
    margin-right: auto;
    margin-left: auto;
    max-width: $max-device-width;
}

Copy the code
  • Other element Settings
/* Unit px is converted to rem */
@function px2rem($px) {
    @return #{$px / $design-width * $blocks}rem;
}
Copy the code
  • Font size
/* Set the font size, do not use rem units, according to the DPR value piecewise */
@mixin font-size($fontSize) {
    font-size: $fontSize / $design-dpr;

    [data-dpr="2"] & {
        font-size: $fontSize / $design-dpr * 2;
    }

    [data-dpr="3"] & {
        font-size: $fontSize / $design-dpr * 3; }}Copy the code

use

html {
    @include root-font-size();
}

header {
    height: px2rem(300);
    line-height: px2rem(300);
    text-align: center;
    background-color: #f2f2f2;
}
 
Copy the code

Refer to the above code

flexiable

  • flexiable

Since viewPort units are compatible with many browsers, lib-flexible is a transition solution that can be abandoned, and there are problems with both current and previous versions. It is recommended that you start using viewPort instead.

conclusion

Simple interfaces can be realized by REM + JS, and for complex content, rem+ VW can be used. We usually write PX directly, so we need to use relevant plug-ins to automatically convert us into REM, with postCSS, if you are interested, you can try it. I looked at a lot of code, and the implementation is pretty much the same.

reference

  • Yanhaijing.com/css/2017/09…

  • www.cnblogs.com/imwtr/p/964…

  • www.npmjs.com/package/px2…

  • amfe-flexible