前端响应式/自适应/流动布局

  1. 响应式网页设计的理念是让 Web 页面在不同尺寸的设备上和窗口上都能得到友好的渲染,以获得良好的浏览体验。
  2. 响应式布局可自动调整并适应任何设备屏幕的大小,无论是 PC,平板电脑还是手机。

1. 控制视口(viewport)

控制视口这一点不论是响应式、自适应还是移动端布局都是最重要的。我们常常会使用这一句:

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"">

viewport是网页默认的宽度和高度,上面这行代码的意思是,网页宽度默认等于屏幕宽度(width=device-width),原始缩放比例(initial-scale=1)为1.0,即网页初始大小占屏幕面积的100%。

视口宽度等于设备宽度,初始缩放比最大缩放比与最小缩放比均为1,禁止用户缩放。详细描述可查看 MDN-meta。在这里的设备像素比(dpr 即 deivcePixelRatio)也就是物理像素与设备独立像素的比值,常见的有retina屏等。

2. 媒体查询

创建媒体查询一般需要以下几个部分: 媒体类型媒体特征逻辑条件

使用@media 查询,你可以针对不同的媒体类型定义不同的样式。

@media screen and (max-width: 800px) {
  body {
    background: #ccc;
  }
}

2.1 媒体类型

媒体类型是呈现页面的用户设备类型,常见的媒体类型包括以下几种:

  • all:所有的设备类型,属于默认类型。如下面示例中省略媒体类型时,默认匹配所有类型设备。
  • screen: 所有非 print 或者 speech 的设备。
  • print: 打印机设备。
  • speech: 屏幕阅读器等类似的发声设备。
/* 两种写法意义相同 */
@media (max-width: 320px) {...}
@media all and max-width: 320px {...}

由于移动设备发展迅速,Web 网页可能呈现在手机、平板、可穿戴等多种设备上,仅仅使用媒体类型检测设备特征是一项艰巨的任务,因此通常需要结合更多的媒体特征来进行判断。

2.2 媒体特征

媒体查询支持丰富的设备特征,除了我们最常看到的宽度和高度查询,还有一些其他的媒体特征比如方向、分辨率等对检测设备也很有用

设备特征取值
width长度数值,如600px
height长度数值,如600px

另外,对于部分取值为数值的属性,媒体查询可以使用 min- 或 max- 前缀表示范围,这为媒体查询提供了更方便的判断方式。例如使用 max-width: 320px 表示设备 viewport 的宽度小于等于 320px,min-width: 321px 表示 viewport 宽度大于等于 321px。

@media (max-width: 320px) { /* viewports <= 320px 时的样式*/ }
@media (min-width: 321px) { /* viewports >= 321px 时的样式*/ }

2.3 逻辑条件

  • 通过使用 andnotonly 等逻辑条件关键词,可以组合多个媒体查询条件。

  • 使用 and 操作符来合并媒体属性

  • 使用 not 可以不在某种条件下使用当前媒体查询规则

  • 使用 only 可以仅在某种条件下使用规则

// 示例是宽度大于 700px 的媒体查询条件,只在横屏情况时使用这个条件。
@media (min-width: 700px) and (orientation: landscape) { ... }

// 媒体查询匹配 viewport 宽度大于 320px 且不是打印机的设备。
@media not print and (min-width: 320px) { ... }

// 仅在 viewport 宽度大于 320px 的屏幕设备中使用
@media only screen and (min-width: 320px) { ... }

2.4 使用媒体查询设置断点

  • 如何选择网站内容的响应点,即如何选择不同 viewport 的 min-width 和 max-width 的取值,我们称为选择断点
  • 在设计断点时,可以从最小支持的屏幕宽度开始,逐渐增加屏幕宽度,覆盖不同尺寸屏幕的体验。
  • 断点的设置主要取决于产品设计本身,没有万能媒体查询的代码。

比较具有代表性的设备断点,代码如下:

/* 很小的设备(手机等,小于 600px) */
@media only screen and (max-width: 600px) {...}
/* 比较小的设备(竖屏的平板,屏幕较大的手机等, 大于 600px) */
@media only screen and (min-width: 600px) {...}
/* 中型大小设备(横屏的平板, 大于 768px) */
@media only screen and (min-width: 768px) {...}
/* 大型设备(电脑, 大于 992px) */
@media only screen and (min-width: 992px) {...}
/* 超大型设备(大尺寸电脑屏幕, 大于 1200px) */
@media only screen and (min-width: 1200px) {...}

3. 图片的自适应

响应式还必须实现图片的自动缩放。

// 这只要一行CSS代码:
img { max-width: 100%;}
// 老版本的IE不支持max-width
img { width: 100%; }

不过,有条件的话,最好还是根据不同大小的屏幕,加载不同分辨率的图片。

4 自适应图片等素材

这里我们常对图片做处理,处理的方法有很多我们可以采用HTML5 picture 标签,利用该标签可以在不同设备中显示不同的图片。如下代码:

<picture>
    <source media="(max-width: 36rem)"
        srcset="img/ad001-l-480w.png"/>
   <source srcset="img/ad001-l-1600w.png"/>
   ![](img/ad001-l.png)
</picture>
  • source 代表你要显示图片的源
  • media代表你需要什么条件下显示该图片
  • srcset 须填写图片路径
  • 当设备视口宽度大于36rem 时显示 ad001-l-480w.png 这张图片,若小于 36rem 则使用ad001-l-1600w.png 这张图片,要是浏览器不支持 picture 则使用 img 标签中的图片。
  • picture 详细信息可查看 MDN-picture 同样的这里需要注意在 IE9&IE9以下, 浏览器想使用 picture 须导入 polyfill ,如 html5shiv.js 。

5 不使用绝对宽度

由于网页会根据屏幕宽度调整布局,所以不能使用绝对宽度的布局,也不能使用具有绝对宽度的元素。这一条非常重要。

CSS代码不能指定像素宽度:

width: xxx px;

可以指定百分比宽度或自适应:

width: xxx %;

width: auto;

6 相对大小的字体

由于px是相对固定单位,字号大写直接被定死,无法随着浏览器进行缩放。

提到相对单位,最熟悉最常见的就是em和rem。

em

em是元素相对于自身的 font-size。如果自身没有设置字体大小,则根据父级元素设置大小。

<style>
  h1 {
    font-size: 20px;
    margin: 1em; /* 1em = 20px */
  }
  p {
    font-size: 14px;
    padding: 1em; /* 1em = 14px */
  }
  .outer {
    font-size: 12px;
  }
  .inner {
    font-size: 2em;
    padding: 1em; /* 1em = 24px */
  }
</style>

rem

rem= root em,顾名思义就是相对于根元素的em,是根据根元素来计算出 CSS 像素点的大小。根元素就是,而它的默认字体大小是 16px

h1 {
  font-size: 20px;
  margin: 1rem; /* 1rem = 16px */
}
p {
  font-size: 1rem; /* 1rem = 16px */
}

所以,如果我们改变根元素的字体大小,页面上所有使用rem的元素都会被重新计算元素属性并重绘。

em和rem

em和rem都是相对单位,两者都可以用来做响应式布局的单位。根据它们的特性,em和rem互有优劣。

  • em - 对于模块化的页面元素比较好,标签内的元素都根据父元素计算像素大小,只需设置最外层父元素的字体大小就可同时影响子元素,保持自定义元素具有一定的模块封闭性。但em比较难以追溯,需要逐层向上排查显式设置了字体大小的元素。
  • rem - 方便是rem最大的好处,只需知道的字体大小即可计算当前的实际像素大小。

7 视口相对单位

视口是相对于浏览器上的可视区域来说的,视口单位计算中涉及的视口都是包含滚动条的。视口单位是相对于浏览器的视口进行计算的。

vh,vw

vh和vw都是相对于视口 viewport 进行计算的单位。

  • vw- viewport width,视口宽度,1vw = 1% 视口宽度
  • vh- viewport height,视口高度,1vh = 1% 视口高度

8 流动布局

流动布局的含义是,各个区块的位置都是浮动的,不是固定不变的。

.main {
    float: right;
    width: 70%;
}

.leftBar {
    float: left;
    width: 25%;
}

float的好处:如果宽度太小,放不下两个元素,后面的元素会自动滚动到前面元素的下方,不会在水平方向overflow(溢出),避免了水平滚动条的出现。

另外,绝对定位(position: absolute)的使用,也要非常小心。

9 选择加载CSS

"自适应网页设计"的核心,就是CSS3引入的Media Query模块。它的意思就是,自动探测屏幕宽度,然后加载相应的CSS文件。

<link rel="stylesheet" type="text/css" media="screen and (max-device-width: 400px)" href="tinyScreen.css" />

上面的代码意思是,如果屏幕宽度小于400像素(max-device-width: 400px),就加载tinyScreen.css文件。

除了用html标签加载CSS文件,还可以在现有CSS文件中加载。

@import url("tinyScreen.css") screen and (max-device-width: 400px);

10 使用flex布局

11 scale方案适应全屏

React项目scale适应


      /*
      JS部分
      */
       //数据大屏自适应函数
    const handleScreenAuto = () => {
        const designDraftWidth = 1920;//设计稿的宽度
        const designDraftHeight = 960;//设计稿的高度
        //根据屏幕的变化适配的比例
        const scale = document.documentElement.clientWidth / document.documentElement.clientHeight < designDraftWidth / designDraftHeight ?
            (document.documentElement.clientWidth / designDraftWidth) :
            (document.documentElement.clientHeight / designDraftHeight);
        //缩放比例
        (document.querySelector('#screen') as any).style.transform = `scale(${scale}) translate(-50%)`;
    }

    //React的生命周期 如果你是vue可以放到mountd或created中
    useEffect(() => {
        //初始化自适应  ----在刚显示的时候就开始适配一次
        handleScreenAuto();
        //绑定自适应函数   ---防止浏览器栏变化后不再适配
        window.onresize = () => handleScreenAuto();
        //退出大屏后自适应消失   ---这是react的组件销毁生命周期,如果你是vue则写在deleted中。最好在退出大屏的时候接触自适应
        return () => window.onresize = null;
    }, [])
    

    /*
      HTML部分
    */  
    <div className="screen-wrapper">
        <div className="screen" id="screen">

        </div>
     </div>
    /*
      CSS部分  --除了设计稿的宽高是根据您自己的设计稿决定以外,其他复制粘贴就完事
    */  
  .screen-root {
    height: 100%;
    width: 100%;
    .screen {
        display: inline-block;
        width: 1920px;  //设计稿的宽度
        height: 960px;  //设计稿的高度
        transform-origin: 0 0;
        position: absolute;
        left: 50%;

    }

}

Vue项目scale适应

    /**
    js部分
    */
    mounted(){
        //初始化自适应  ----在刚显示的时候就开始适配一次
        handleScreenAuto();
        //绑定自适应函数   ---防止浏览器栏变化后不再适配
        window.onresize = () => handleScreenAuto();
    },
    deleted(){
        window.onresize = null;
    },
    methods: {
        //数据大屏自适应函数
        const handleScreenAuto = (): void => {
            const designDraftWidth = 1920;//设计稿的宽度
            const designDraftHeight = 960;//设计稿的高度
            //根据屏幕的变化适配的比例
            const scale = document.documentElement.clientWidth / document.documentElement.clientHeight < designDraftWidth / designDraftHeight ?
                (document.documentElement.clientWidth / designDraftWidth) :
                (document.documentElement.clientHeight / designDraftHeight);
            //缩放比例
            (document.querySelector('#screen') as any).style.transform = `scale(${scale}) translate(-50%)`;
        }
    }

同样。将上述生命周期和methods中的代码复制,然后在id为screen的div中编写数据大屏即可。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值