前端响应式布局适配方案

响应式布局是为了同一页面在不同设备屏幕尺寸下都能正常显示。

常用响应式布局方案

>>媒体查询方案

媒体查询有两种用法

  • 直接在 css 文件中定义不同屏幕下的样式
  • 通过 link 中的媒体查询,不同屏幕引用不同的分辨率

如果要实现两个不同屏幕下的样式,可以这样使用媒体查询

/** 方式一:直接定义两个屏幕的样式 **/
@media screen and (max-width: 320px) {
  .home {
    width: 80%;
    font-size: 14px
  }
}

@media screen and (min-width: 768px) {
  .home {
    width: 100%;
    font-size: 10px
  }
}

<!-- 方式二:通过 link 引用不同屏幕的 css 文件 -->
<link rel="stylesheet" media="(max-width: 320px)" href="pc.css" />
<link rel="stylesheet" media="(min-width: 768px)" href="laptop.css" />

max-width:对最大宽度的限制。max-width: 320px,意思是说当设备屏幕宽度不大于320px时,则采纳这条声明对应的样式规则。

min-width:对最小宽度的限制。min-width: 768px,意思是说当设备屏幕宽度不小于768px时,则采纳这条声明对应的样式规则。

>>动态rem / em方案

em 和 rem 都是相对单位,区别在于

  • em 根据自身字体大小计算
  • rem 根据根节点 html 的字体大小计算(root em),默认是 16 px
    所有单位都是相对于根元素html的font-size来决定大小的,当页面的size发生变化时,只需要改变font-size的值,那么以remem为固定单位的元素的大小也会发生响应的变化。所以我们只要根据屏幕宽度和设计图的宽度动态声明 font-size 的大小,然后以 remem 作为长度单位声明所有节点的几何属性,就可以实现自适应布局的效果。
function autoResponse(width = 750) {
  const target = document.documentElement
  if (target.clientWidth >= 600) {
    target.style.fontSize = '40px'
  } else {
    target.style.fontSize = `${target.clientWidth / width * 100}px`
  }
}

autoResponse()

window.addEventListener('resize', autoResponse)

rem响应式的布局思想:

  • 一般不要给元素设置具体的宽度,但是对于一些小图标可以设定具体宽度值。
  • 高度值可以设置固定值。
  • 所有设置的固定值都用rem做单位(首先在HTML总设置一个基准值:pxrem的对应比例,然后在效果图上获取px值,布局的时候转化为rem值)
  • js获取真实屏幕的宽度,让其除以设计稿的宽度,算出比例,把之前的基准值按照比例进行重新的设定,这样项目就可以在移动端自适应了。

rem布局的缺点:

  • 在响应式布局中,必须通过js来动态控制根元素font-size的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前。
  • 要在 html 的 meta 属性中将布局窗口设置为屏幕宽度,并且禁止缩放屏幕。

>>视口单位 vw/vh 方案

css3引入了新的单位 vw/vh

  • vw:表示相对于视图窗口的宽度,1vw等于视口宽度的1%
  • vh:表示相对于视图窗口的高度,1vh等于视口高度的1%

另外还有vmin和vmax两个相关单位

  • vmin:vw和vh中的较小值
  • vmax:vw和vh中的较大值

使用视口单位来实现响应式有两种做法:

1、仅使用vw作为CSS单位
  • 对于设计稿的尺寸转换为vw、vh为单位
//iPhone 6尺寸作为设计稿基准
@function vm(px) {
    @return (px / 375) * 100vw;
}
  • 无论是文本还是布局宽度、间距等都使用vm作为单位
.mod_nav {
    background-color: #fff;
    &_list {
        display: flex;
        padding: vm(15) vm(10) vm(10); // 内间距
        &_item {
            flex: 1;
            text-align: center;
            font-size: vm(10); // 字体大小
            &_logo {
                display: block;
                margin: 0 auto;
                width: vm(40); // 宽度
                height: vm(40); // 高度
                img {
                    display: block;
                    margin: 0 auto;
                    max-width: 100%;
                }
            }
            &_name {
                margin-top: vm(2);
            }
        }
    }
}
  • 1物理像素线(也就是普通屏幕下1px,高清屏幕下0.5px的情况)采用transform属性scale实现
.mod_grid {
    position: relative;

    &::after {
        // 实现1物理像素的下边框线
        content: '';
        position: absolute;
        z-index: 1;
        pointer-events: none;
        background-color: #ddd;
        height: 1px;
        left: 0;
        right: 0;
        top: 0;
        @media only screen and (-webkit-min-device-pixel-ratio: 2) {
            -webkit-transform: scaleY(0.5);
            -webkit-transform-origin: 50% 0%;
        }
    }
    ...
}
  • 对于需要保持宽高比的图,应该用padding-top实现
.mod_banner {
    position: relative;

    padding-top: percentage(100/700); // 使用padding-top
    height: 0;
    overflow: hidden;
    img {
        width: 100%;
        height: auto;
        position: absolute;
        left: 0;
        top: 0; 
    }
}
2、搭配vw和rem

虽然采用vw适配后的页面效果很好,但是它是利用视口单位实现的布局,依赖视口大小而自动缩放,无论视口过大还是过小,它也随着时候过大或者过小,失去了最大最小宽度的限制,此时我们可以结合rem来实现布局

  • 给根元素大小设置随着视口变化而变化的vw单位,这样就可以实现动态改变其大小
  • 限制根元素字体大小的最大最小值,配合body加上最大宽度和最小宽度
// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
$vm_fontsize: 75; // iPhone 6尺寸的根元素大小基准值
@function rem($px) {
     @return ($px / $vm_fontsize ) * 1rem;
}
// 根元素大小使用 vw 单位
$vm_design: 750;
html {
    font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw; 
    // 同时,通过Media Queries 限制根元素最大最小值
    @media screen and (max-width: 320px) {
        font-size: 64px;
    }
    @media screen and (min-width: 540px) {
        font-size: 108px;
    }
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
    max-width: 540px;
    min-width: 320px;
}

参考文章:

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYluwd8w' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片