CSS preprocessor, mobile adaptation

1. The concept of preprocessor

1.1 Pain points of CSS writing

As a style language , CSS itself is no problem for adding styles to HTML elements .

However, the current front-end projects have become more and more complex, and it is no longer a simple few lines of CSS. We need thousands or even tens of thousands of lines of CSS to complete the beautification of the page.

As the amount of code increases, it will inevitably cause a lot of inconvenience in writing:

  • For example, a large number of repetitive codes can be managed and extracted with classes , but it is still inconvenient to use ;
  • For example, it is impossible to define variables (of course, it is currently supported) , if a value is modified, then a lot of code needs to be modified, and the maintainability is very poor ; (such as theme color)
  • For example, there is no special scope and nesting , and a large number of id/classes need to be defined to ensure the accuracy of the selector and avoid style confusion;
  • Wait for a series of questions;

So there is a name for CSS called " name-oriented programming ";

In order to solve a large number of problems faced by CSS in the community, a series of CSS preprocessors (CSS_preprocessor) appeared

  • A CSS preprocessor is a program that allows you to generate CSS through the preprocessor's own unique syntax ;
  • There are many CSS preprocessors to choose from on the market, and most CSS preprocessors will add some features that native CSS does not have;
  • The code will eventually be converted to CSS to run, because only CSS is recognized for the browser;

1.2. Common CSS preprocessors

What are the common preprocessors? At present, three preprocessors are used more:

Sass/Scss

  • Born in 2007, the earliest and most mature CSS preprocessor, supported by the ruby ​​community, is part of Haml (a template system);
  • Currently influenced by LESS, it has evolved to SCSS which is fully compatible with CSS ;

Less:

  • Appeared in 2009, it is greatly influenced by SASS, but it also uses CSS syntax, making it easier for most developers to get started;
  • Compared with SASS, the programmable function is not enough, but the advantage is that it is simple and convenient to use, compatible with CSS, and it is enough for use;
  • In addition, it also affected the evolution of SASS to the era of SCSS;
  • The famous Twitter Bootstrap uses LESS as the underlying language, including React's UI framework AntDesign.

Stylus:

  • Created in 2010, it comes from the Node.js community and is mainly used to support CSS preprocessing for Node projects;
  • The syntax is biased towards Python, and the usage rate is much less than that of Sass/Less

2、Less

2.1. Know Less

Less (short for Leaner Style Sheets) is a CSS extension language and compatible with CSS.

  • Less adds a lot of features that are better than CSS ;
  • Such as defining variables, mixing in, nesting, computing, etc.;
  • Less will eventually need to be compiled into CSS to run in the browser (including deployed to the server);

2.2. Compilation of less code

How is less code compiled into CSS code to run?

Method 1: Download the Node environment, download the less tool through npm package management, and use the less tool to compile the code;

Method 2: Compile into CSS through the VSCode plug-in or compile online, Less Preview (online playground)

Method 3: Introduce CDN's less compiled code to process less in real time;

<script src="https://cdn.jsdelivr.net/npm/less@4" ></script>

Method 4: Download the js code compiled by less to the local, execute the js code to compile less;

2.3, Less is compatible with CSS

  • Less is compatible with CSS, so we can write all CSS codes in Less files;
  • Just change the extension of css to the end of .less;

2.4. Variables 

In a large-scale web project, some of the property values ​​​​used by our CSS are often specific

  • For example, we use the theme color value, then write a syntax similar to #f3c258 format every time;
  • On the one hand, it is not convenient to remember, and the style needs to be rewritten or copied;
  • On the other hand, if the theme color changes one day, we need to modify a lot of code;
  • Therefore, we can define common colors or fonts as variables to use;

Use the following format to define variables in Less;

@variable name: variable value;

2.5. Nesting 

In previous projects, when we needed to find an inner element, we often needed to nest many layers of selectors

Less provides nesting of selectors 

Special symbols: & indicates the parent of the current selector 

html code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>

    <link href="./less/02_less的语法-兼容CSS-变量-嵌套.less" rel="stylesheet/less">
    <script src="https://cdn.jsdelivr.net/npm/less@4" ></script>

</head>
<body>

    <!-- 1.兼容css -->
    <!-- <div class="box">
      我是box
    </div> -->

    <!-- 2.定义变量 -->
    <div class="box">
        <p class="pel">我是p元素</p>
        <h1>我是h1元素 <span class="keyword">关键字</span></h1>
        <p>
            我是一个大的段落
            <a class="link" href="#">百度一下</a>
        </p>
    </div>

    <!-- &符号的练习 -->
    <ul class="list">
        <li class="item">1</li>
        <li class="item">2</li>
        <li class="item">3</li>
        <li class="item">4</li>
        <li class="item">5</li>
    </ul>

</body>
</html>

less code

// 1.兼容CSS代码
// .box {
//   width: 100px;
//   height: 100px;
//   background-color: orange;
//   font-size: 20px;
//   color: #fff;
// }

// 2.定义变量
@mainColor: #a40011;

@smallFontSize: 12px;
@normalFontSize: 14px;
@bigFontSize: 18px;

// .box .pel {
//   color: @mainColor;
//   font-size: @normalFontSize;
// }

// .box h1 .keyword .section .list .item a .desc {
//   color: @mainColor;
//   font-size: @bigFontSize;
// }

// .box p .link {
//   color: @mainColor;
//   font-size: @smallFontSize;
// }

// 3.选择器的嵌套
.box {
  .pel {
    color: @mainColor;
    font-size: @normalFontSize;
  }

  h1 {
    .keyword {
      color: @mainColor;
      font-size: @bigFontSize;
    }
  }

  p {
    a.link {
      color: @mainColor;
      font-size: @smallFontSize;

      background-color: #0f0;

      &:hover {
        color: #00f;
      }
    }
  }
}

// &符号的练习
.list {
  .item {
    font-size: 20px;

    &:hover {
      color: @mainColor;
    }

    &:nth-child(1) {
      color: orange;
    }

    &:nth-child(2) {
      color: #00f;
    }
  }
}

2.5. Operations

In Less, the arithmetic operators +, -, *, / can operate on any number, color or variable.

  • Arithmetic operators perform unit conversion before addition, subtraction or comparison, and the calculation result is based on the unit type of the leftmost operand;
  • Units are ignored if the unit conversion is invalid or meaningless;

2.6. Mixing (Mixins) 

In the original CSS writing process, there may be a lot of the same code in multiple selectors

  • We hope that these codes can be extracted to an independent place, and any selector can be reused;
  • Mixing (Mixins) is provided in less to help us complete such operations;

A mixin is a method of taking (or mixing in) a set of properties from one ruleset to another.

Note: When there are no parameters in the mix, the parentheses can be omitted, but this is not recommended; 

Mixins can also pass in variables 

Mapping (Maps): 

Combination of mix-in and mapping: mix-in can also be used as a custom function 

html code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>
    <link href="./less/03_less语法-运算-混入-映射.less" rel="stylesheet/less">
    <script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
</head>
<body>

    <!-- 1.less中的运算 -->
    <!-- <div class="box">
      我是box
    </div> -->

    <!-- 2.混入mixins -->
    <div class="box1">
        向阳草木青,明媚春光暖。伴随着天气晴好、气温回升,沉闷了一个冬日的人们纷纷走出家门,与大自然亲密接触,恣意享受春日好时光。
    </div>
    <div class="box2">
        “露营热”不断升温的背后,是人们生活方式日趋多元、生活观念不断蝶变的折射。
    </div>

</body>
</html>

less code:

// 1.运算
// .box {
//   font-size: 20px;
//   width: 10% + 50px;
//   height: 100px;
//   background-color: #ff0000 + #00ff00;
// }

// px to rem

// 2.混入
// 2.1. 混入的基本使用
.nowrap_ellipsis {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

// 2.2.混入是可以传递参数(定义变量)的
.box_border(@borderWidth: 5px, @borderColor: purple) {
  border: @borderWidth solid @borderColor;
}

// 2.3.混入和映射(Map)结合使用
// 作用: 弥补less中不能自定义函数的缺陷
.box_size {
  width: 100px;
  height: 100px;
}

.box1 {
  width: .box_size()[width];
  background-color: #f00;

  .nowrap_ellipsis();
  .box_border();
}

.box2 {
  width: 150px;
  background-color: #0f0;

  .nowrap_ellipsis();
  .box_border(10px, orange);
}

2.7, less other grammatical supplements

extend inheritance

  • Similar to mixins, it is used to reuse code ;
  • Compared with mixins, inherited code will eventually be converted into a union selector;

Less built-in functions

Scope

  • When looking up a variable, first look up variables and mixins locally;
  • If not found, inherit from the "parent" level scope; 

Comments : In Less, both block comments and line comments can be used; 

Importing

  • The import method is consistent with the usage of CSS;
  • Import a .less file, all variables in this file can be used ;
  • If the imported file has a .less extension, the extension can be omitted ;

html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>
    <link href="./less/04_less语法-继承-函数-注释-导入.less" rel="stylesheet/less">
    <script src="./js/lessc.js"></script>
</head>
<body>

    <div class="box">
        我是box文本

        <div class="item">
            我是item文本
            <span>呵呵呵呵</span>
            我是结束文本
        </div>

    </div>

</body>
</html>

less code:

// 1.extend
// .box_border {
//   border: 5px solid #f00;
// }

// .box {
//   width: 100px;
//   background-color: orange;

//   // .box_border();
//   &:extend(.box_border);
// }

// 2.内置函数
// .box {
//   color: color(skyblue);
//   width: convert(100px, "in");
//   font-size: ceil(18.5px);
//   background-color: orange;
// }


// 3.作用域(scope)
@mainColor: #f00;

.box_mixin {
  @mainColor: orange;
}

.box {
  // @mainColor: #0f0;

  .item {
    span {
      color: @mainColor;

      .box_mixin();
      // @mainColor: #00f;
    }
  }
}

// 4.注释(comment)
// 单行注释
/* 多行注释 */ 

3. Know Sass and Scss

  • In fact, originally Sass was part of Haml, a templating system designed and developed by Ruby developers.
  • Therefore, the syntax of Sass uses a syntax similar to Ruby, without curly braces, without semicolons, and with strict indentation;

We will find that its syntax is very different from CSS. Later, the official launched a new syntax SCSS, which means Sassy CSS, which is fully compatible with CSS.

At present, learning SCSS at the front end can directly learn SCSS:

  • The syntax of SCSS also includes variables, nesting, mixing, functions, operators, scopes, etc.;
  • Usually also includes more powerful control statements, more flexible functions, interpolation syntax, etc.;
  • You can learn some SCS grammars based on the less grammar you learned before;
  • Sass: Sass Basics (sass-lang.com)

 

4. Mobile terminal adaptation

4.1. What is mobile adaptation?

With the rapid development of the mobile Internet, people have become more and more accustomed to using mobile phones to complete most of their daily affairs.

  • Front-end We have learned a lot of front-end development knowledge of HTML and CSS, and also carried out actual project combat;
  • This knowledge is also applicable to mobile terminal development, but if we want a page to be truly adapted to the mobile terminal, we'd better learn more about the mobile terminal;

Mobile terminal development currently mainly includes three categories:

  • Native App development (iOS, Android, RN, uniapp, Flutter, etc.)
  • Small program development (native small program, uniapp, Taro, etc.)
  • Web pages (Web pages on the mobile side, which can be browsed with a browser or webview)

Because there are many mobile devices at present, we need to make some adaptations to them.

There are two concepts here:

  • Adaptive : automatically adjust the size and size according to different device screen sizes;
  • Responsive : It will automatically adjust with the real-time changes of the screen, which is a kind of self-adaptation ;

4.2, know the viewport viewport

We have already briefly understood the concept of the viewport before:

  • In a browser, the area we can see is the viewport ;
  • We said that fixed is positioned relative to the viewport ;
  • In the page on the PC side , we do n't need to distinguish the viewport , because our layout viewport and visual viewport are the same;

But on the mobile side, it's different. The viewport you layout is not the same as the viewport you can see.

  • This is because the webpage window on the mobile terminal is often relatively small , and we may hope that a large webpage can be completely displayed on the mobile terminal;
  • So by default, the layout viewport of the mobile terminal is larger than the visual viewport;

So on the mobile side, we can divide the viewport into three situations:

  • layout viewport
  • visual viewport (visual layout)
  • ideal viewport (ideal layout)

The distinction between these concepts actually comes from ppk, who is also a person who has contributed a lot to the front end (especially in mobile browsers)

A tale of two viewports — part two

4.3. Layout viewport and visual viewport

layout viewport

By default, how will a webpage on the PC side be displayed on the mobile side?

  • First, it will lay out the box and content of a page according to the width of 980px;
  • Second, in order to show that it can be completely displayed on the page, the entire page is reduced;

The viewport we layout relative to 980px is called the layout viewport (layout viewport) ;

  • The default width of the layout viewport is 980px ;

visual viewport

  • If we display the content according to 980px by default, a part of the area on the right side will not be displayed, so the mobile browser will zoom the page by default to display it in the visible area of ​​the user;
  • Then the viewport displayed in the visible area is the visual viewport.

Press shift+left mouse button on Chrome to zoom.

4.4, ideal viewport (ideal viewport) 

If all web pages are laid out on the mobile terminal according to 980px, then the final page will be scaled and displayed.

  • In fact, this method is not conducive to our mobile development. What we hope is to set 100px, then the display is 100px;
  • How to do this? By setting the ideal viewport (ideal viewport) ;

Ideal viewport:

  • The default layout viewport is not suitable for our layout;
  • We can set the width and zoom of the layout viewport to meet the normal layout of a mobile window ;
  • At this time, you can set the viewport in meta

value

possible added value

describe

width

A positive integer, or the string device-width

Defines the width of the viewport .

height

A positive integer, or the string device-height

Defines the height of the viewport . Not used by any browser.

initial-scale

a positive number between 0.0 and 10.0

Defines the scaling between the device width and the viewport size.

maximum-scale

a positive number between 0.0 and 10.0

Define the maximum value of scaling, must be greater than or equal to minimum-scale , otherwise the performance will be unpredictable.

minimum-scale

a positive number between 0.0 and 10.0

Defines the minimum value for scaling, must be less than or equal to maximum-scale , otherwise performance will be unpredictable.

user-scalable

yes or no

The default is yes , if it is set to no , the current page cannot be zoomed. Browsers can ignore this rule;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">

    <!-- width: 设置布局视口的宽度 -->
    <meta content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
          name="viewport">
    <title>Document</title>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        .box {
            width: 100px;
            height: 100px;
            background-color: orange;
        }
    </style>
</head>
<body>

    <div class="box"></div>

</body>
</html>

 

5. Mobile terminal adaptation scheme

The screen size of the mobile terminal is usually very diverse, and many times we want to display different sizes on different screen sizes;

  • For example, we set up a 100x100 box
    • Displayed on a 375px screen is 100x100;
    • Displayed on a 320px screen is 90+x90+;
    • Displayed on a 414px screen is 100+x100+;
  • Other sizes are similar, such as padding, margin, border, left, and even font-size, etc.;

At this time, we may think of some solutions to deal with the size:

  • Option 1 : percentage setting ;
    • Because the percentage values ​​of different attributes may correspond to different reference objects, it is often difficult to unify the percentages;
    • Therefore, percentages are rarely used in mobile adaptation;
  • Solution 2 : rem unit + font-size of dynamic html ;
  • Option three : vw unit ;
  • Solution 4 : flexible layout of flex ;

5.1, font-size of rem+ dynamic html

        The rem unit is set relative to the font-size of the html element, so if we need different sizes on different screens, we can dynamically modify the font-size of the html.

For example the following case:

  • Set the width of a box to 2rem ;
  • Set the font-size of html on different screens to be different;

screen size

html font -size

Set the width of the box

final width of the box

375px

37.5px

1 thing

37.5px

320px

32px

1 thing

32px

414px

41.4px

1 thing

41.4px

In this way, in development, we only need to consider two issues:

  • Question 1: Set different font-sizes of html for different screens;
  • Question 2: Convert the original size to be set into rem unit;

5.2, font-size of rem

Option 1: Media queries

  • The font-size of screen html in different size ranges can be set through media queries ;
  • shortcoming:
    • We need to write a lot of media queries for different screens;
    • If the size is changed dynamically, it will not be updated in real time;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>
    <style>
        @media screen and (min-width: 320px) {
            html {
                font-size: 20px;
            }
        }

        @media screen and (min-width: 375px) {
            html {
                font-size: 24px;
            }
        }

        @media screen and (min-width: 414px) {
            html {
                font-size: 28px;
            }
        }

        @media screen and (min-width: 480px) {
            html {
                font-size: 32px;
            }
        }

        .box {
            width: 5rem;
            height: 5rem;
            background-color: orange;
        }
    </style>
</head>
<body>

    <div class="box">

    </div>

</body>
</html>

Solution 2: Write js code

  • If you want to change the screen size in real time, the font-size can also be changed in real time through js code;
  • method:
    • Calculate the size of font-size according to the width of html, and set it to html;
    • Monitor the real-time changes of the page , and reset the size of font-size to html ;

html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>

    <script src="./js/hy_flexible.js"></script>

    <style>
        body {
            font-size: 16px;
        }

        .box {
            width: 5rem;
            height: 5rem;
            background-color: orange;
        }

        p {
            font-size: 0.5rem;
        }
    </style>
</head>
<body>

    <div class="box">

    </div>

    <p>我是文本</p>

    <!-- 动态的修改html的font-size -->
    <span>哈哈哈哈哈哈</span>

</body>
</html>

js code:

// 1.获取html的元素
const htmlEl = document.documentElement

function setRemUnit() {
    // 2.获取html的宽度(视口的宽度)
    const htmlWidth = htmlEl.clientWidth
    // 3.根据宽度计算一个html的font-size的大小
    const htmlFontSize = htmlWidth / 10
    // 4.将font-size设置到html上
    htmlEl.style.fontSize = htmlFontSize + "px"
}

// 保证第一次进来时, 可以设置一次font-size
setRemUnit()

// 当屏幕尺寸发生变化时, 实时来修改html的font-size
window.addEventListener("resize", setRemUnit)

Solution 3: lib-flexible library

  • In fact, the lib-flexible library does the same thing , you can also import it directly;

html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>

    <script src="./js/lib_flexible.js"></script>

    <style>
        .box {
            width: 5rem;
            height: 5rem;
            background-color: orange;
        }

        p {
            font-size: 0.5rem;
        }
    </style>
</head>
<body>

    <div class="box">

    </div>

    <p>我是文本</p>

</body>
</html>

js code:

(function flexible(window, document) {
    var docEl = document.documentElement
    var dpr = window.devicePixelRatio || 1

    // adjust body font size
    function setBodyFontSize() {
        if (document.body) {
            document.body.style.fontSize = (12 * dpr) + 'px'
        } else {
            document.addEventListener('DOMContentLoaded', setBodyFontSize)
        }
    }

    setBodyFontSize();

    // set 1rem = viewWidth / 10
    function setRemUnit() {
        var rem = docEl.clientWidth / 10
        docEl.style.fontSize = rem + 'px'
    }

    setRemUnit()

    // reset rem unit on page resize
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow', function (e) {
        if (e.persisted) {
            setRemUnit()
        }
    })

    // detect 0.5px supports
    if (dpr >= 2) {
        var fakeBody = document.createElement('body')
        var testElement = document.createElement('div')
        testElement.style.border = '.5px solid transparent'
        fakeBody.appendChild(testElement)
        docEl.appendChild(fakeBody)
        if (testElement.offsetHeight === 1) {
            docEl.classList.add('hairlines')
        }
        docEl.removeChild(fakeBody)
    }
}(window, document))

5.3, unit conversion of rem

Solution 1: Manual conversion

  • For example, there is a box with a width and height of 100px on a 375px screen;
  • We need to convert 100px into the corresponding rem value;
  • 100/37.5=2.6667, other calculations can be done in the same way;

Solution 2: less/scss function

Solution 3: postcss-pxtorem : currently in the front-end engineering development, we can use webpack tools to complete automatic conversion; 

Solution 4: VSCode plug-in: px to rem plug-in, automatically converted when writing;

5.4. Adaptation scheme - vw

Such a sentence has been written on flexible GitHub:

So it is more recommended to use the two units vw and wh of viewport .

What is the compatibility of vw?

5.5 Comparison of vw and rem 

In fact, rem is used as a transitional solution, and it also uses the idea of ​​​​vw.

  • Whether it is the js written by ourselves or the source code of flexible;
  • Both equate 1rem to 1/10 of the design draft, and use 1rem to calculate the size relative to the entire screen;
  • So let's think about it, isn't 1vw just equal to 1/100 of the screen?
  • And it has more advantages than rem;

Advantages of vw over rem:

  • Advantage 1 : There is no need to calculate the font-size of HTML, and there is no need to set such a font-size for HTML;
  • Advantage 2 : It is not necessary to set another font-size for the body to prevent inheritance because of setting the font-size of html;
  • Advantage 3 : Because it does not depend on the font-size size, there is no need to worry about the font-size size of html being tampered with for some reason, and the page size is confused;
  • Advantage 4: vw is more semantic than rem, 1vw is just 1/100 of the viewport size;
  • Advantage 5: It can have all the advantages of rem before;

We only face one problem with vw, just convert the size into the unit of vw;

Therefore, compared to rem, it is recommended that you use vw (but understanding rem is still very important)

5.6. Unit conversion of vw

Solution 1: Manual conversion

  • For example, there is a box with a width and height of 100px on a 375px screen;
  • We need to convert 100px into the corresponding vw value;
  • 100/3.75=26.667, other calculations can be done in the same way;

Solution 2: less/scss function

Solution 3: postcss-px-to-viewport-8-plugin: Like rem, in front-end engineering development, we can use webpack tools to complete automatic conversion;

Solution 4: VSCode plug-in: px to vw plug-in, automatically converted when writing;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Document</title>
    <style>
        /*
          rem:
            1> 动态的设置html的font-size
              font-size: 视口的宽度 / 10
            2> 换算成rem的单位
        */
        /* html {
          font-size: 10vw;
        } */

        /*
          1> 动态的设置html的font-size
            font-size: 视口的宽度 / 100 -> 1vw
        */

        .box {
            width: 26.667vw;
            height: 26.666vw;
            background-color: orange;
        }
    </style>
</head>
<body>

    <div class="box"></div>

</body>
</html>

Guess you like

Origin blog.csdn.net/weixin_52851967/article/details/128784340