响应式技术笔记

media query

@media screen and (max-width: 375px)

按照断点设置不同的 css

CSS Grid

1
2
3
4
display: grid
grid-template-columns: xxx xxx
grid-template-rows: xxx xxx
grid-template-areas: 'x x x';

候选技术

flex

container

1
2
3
4
5
display: flex;
flex-flow: ;
justify-content: ;
align-items: ;
align-content: ;

items

1
2
3
flex: flex-grow flex-shrink flex-basis;
order: ;
self-align: ;

目前最好用的移动 layout 技术

rem

根据 root 的 font-size 设置后续尺寸。网页上 root 就是 html,也就是根据 html 的 font-size 决定尺寸单位。

做法:

  1. JS 动态获取 root 元素的宽度 documentElement | bodyclientHeight
  2. 根据获取的宽度设置一个合理的rem
  3. 使用 scss 之类技术为后续其他元素的px单位转为rem单位

Flexible

基本概念

视窗 viewport

  1. PC 端就是浏览器窗口
  2. 移动端为了 CSS 布局提供两个 viewport
    1. visual viewport 虚拟
    2. layout viewport 布局

物理像素 physical pixel

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。

设备独立像素 density-independent pixel

与密度无关,计算机坐标系统的一个点,可以有程序使用的虚拟像素

CSS 像素

抽象单位,用于浏览器上,精确度量 web 页面的内容,DIPs(与上一个有关)

屏幕密度

设备表面像素数量 PPI

设备像素比 device pixel ratio

dpr 物理像素和 DIPs 之间对应关系 dpr = pp / dip

JS: window.devicePixelRatio

CSS:

1
2
3
device-pixel-ratio
min-device-pixel-ratio
max-device-pixel-ratio

meta 标签

告诉浏览器渲染 web 页面

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

rem

Font size of the root element

前端实现方案

使用库 lib-flexible

1
2
3
<meta name="flexible" content="initial-dpr=2" />
<script src="build/flexible_css.debug.js"></script>
<script src="build/flexible.debug.js"></script>

执行这个 JS 后,会在<html>元素上增加一个data-dpr属性,以及一个font-size样式。JS 会根据不同的设备添加不同的data-dpr值,比如说2或者3,同时会给html加上对应的font-size的值,比如说75px

页面其他元素可以通过rem单位设置。

flexible 实质

  1. JS 动态改写 meta 标签
  2. html元素添加data-dpr属性并动态改写值
  3. html元素添加font-size属性并动态改写值

具体案例

  1. 为兼容vw``vh,规定1rem = 10a 1a = 页面的 1/100

  2. 用工具转换 px 到 rem:

    1. SCSS
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @function px2em($px, $base-font-size: 16px) {
    @if (unitless($px)) {
    @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you";
    @return px2em($px + 0px); // That may fail.
    } @else if (unit($px) == em) {
    @return $px;
    }
    @return ($px / $base-font-size) * 1em;
    }
    1. 其他工具包括 PostCSS 之类
  3. 字号不使用 rem

    1. 不希望文本变小,而希望看到更多文本

    2. 更适应字体点阵尺寸

      1. 效果

      2. HTML

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        div {
        width: 1rem;
        height: 0.4rem;
        font-size: 12px;
        }
        [data-dpr="2"] div {
        font-size: 24px;
        }
        [data-dpr="3"] div {
        font-size: 36px;
        }
      3. Scss

        1
        2
        3
        4
        5
        6
        7
        8
        9
        @mixin font-dpr($font-size) {
        font-size: $font-size;
        [data-dpr="2"] & {
        font-size: $font-size * 2;
        }
        [data-dpr="3"] & {
        font-size: $font-size * 3;
        }
        }
      4. 使用 scss 的 mixin @include font-dpr(16px)

vw/vh

各种概念

  1. offsetHeight/offsetWidth = content + padding + border
  2. clientHeight/clientWidth = content + padding - scroll(if)
  3. scrollHeight/scrollWidth = content + padding - scroll(if) + ::before/after(if) 【包括不在可视区域内】
  4. window.innerHeight = window viewport including scrollbar
  5. document.documentElement.clientWidth/Height = window.innerWidth/Height - scroll
  6. window.outerHeight = innerHeight + UI
  7. screen.width/height 屏幕尺寸
  8. vw | vh | vin | vmax
  9. 宽度 750px,1vw = 750/100 = 7.5px
  10. 使用场景
  11. 容器适配
  12. 文本适配
  13. 大于1px的边框、圆角、阴影
  14. padding margin

技术点

  1. 使用vw来实现页面的适配,并且通过 PostCSS 的插件 postcss-px-to-viewportpx转换成vw
  2. 为了更好的实现长宽比,特别是针对于imgvedioiframe元素,通过 PostCSS 插件 postcss-aspect-ratio-mini来实现,在实际使用中,只需要把对应的宽和高写进去即可
  3. 为了解决1px的问题,使用 PostCSS 插件 postcss-write-svg ,自动生成border-image或者background-image的图片

降级处理

使用 CSS Houdini 或者 CSS Polyfill 处理。

Viewport 不足之处

  1. margin 使用 px:转换成 padding 或者 border-box 或者 calc()
  2. px -> vw 的偏差