回顾rem+vw+响应式布局方案

222 阅读3分钟

1. rem和vw布局

  1. 实现除图片外的等比例缩放(图片如果只设置宽或者高,本身就是等比例的),各布局方式并不孤立,根据需要可以结合使用。
  • rem布局方案
  • rem+vw布局方案
  • vw布局方案

2. rem布局方案

  1. 设计稿的宽度一般是750(375*2)
  2. 375是iphone6的屏幕尺寸,选择它的宽度的2倍作为设计稿的宽度
  3. 案例:已知设计稿的测量值,要求使用rem实现等比例缩放
  • 注意 ** 1rem === html标签的字体大小 **
  • 案例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html {
            font-size: 10px;
        }
        .tabbar-layout {
            position: fixed;
            bottom: 0;
            left: 0;
            width: 75rem;
            height: 9.6rem;
            box-shadow: 0 -0.4rem 0.4rem rgba(0, 0, 0, .4);
        }
        img {
            width: 100%;
        }
    </style>
</head>
<body>
    <!-- 
        实现rem响应式布局的思路
            1.把px改成rem
            2.1rem === html的字体大小
            3.监控屏幕尺寸,尺寸发生改变时,修改html的字体大小,js来做
        假设:html的字体大小是10px
     -->
    <div class="tabbar-layout">
        <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112101446793.png" alt="">
    </div>
    <script>
        // 定义手机屏幕尺寸发生变化的时候,使用js动态的修改html的字体大小
        function setHtmlFontSize(){
            // 获取用户的手机尺寸
            const clientWidth = document.documentElement.clientWidth || window.innerWidth || document.documentElement.getBoundingClientRect().width
            // 计算html标签对应的字体大小
            const htmlFontSize = clientWidth / 75 + 'px'
            // 通过js来动态修改html标签的字体大小
            document.documentElement.style.fontSize = htmlFontSize
        }
        // 监控尺寸变化,每次尺寸变化,调用setHtmlFontSize函数
        window.onresize = setHtmlFontSize;
    </script>
</body>
</html>

2. rem+vw布局方案

  • 上面的移动端适配方案,因为加载和运行了js,所以会消耗一定的时间和性能,可不可以即使用rem,又不使用js呢?
  • 之所以使用js修改html字体大小,因为html的字体大小是px,它是绝对单位
  • 如果html的字体大小是vw?是相对单位,该如果获取html的字体大小是多少vw呢?
宽度手机尺寸html字体大小
75rem750px/100vw10px/?vw
75rem375px/100vw5px/?vw
75rem400px/100vw?vw
75rem200px/100vw?vw
  • 只需要修改html的font-size为vw单位即可,其他不需要改动也不需要写js监控尺寸的变化来更改html的字体大小
  • vw如何计算呢?假设我们使用的是750px宽度的设计稿,96px ===> ?vw
    96px/750px === ?vw/100vw
    750px*?vw = 96px*100vw
    ?vw = 9600/750
    最后得出 96px = 12.8vw
宽度手机尺寸html字体大小
75rem750px/100vw10px/1.33333vw
75rem375px/100vw5px/1.3333vw
75rem400px/100vw?vw
75rem200px/100vw?vw
  • 案例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html {
            font-size: 1.33333vw;
        }
        .tabbar-layout {
            position: fixed;
            bottom: 0;
            left: 0;
            width: 100vw;
            height: 12.8vw;
            box-shadow: 0 -0.4rem 0.4rem rgba(0, 0, 0, .4);
        }
        img {
            width: 100%;
        }
    </style>
</head>
<body>
    <!-- 
        实现rem响应式布局的思路
            1.把px改成rem
            2.1rem === html的字体大小
            3.监控屏幕尺寸,尺寸发生改变时,修改html的字体大小,js来做
        假设:html的字体大小是10px
     -->
    <div class="tabbar-layout">
        <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112101446793.png" alt="">
    </div>
    <script>
        // 定义手机屏幕尺寸发生变化的时候,使用js动态的修改html的字体大小
        function setHtmlFontSize(){
            // 获取用户的手机尺寸
            const clientWidth = document.documentElement.clientWidth || window.innerWidth || document.documentElement.getBoundingClientRect().width
            // 计算html标签对应的字体大小
            const htmlFontSize = clientWidth / 75 + 'px'
            // 通过js来动态修改html标签的字体大小
            document.documentElement.style.fontSize = htmlFontSize
        }
        // 监控尺寸变化,每次尺寸变化,调用setHtmlFontSize函数
        window.onresize = setHtmlFontSize;
    </script>
</body>
</html>

3. vscode中计算rem和vw单位的插件推荐

  • rem:px2rem
  • vw: px2vw

image.png

4. 媒体查询

  1. Media querys,针对各种大小的屏幕写样式,让页面在不同大小的屏幕上都能正常显示
  2. 媒体查询书写
       /** 例如这样 */
       @media screen and (min-width: 320px) {
            这里书写样式
        }

4.1 媒体类型

  • all (所有设备默认值)
  • screen (屏幕设备)
  • print (打印设备)
  • speech (屏幕阅读器)

4.2 媒体查询中的逻辑

  • and() 或,not非
        @media screen and (min-width: 320px) and (max-width:750px) {
            在320px-750px宽度要生效的样式
        }

4.3 断点的设置

  1. 业界主流的做法
Extra samll 超小屏Small 小屏Medium 中屏Large大屏Extra large 超大屏
xs:< 576pxsm: 576px - 758pxmd 768px - 992pxlg 922px - 1200pxxl: >=1200px
  1. 改变屏幕大小,当页面显示不正常的时候,就需要设置断点了

4.4 媒体查询的策略

  1. 无策略
  2. PC端优先
  3. 移动端优先
  4. 案例:三星官网首页
  • 无策略方案布局
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            padding-top: 100px;
        }
        img {
            width: 100%;
        }
        div.row {
            width: 100%;
            display: flex;
            flex-wrap: wrap;
        }
        div.column {
            padding: 10px 0;
            background-color: olivedrab;
            border: 1px solid #444444;
        }
        /* 无策略方案 */
        @media screen and (max-width: 576px) {
            div.column {
                width: 100%;
            }
        }
        @media screen and (min-width: 576px) and (max-width: 768px) {
            div.column {
                width: 50%;
            }
        }
        @media screen and (min-width: 768px) and (max-width: 992px) {
            div.column {
                width: 25%;
            }
        }
        @media screen and (min-width: 992px) and (max-width: 1200px) {
            div.column {
                width: 16.88888%;
            }
        }
        @media screen and (min-width: 1200px){
            div.column {
                width: 8.3333%;
            }
        }
    </style>
</head>
<body>
    <div class="row">
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
    </div>
</body>
</html>
  • PC端优先,从大到小写
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            padding-top: 100px;
        }
        img {
            width: 100%;
        }
        div.row {
            width: 100%;
            display: flex;
            flex-wrap: wrap;
        }
        div.column {
            width: 8.333%;
            padding: 10px 0;
            background-color: olivedrab;
            border: 1px solid #444444;
        }
        /* PC端优先 */
        @media screen and (max-width: 1200px) {
            div.column {
                width: 16.6667%;
            }
        }
        @media screen and (max-width: 992px) {
            div.column {
                width: 25%;
            }
        }
        @media screen and (max-width: 768px) {
            div.column {
                width: 50%;
            }
        }
        @media screen and (max-width: 576px) {
            div.column {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="row">
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
    </div>
</body>
</html>
  • 移动端优先,从小到大写
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            padding-top: 100px;
        }
        img {
            width: 100%;
        }
        div.row {
            width: 100%;
            display: flex;
            flex-wrap: wrap;
        }
        div.column {
            width: 100%;
            padding: 10px 0;
            background-color: olivedrab;
            border: 1px solid #444444;
        }
        /* 移动端优先 */
        @media screen and (min-width: 576px) {
            div.column {
                width: 50%;
            }
        }
        @media screen and (min-width: 768px) {
            div.column {
                width: 25%;
            }
        }
        @media screen and (min-width: 992px) {
            div.column {
                width: 16.6667%;
            }
        }
        @media screen and (min-width: 1200px) {
            div.column {
                width: 8.3333%;
            }
        }
    </style>
</head>
<body>
    <div class="row">
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
        <div class="column">
            <img src="https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202112111633921.png" alt="">
        </div>
    </div>
</body>
</html>