Better

Ethan的博客,欢迎访问交流

如何确定响应式边界和统一团队使用规范

网站开发中,通常需要对不同的分辨率进行适配,但具体每个分辨率的临界点是啥呢?

确定临界点

直接参考 Bootstrap 的设置,其规则如下

  • < 576px 竖屏手机
  • >= 576px 横屏手机
  • >= 768px 平板
  • >= 992px 桌面
  • >= 1200px 大屏
  • >= 1600px 超大屏

创建 mixins

确定临界点后,就是统一团队的使用规范,答案就是使用 mixins,既能方便使用,同时还能帮助我们达到统一的目的。我们注意到 Bootstrap 是提供了 SCSS 的一系列 mixins 的,使用规则如下

@include media-breakpoint-up(xs|sm|md|lg|xl) { ... }
@include media-breakpoint-down(xs|sm|md|lg|xl) { ... }
@include media-breakpoint-between(xs|sm|md|lg|xl, xs|sm|md|lg|xl) { ... }

在 Sass 的实现原理大概如下,通过 content 关键字即可

// Mixin
@mixin responsive($maxWidth) {
    @media only screen and (max-width: $maxWidth) {
        @content;
    }
}

// Usage
.bacon {
    width: 100%;

    @include responsive(450px) {
        float: left;
        margin-top: 10px;
    }
}

那么如何在 Less 中达到类似的目的呢。需要使用到 v.1.7 提供的 rulesets

// Mixin
.responsive(@maxWidth; @rules) {
    @media only screen and (max-width: @maxWidth) {
        @rules();
    }
}

// Usage
.bacon {
    width: 100%;

    .responsive(450px, {
        float: left;
        margin-top: 10px;
    });
}

Less Mixins

确定好边界点之后,就是创建 mixin util 啦,编写的过程中发现,xs 不好设置变量值,因为其是 < 576 的规则,因此直接翻看 Bootstrap 源码了。发现其定义如下

(xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)

现在屏幕都变大了,因此还需要加上我们的超大屏 1600 的边界点,具体的 Less 代码如下

@offset: 0.02px;

/** 竖屏手机设备 (0, 576) */
@breakpoint-xs: 0;

/** 横屏手机设备 [576, 768) */
@breakpoint-sm: 576px;

/** 平板设备 [768, 992) */
@breakpoint-md: 768px;

/** 桌面设备 [992, 1200) */
@breakpoint-lg: 992px;

/** 大屏幕设备 [1200, 1600) */
@breakpoint-xl: 1200px;

/** 超大屏幕设备 [1600, +) */
@breakpoint-xxl: 1600px;

.media-breakpoint-up(@point; @rules) {
  @var: 'breakpoint-@{point}';
  @media (min-width: @@var) {
    @rules();
  }
}

.media-breakpoint-down(@point; @rules) {
  @var: 'breakpoint-@{point}';
  @media (max-width: @@var - @offset) {
    @rules();
  }
}

.media-breakpoint-between(@lower, @upper, @rules) {
  @lowerVar: 'breakpoint-@{lower}';
  @upperVar: 'breakpoint-@{upper}';
  @media (min-width: @@lowerVar) and (max-width: @@upperVar - @offset) {
    @rules();
  }
}

响应式组件

有些情况,我们并不能通过 CSS 完全搞定我们的需要,可能还是需要借助 JS 来帮助。这里可以借助社区组件 react-media,为统一团队规范,我们再套一层,如下

import React from 'react';
import Media from 'react-media';

const GLOBAL_MEDIA_QUERIES = {
  xs: '(max-width: 575.98px)',
  sm: '(min-width: 576px) and (max-width: 767.98px)',
  md: '(min-width: 768px) and (max-width: 991.98px)',
  lg: '(min-width: 992px) and (max-width: 1199.98px)',
  xl: '(min-width: 1200px) and (max-width: 1599.98px)',
  xxl: '(min-width: 1600px)',
};

type Matches = {
  xs: boolean;
  sm: boolean;
  md: boolean;
  lg: boolean;
  xl: boolean;
  xxl: boolean;
};

interface MediaQueryProps {
  render?: () => React.ReactNode;
  children?: (matches: Matches) => React.ReactNode | React.ReactNode;
}

function MediaQuery({ render, children }: MediaQueryProps) {
  return (
    <Media render={render} queries={GLOBAL_MEDIA_QUERIES}>
      {children}
    </Media>
  );
}

export default MediaQuery;

资料



留言