移动端H5-响应式布局方案

耶温

1803字约6分钟

2024-05-09

移动端H5-响应式布局方案

响应式设计是指在开发 HTML5 网页时,采用一系列技术和方法,使网页能够根据不同设备的屏幕尺寸、分辨率和方向自动调整布局和样式,从而提供最佳的用户体验。响应式设计的核心理念是“一个网站,适应所有设备”,通过灵活的布局、媒体查询和流式网格等技术,确保网页在手机、平板和桌面等不同设备上都能良好显示。

但是由于移动设备和PC端的屏幕大小和方位的不同。PC大部分是横屏,移动端设备为竖屏,操作习惯的不同,以及PC端的大部分的浏览器页面宽度会比移动端设备大很多。因此我们在日常开发中,通常会开发两套web页,一套是PC端的,一套是移动端的。

  • 一套PC端的,用来适配Mac,PC 端等中屏以上。大部分的浏览器页面宽度(Viewport Size)CSS像素在 1280px 以上。
  • 一套移动端的,用来适配手机等小屏。手机的页面宽度(Viewport Size)CSS像素在 320px 以上。平板的页面大小(Viewport Size)CSS像素大部分在 800px 左右。我们可以使用响应式布局,来适应手机,平板等不同设备的屏幕大小。

我们将在下面主要介绍实现移动端响应式布局的两个方案。

Rem 方案

rem 是 CSS 中的一种单位,代表“根元素的字体大小”(root em)。它是相对于文档根元素(通常是 <html> 标签)的字体大小来计算的。使用 rem 单位可以帮助实现响应式设计,使得布局和字体大小更易于管理和调整。

  • rem 是 CSS3 新增的一个相对单位(root em,根 em)
  • 只根据当前页面 HTML 页面的 font-size 设置,如果根目录的 font-size18px,则 1rem = 18px

因此我们可以使用 rem 单位来实现响应式布局。动态设置 html 的 font-size 大小,来实现响应式布局。

媒体查询

在不同的屏幕尺寸(Viewport Size)下,设置不同的 font-size 大小。

@media screen and (min-width: 320px) {
  html {
    font-size: 32px;
  }
}
@media screen and (min-width: 375px) {
  html {
    font-size: 37.5px;
  }
}
@media screen and (min-width: 414px) {
  html {
    font-size: 41.4px;
  }
}
@media screen and (min-width: 750px) {
  html {
    font-size: 75px;
  }
}

动态修改

我们可以通过 js 动态修改 html 的 font-size 大小,来实现响应式布局。

<script>
  // 根据屏幕尺寸大小调整html的fontsize
  function setHtmlFontSize() {
    const width = document.documentElement.clientWidth;
    // 把宽度除以10,得到rem的大小,平分为十份
    document.documentElement.style.fontSize = width / 10 + "px";
  }
  //   初始化
  setHtmlFontSize();
  //   监听屏幕尺寸变化事件
  window.addEventListener("resize", setHtmlFontSize);
  //   监听屏幕翻转事件
  window.addEventListener("orientationchange", setHtmlFontSize);
</script>

封装插件使用。

(function(global) {
    // 创建一个 FontSizeAdjuster 构造函数
    function FontSizeAdjuster(options) {
        this.defaultSize = options.defaultSize || 16; // 默认字体大小
        this.designWidth = options.designWidth || 375; // 设计宽度
        this.resize(); // 初始化时设置字体大小
        this.bindEvents(); // 绑定窗口 resize 事件
    }

    // 设置字体大小的方法
    FontSizeAdjuster.prototype.resize = function() {
        var width = window.innerWidth; // 获取窗口宽度
        var fontSize = this.defaultSize * (width / this.designWidth); // 根据宽度线性缩放
        // 设置根元素的字体大小
        document.documentElement.style.fontSize = fontSize + 'px';
    };

    // 绑定窗口 resize 事件
    FontSizeAdjuster.prototype.bindEvents = function() {
        var self = this;
        window.addEventListener('resize', function() {
            self.resize();
        });
    };

    // 将插件暴露给全局
    global.FontSizeAdjuster = FontSizeAdjuster;

})(window);


// 使用插件
var fontSizeAdjuster = new FontSizeAdjuster({
    defaultSize: 16, // 默认字体大小
    designWidth: 375 // 设计宽度
});

注意事项

  • 在设置盒子的宽度时,我们推荐使用百分比单位,这样可以保证在不同屏幕尺寸下,盒子的宽度占比保持一致。
  • 需要注意的是,我们在使用百分比%宽度的盒子布局时,需要注意在不同屏幕尺寸下,盒子里的内容是否会溢出或者换行。

插件推荐

  • Flexible.js:是一个流行的 JavaScript 插件,旨在根据设备宽度动态设置根元素的字体大小。

  • postcss-pxtorem:这个插件可以将 px 单位自动转换为 rem 单位。在构建过程中使用它,方便地将设计稿中的像素值转换为 rem。

Viewport 方案

在移动端开发中,使用 viewport 方案可以帮助我们更好地控制页面的缩放和布局。通过设置 viewport 元素,我们可以确保页面在不同设备上以适当的比例显示。

简单来说就是通过缩放来实现移动端各个尺寸的适配,适配方案就是动态创建 mate viewport 属性,根据当前屏幕尺寸动态设置缩放值。

Viewport方案的优势:

  • 可以根据不同设备的屏幕尺寸自动调整页面的大小和布局,保证页面在不同设备上的显示效果一致。
  • 可以通过设置 viewport 的 initial-scale 相关属性,将所有设备布局视口的宽度调整为设计图的宽度,从而实现移动端适配。

属性说明

属性说明备注
width以 px 为单位定义 viewport 的宽度一个正整数或者字符串 device-width
height以 px 为单位定义 viewport 的高度一个正整数或者字符串 device-height
initial-scale定义网页在加载时的初始缩放比例一个 0.0 到 10.0 之间的正数
maximum-scale定义最大缩放值一个 0.0 到 10.0 之间的正数
minimum-scale定义最小缩放值一个 0.0 到 10.0 之间的正数
user-scalable布尔值,是否可以缩放yes 或 no

动态修改

使通过设置 viewport 的 initial-scale 相关属性 , 将所有设备布局视口的宽度调整为设计图的宽度

//定义设计稿宽度为375
const DESIGN_WIDTH = 375;
//通过设置meta元素中content的initial-scale值达到移动端适配
const setViewport = function() {
  //计算当前屏幕的宽度与设计稿比例
  let scale = window.screen.width / DESIGN_WIDTH;
  // 获取元素
  let meta = document.querySelector("meta[name=viewport]");
  let content = `width=${DESIGN_WIDTH}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}`;
  // 判断是否已存在
  if (!meta) {
    meta = document.createElement("meta");
    meta.setAttribute("name", "viewport");
    document.head.appendChild(meta);
  }
  meta.setAttribute("content", content);
};
setViewport();
//   监听屏幕变化事件
window.addEventListener("resize", setViewport);
//   监听屏幕翻转事件
window.addEventListener("orientationchange", setViewport);

注意事项

  • 该方法在PC端不会生效。

封装插件

(function(global) {
    // 定义设计稿宽度
    const DESIGN_WIDTH = 375;

    // 创建一个 ResponsiveLayout 构造函数
    function ResponsiveLayout(options) {
        this.designWidth = options.designWidth || DESIGN_WIDTH; // 设计宽度
        this.setViewport(); // 初始化时设置 viewport
        this.bindEvents(); // 绑定事件
    }

    // 设置 viewport 的方法
    ResponsiveLayout.prototype.setViewport = function() {
        // 计算当前屏幕的宽度与设计稿比例
        let scale = window.screen.width / this.designWidth;
        // 获取 meta 元素
        let meta = document.querySelector("meta[name=viewport]");
        let content = `width=${this.designWidth}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}`;
        
        // 判断是否已存在
        if (!meta) {
            meta = document.createElement("meta");
            meta.setAttribute("name", "viewport");
            document.head.appendChild(meta);
        }
        meta.setAttribute("content", content);
    };

    // 绑定事件的方法
    ResponsiveLayout.prototype.bindEvents = function() {
        const self = this;
        // 监听屏幕变化事件
        window.addEventListener("resize", function() {
            self.setViewport();
        });
        // 监听屏幕翻转事件
        window.addEventListener("orientationchange", function() {
            self.setViewport();
        });
    };

    // 将插件暴露给全局
    global.ResponsiveLayout = ResponsiveLayout;

})(window);

// 使用插件
var responsiveLayout = new ResponsiveLayout({
    designWidth: 375 // 设计宽度
});