The introduction

Responsive layout means that the same page has different layouts for different screen sizes. The traditional way of development is to develop a set of PC terminal, mobile terminal and another set of development, and the use of responsive layout as long as the development of a set of enough, the disadvantage is that CSS is heavy. Here is a blog site, the results of different equipment after adaptation, respectively, the iphone 5 / SE, iphone6/7/8, iphone 6/7/8 plus, the pro, dell desktop widescreen (1440 X 900).

The difference between responsive design and adaptive design: responsive development of a set of interfaces, through the detection of viewport resolution, for different clients do code processing in the client, to show different layout and content; Adaptive needs to develop multiple sets of interfaces, through the detection of viewport resolution, to determine the current access to the device is PC, tablet, mobile phone, so as to request the service layer, return different pages.

The implementation scheme of the responsive layout

1. Media query

CSS3 media queries allow us to define different styles for different media types, and when resizing the browser window, the page will also rerender the page according to the width and height of the browser.

How do I select a screen size split point

How to determine the split point of media query is also a problem that will be encountered in development. The following is the distribution of mobile device and computer screen resolution on the market. It can be found that different brands and models of devices generally have different screen resolutions

If we choose 600 px, 900 px, 1200 px, 1800 px as a division point, can be adapted to common 14 models:

Of course this is just one of those kind of segmentation scheme, we can also be divided like this: 480 px, 800 px, 1400 px, 1400 px

How does Bootstrap, once a typical responsive layout framework, make breakpoints?

The above segmentation scheme may not necessarily meet the actual needs of the project. We can first use the segmentation points with large span for segmentation, and then add new segmentation points according to the actual situation if the mismatch occurs.

Mobile priority OR PC priority

Whether mobile-first or PC-first is based on the fact that the later styles overwrite the previous styles as the screen width increases or decreases. Therefore, the mobile terminal preferentially uses min-width and the PC terminal preferentially uses max-width.

Mobile first:

/* iphone6 7 8 */
body {
    background-color: yellow;
}
/* iphone 5 */
@media screen and (max-width: 320px) {
    body {
      background-color: red; }}/* iphoneX */
@media screen and (min-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    body {
      background-color: #0FF000; }}/* iphone6 7 8 plus */
@media screen and (min-width: 414px) {
    body {
      background-color: blue; }}/* ipad */
@media screen and (min-width: 768px) {
    body {
      background-color: green; }}/* ipad pro */
@media screen and (min-width: 1024px) {
    body {
      background-color: #FF00FF; }}/* pc */
@media screen and (min-width: 1100px) {
    body {
      background-color: black; }}Copy the code

PC priority:

/* pc width > 1024px */
    body {
        background-color: yellow;
    }
/* ipad pro */
@media screen and (max-width: 1024px) {
    body {
        background-color: #FF00FF; }}/* ipad */
@media screen and (max-width: 768px) {
    body {
        background-color: green; }}/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
    body {
        background-color: blue; }}/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    body {
        background-color: #0FF000; }}/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
    body {
        background-color: #0FF000; }}/* iphone5 */
@media screen and (max-width: 320px) {
    body {
        background-color: #0FF000; }}Copy the code

2. Percentage layout

Percentage units allow the width and height of components in the browser to vary with the height of the browser, resulting in a responsive effect. The grid system in Bootstrap uses percentages to define the width and height of elements. CSS3 supports maximum and minimum heights. You can use percentages together with Max (min) to define the width and height of elements under different devices.

/* pc width > 1100px */
html.body { margin: 0;padding: 0;width: 100%;height: 100%; }aside {
    width: 10%;
    height: 100%;
    background-color: red;
    float: left;
}
main {
    height: 100%;
    background-color: blue;
    overflow: hidden;
}
/* ipad pro */
@media screen and (max-width: 1024px) {
    aside {
      width: 8%;
      background-color: yellow; }}/* ipad */
@media screen and (max-width: 768px) {
    aside {
      float: none;
      width: 100%;
      height: 10%;
      background-color: green;
    }
    main {
      height: calc(100vh - 10%);
      background-color: red; }}/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
    aside {
      float: none;
      width: 100%;
      height: 5%;
      background-color: yellow;
    }
    main {
      height: calc(100vh - 5%);
      background-color: red; }}/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    aside {
      float: none;
      width: 100%;
      height: 10%;
      background-color: blue;
    }
    main {
      height: calc(100vh - 10%);
      background-color: red; }}/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
    aside {
      float: none;
      width: 100%;
      height: 3%;
      background-color: black;
    }
    main {
      height: calc(100vh - 3%);
      background-color: red; }}/* iphone5 */
@media screen and (max-width: 320px) {
    aside {
      float: none;
      width: 100%;
      height: 7%;
      background-color: green;
    }
    main {
      height: calc(100vh - 7%);
      background-color: red; }}Copy the code

But we have to figure out what the percentage of neutrons in CSS is relative to who. Let’s jump to the conclusion:

The percentage used in the height or width of the child element is relative to the child element’s immediate parent, width relative to the parent’s width, height relative to the parent’s height; The height of the parent of the child element with respect to direct nonstatic positioning (default positioning) if set as a percentage, and the width of the parent of the same element with respect to direct nonstatic positioning (default positioning) if set as a percentage. The padding of the child element, if set as a percentage, is relative to the width of the direct parent element, whether vertical or horizontal, regardless of the height of the parent element. Like the padding, the same is true of margin. If the margin of the child element is set to a percentage, it is relative to the width of the parent element, both vertically and horizontally. Border-radius is different. If border-radius is set to percentage, it is the width relative to itself. In addition to border-radius, translate and background-size are all relative to itself.

From the above introduction to percentage units, it is easy to see that there are two obvious disadvantages of using all percentage units to achieve a responsive layout:

  • It is difficult to calculate, if we want to define the width and height of an element, according to the design, must be converted to percentage units.
  • As you can see, the attribute relative to the parent element is not unique if the percentage is used in each attribute. Such aswidthandheightRelative to the parent elementwidthandheightAnd themargin,paddingBoth vertically and horizontally relative to the parent’s width,border-radiusRelative to the element itself and so on, making it easy to complicate the layout by using percentage units.

3. Rem layout

REM is a new unit in CSS3, and it is supported on Android2. X + and ios5+. The size of THE UNIT of REM is determined relative to the font-size of the root element HTML. The font-size of the root element is equivalent to providing a benchmark. When the size of the page changes, only the value of the font-size needs to be changed, so the size of the element with a fixed unit of REM will also change in response. Therefore, if rem is used to implement a responsive layout, you only need to dynamically change the font size according to the size of the view container (whereas EM is relative to the parent element).

Rem responsive layout idea:

  • In general, you don’t want to set specific widths for elements, but you can set specific widths for small ICONS
  • The height value can be set to a fixed value, the design of the draft, we strictly how big
  • All set fixed values are usedremDo units (first set a reference value in the HTML total:pxandremAnd then get on the effect diagrampxValue, when the layout is converted toremValue)
  • Js takes the width of the real screen, divides it by the width of the design, calculates the proportion, and resets the previous reference value according to the proportion, so that the project can adapt to the mobile terminal

Disadvantages of REM layout:

In a responsive layout, the root element’s font-size must be dynamically controlled by JS. This means that the CSS style is coupled to the JS code, and the code that changes the font-size must be placed before the CSS style

/* This code divides the view container into 10 parts, and the font size is represented by a tenth of the width. This code is executed in the header tag to dynamically define the size of the font size, so that 1rem represents different sizes in different visual containers. The rem fixed unit can be used to adapt the layout of different containers. * /
function refreshRem() {
    var docEl = doc.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem);
Copy the code

REM layout is also by far the best way to fit multiple screens. By default the font size of our HTML tags is 16px. We use media queries to set font sizes for different devices.

/* pc width > 1100px */ html{ font-size: 100%; } body { background-color: yellow; The font - size: 1.5 rem; } /* ipad pro */ @media screen and (max-width: 1024px) { body { background-color: #FF00FF; The font - size: 1.4 rem; } } /* ipad */ @media screen and (max-width: 768px) { body { background-color: green; The font - size: 1.3 rem; } } /* iphone6 7 8 plus */ @media screen and (max-width: 414px) { body { background-color: blue; The font - size: 1.25 rem; } } /* iphoneX */ @media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) { body { background-color: #0FF000; The font - size: 1.125 rem; } } /* iphone6 7 8 */ @media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) { body { background-color: #0FF000; font-size: 1rem; } } /* iphone5 */ @media screen and (max-width: 320px) { body { background-color: #0FF000; The font - size: 0.75 rem; }}Copy the code

Viewport unit

Css3 introduces a new unit vw/ VH, which is related to the view window. Vw represents the width relative to the view window, and VH represents the height relative to the view window. In addition to VW and VH, there are two related units vmin and vmax. The specific meaning of each unit is as follows:

unit meaning
vw Relative to the width of the window, 1VW is equal to 1% of the viewport width, so the window width is 100VW
vh Relative to the height of the window, 1vh is equal to 1% of the viewport height, i.e. the window height is 100vh
vmin Smaller values in vw and VH
vmax Large values in vw and VH

Measured in viewport unit, the width of viewport is 100vw and the height is 100vh (the left side is portrait and the right side is landscape). For example, if the browser viewport size is 650px on the desktop, then 1vw = 650 * 1% = 6.5px (this is a theoretical assumption, if the browser does not support 0.5px, the actual rendering might be 7px).

So v sub w or v sub H is very similar to percentage units. The difference between vw and % is:

unit meaning
% Most are relative to ancestor elements, but also relative to themselves (border-radius, translate, etc.)
vw/vh Relative to the size of the window

From the comparison, we can find that the unit of VW is similar to the unit of percentage, but there is a difference. Previously, we introduced the difficulty in converting the unit of percentage. Here, VW is more like the “ideal unit of percentage”. At any level, in terms of vw units, 1VW is equal to one hundredth of the width of the view.

There are two ways to implement a response using viewport units:

1. Use only VW as the CSS unit
  • To convert the dimensions of the design to units, we compile using the Sass function

    $vm_base: 375; $vm_base: 375; @function vw($px) { @return ($px / 375) * 100vw; }Copy the code
  • Vw is used as the unit for text, layout width, spacing, etc

    .mod_nav { background-color: #fff; &_list { display: flex; padding: vm(15) vm(10) vm(10); // Inside spacing &_item {flex: 1; text-align: center; font-size: vm(10); // Font size &_logo {display: block; margin: 0 auto; width: vm(40); // vm(40); Img {display: block; margin: 0 auto; max-width: 100%; } } &_name { margin-top: vm(2); }}}}Copy the code
  • 1 Physical pixel line (i.e. 1px under normal screen and 0.5px under HD screen) is implemented using the Transform attribute scale

    .mod_grid { position: relative; &::after {// implement 1 physical pixel bottom border line content: "; position: absolute; z-index: 1; pointer-events: none; background-color: #ddd; height: 1px; left: 0; right: 0; top: 0; @media only screen and (-webkit-min-device-pixel-ratio: 2) {-webkit-transform: scaleY(0.5); -webkit-transform-origin: 50% 0%; }}... }Copy the code
  • For graphs that need to maintain the aspect ratio, use the padding-top implementation

    .mod_banner { position: relative; padding-top: percentage(100/700); // Use padding-top height: 0; overflow: hidden; img { width: 100%; height: auto; position: absolute; left: 0; top: 0; }}Copy the code
2. Mix VW and REM

Although the page adapted by VW has a good effect, it uses viewport units to realize the layout and automatically scales depending on the viewport size. No matter whether the viewport is too large or too small, it also loses the limit of maximum and minimum widths as time goes by. At this time, we can combine REM to realize the layout

  • You can dynamically change the size of the root element by setting vw units that vary with viewport

  • Limits the maximum and minimum font size of the root element, along with the body plus the maximum and minimum width

    $vm_fontsize: 75; $vm_fontsize: 75; $vm_fontsize: 75; $vm_fontsize: 75; $vm_fontsize: 75; $vm_fontsize: 75; @function rem($px) {@return ($px / $vm_fontsize) * 1rem; } // Use vw unit for root element size $vm_design: 750; html { font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw; @media screen and (max-width: 320px) {font-size: 64px; } @media screen and (min-width: 540px) { font-size: 108px; }} {max-width: 540px; max-width: 540px; min-width: 320px; }Copy the code

5. Picture response

Here the image response includes two aspects, one is the size of the adaptive, so as to ensure that the picture in different screen resolution compression, stretching; One is to choose as high a resolution as possible depending on the screen resolution and the device pixel ratio, that is, when there is no need for high or large images on a small screen, we use small images instead, so we can reduce the network bandwidth.

1. Use max-width: 0;

Image adaptive means that the image scales with the size of the container. This code can be used:

img {
    display: inline-block;
    max-width: 100%;
    height: auto;
}
Copy the code

Inline-block elements are rendered inline relative to their surrounding content, but unlike inlining, we can set the width and height in this case. Max-width ensures that all images are equal to 100% of their width. At this point, if the elements containing the image are smaller than the inherent width of the image, the image will be scaled to take up the maximum available space), and the height of auto can ensure that the image can be scaled without distortion. If it is a background image, use the background-size attribute flexibly.

So why not use width: 100%? Because this rule causes it to appear as wide as its container. In cases where the container is much wider than the picture, the picture will be stretched unnecessarily.

2. Use srcset
<img srcset="photo_w350.jpg 1x, photo_w640.jpg 2x" src="photo_w350.jpg" alt="">
Copy the code

If the screen’s DPI is 1, it loads a double image, and if the screen’s DPI is 2, it loads a double image. Mobile phones and Macs generally have a DPI above 2, which is not a waste of traffic for a normal screen, but a high-definition experience for a retina screen.

If the browser does not support srcset, the images in SRC are loaded by default.

But you’ll notice that this is not the case. Chrome on Mac loads the 2x image in srcset and loads the SRC image at the same time. All srcsets are loaded first, and then the SRC is loaded. This strategy is a bit odd as it loads two images, not two if you don’t write SRC, but it’s not as compatible. This is probably because the browser thinks that since there is srcset, there is no need to write SRC, and if SRC is written, the user might be useful. Picture doesn’t load two

3. Use the background image
.banner{
  background-image: url(/static/large.jpg);
}

@media screen and (max-width: 767px){
  background-image: url(/static/small.jpg);
}
Copy the code
4. Use the picture label

Picturefill.min.js: indicates that the browser such as Internet Explorer does not support the picturefill

<picture> <source srcset="banner_w1000.jpg" media="(min-width: 801px)"> <source srcset="banner_w800.jpg" media="(max-width: 800px)"> <img src="banner_w800.jpg" alt=""> </picture> <! <script type="text/javascript" <script type="text/javascript" src="js/vendor/picturefill.min.js"></script>Copy the code

For example, the onload event is triggered from the img tag. Picture and source do not layout. Their width and height are both 0.

In addition, using source, you can also do some compatible processing for the image format:

<picture>
    <source type="image/webp" srcset="banner.webp">
    <img src="banner.jpg" alt="">
</picture>
Copy the code

Summary: The implementation of responsive layout can be achieved by media query + PX, media query + percentage, media query + REM + JS, VM/VH, VM/VH + REM these several ways to achieve. But every way is flawed, the mainstream media query need to select the device width dimension as a breakpoint write extra style targeted adaptation, but doing so will have trouble, only in a select few mainstream equipment size under present perfect adaptation, and the user experience is not friendly, layout remain unchanged in response to a breakpoint within the scope of the resolution, And in response to the breakpoint, the layout brings about breakpoint changes, like a record player on a cassette, “click, click, click, click, click.” First of all, it is difficult to calculate the percentage to adapt the layout. Secondly, if the percentage is used in each attribute, the attribute of the relative element is not unique, so the layout problem becomes complicated when we use percentage units. By adopting the elastic layout of DYNAMIC calculation of REM unit, it is necessary to embed a script in the head to dynamically change the font size of the root element by changing the listening resolution, so that CSS and JS are coupled together. By using pure CSS viewport units to achieve adaptive pages, it can solve both the problem of response fault and script dependency, but the compatibility is not fully accepted by the structure.

Responsive layout of the molding scheme

Today’s CSS, UI frameworks, etc., have been designed to accommodate different screen resolutions, and we can use these new features and frameworks directly to achieve responsive layouts in real projects. The following options are available:

  • Use the above methods to implement themselves, such as CSS3 Media Query, REM, VW, etc
  • Flex has flexible layout and is not compatible
  • Grid Grid layout, poor compatibility
  • The Columns grid system often relies on a UI library, such as Bootstrap

Key points of responsive layout

In actual project, we may need to integrated solutions, such as rem to do font adaptation, to do with srcset picture response type, width can be used to rem, flex, grid system to implement reactive, then you may also need to use the media queries to response the basis of the layout, therefore, a comprehensive scheme of realization of the above The following points should be noted to implement responsive layout in a project:

  • Set the viewport
  • Media queries
  • Font adaptation (font unit)
  • Percentage layout
  • Image adaptation (image response)
  • Combined with Flex, Grid, BFC, grid system and other already formed solutions

Reference article:

  1. Comparison of common solutions for responsive layouts (media queries, percentages, REM and VW/VH)
  2. Pure CSS3 is adaptive using VW and VH viewport units
  3. Do you really understand responsive layout?
  4. Mobile terminal H5 page iphone6 adaptation tips
  5. Responsive development tips
  6. Detailed front-end responsive layout, responsive graphics, and homemade grid systems
  7. Practice of responsive layout based on media query and REM
  8. Thinking of front-end design draft and workflow from the font-size of netease and Taobao
  9. Comparison of front-end adaptation schemes of mobile terminals