前端响应式布局


前端响应式布局原理与方案(详细版)



响应式布局:在不同屏幕尺寸下, 同一页面有不同的布局。
传统的开发模式:PC端搞一套布局,移动端搞一套布局。
使用了响应式布局,只需要开发一套即可,缺点是CSS比较重

响应式设计和自适应设计的区别:响应式开发一套界面,通过检测视口分辨率,针对不同客户端在客户端做代码处理,展现不同的布局和内容
自适应需要开发多套界面,通过检测视口分辨率,判断当前访问的设备是PC端、平板、手机,从而请求服务层返回不同的页面

1、媒体查询

不同尺寸设置不同css样式

关键点如何选择不同的尺寸区间,即如何确定媒体查询的分割点。
如果我们选择600px,900px,1200px,1800px作为分割点,可以适配到常见的14个机型
当然这只是其中的一种分割方案,我们还可以这样划分:480px,800px,1400px,1400px
而作为曾经典型的响应式布局框架,Bootstrap是怎么进行断点的呢?
在这里插入图片描述
上面的分割方案不一定满足项目中的实际需求,我们可以先用跨度大的分割点进行分割,如果出现不适配的情况可以再根据实际情况增加新的分割点。

移动优先 OR PC优先

移动用的多,pc不多
不管是移动优先还是PC优先,都是依据当随着屏幕宽度增大或减小的时候,后面的样式会覆盖前面的样式。因此,移动端优先首先使用的是min-width,PC端优先使用的max-width。

移动优先:

<style>
    /* iphone6 7 8 */
    body {
        background-color: yellow;
    }

    /* iphone 5   [, 320]是红色*/
    @media screen and (max-width: 320px) {
        body {
            background-color: red;
        }
    }

    /* iphoneX  [375, 414-1px] 为啥没有显示#0FF000;  */
    @media screen and (min-width: 375px) and (-webkit-device-pixel-ratio: 3) {
        body {
            background-color: #0FF000;
        }
    }

    /* iphone6 7 8 plus  [414, 768-1]是Blue  */
    @media screen and (min-width: 414px) {
        body {
            background-color: blue;
        }
    }

    /* ipad  [768px]*/
    @media screen and (min-width: 768px) {
        body {
            background-color: green;
        }
    }

    /* ipad pro [1024px,  1100-1]*/
    @media screen and (min-width: 1024px) {
        body {
            background-color: #f0f;
        }
    }


    /* pc  [1100px,] */
    @media screen and (min-width: 1100px) {
        body {
            background-color: black;
        }
    }
</style>

PC优先:

/* pc width > 1024px */
    body {
        background-color: yellow;
    }
/* ipad pro */
@media screen and (max-width: 1024px) {
    body {
        background-color: #FF00FF;
    }
}
/* ipad */
@media screen and (max-width: 768px) {
    body {
        background-color: green;
    }
}
/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
    body {
        background-color: blue;
    }
}
/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    body {
        background-color: #0FF000;
    }
}
/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
    body {
        background-color: #0FF000;
    }
}
/* iphone5 */
@media screen and (max-width: 320px) {
    body {
        background-color: #0FF000;
    }
}

device-width device-height 是用在移动端
width height 用在pc端

<body>
    <script src="./dist/app.js"></script>
    <div class="div0">
        sgfdl
    </div>
</body>
<style>
    .div0 {
        width: 100px;
     
       
    }
    /* screen */
    /* 最小屏幕尺寸200px 最大300px */
    @media screen and (min-device-width: 200px) and (max-device-width: 300px){
        .div0 {
            background-color: rebeccapurple;
        }
    }
    @media screen and (min-device-width: 301px) and (max-device-width: 500px) {
        .div0 {
            background-color: blue;
        }
    }
</style>

在这里插入图片描述
在pc端做个案例: 【500, 800】px一行一个div , 【801, 1000】第一行两个,第二行放1个, 【1001,无穷】一行三个div
主要是媒体查询,根据不同宽度选择不同的style, 使用float使元素左浮动,利用%宽使得元素是否在一行显示
在这里插入图片描述

<body>
    <script src="./dist/app.js"></script>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
    </div>
</body>
<style>
    .div0 {
       height: 100px;
        width: 100%;
        background-color: blueviolet;
    }
    /* 给三个div添加浮动 ,添加高度不然不显示*/
    .div0 div {
        float: left;
        height: 100px;
    }
    /* 不同的div设置不同颜色 */
    .div0 div:nth-child(1) {
        background-color: antiquewhite;
    }

    .div0 div:nth-child(2) {
        background-color: aqua;
    }

    .div0 div:nth-child(3) {
        background-color: blue;
    }

    /* 设置不同尺寸的style */
    @media screen and (min-width: 500px) and (max-width: 800px) {
        .div0 div{
            /* 给子元素统一设置宽度 */
            width: 100%;
        }
    }
    @media screen and (min-width: 801px) and (max-width: 1000px) {
        .div0 div {
            width: 50%;
        }
    }
    @media screen and (min-width: 10001px) {
        .div0 div {
            width: 33.3%;
        }
    }
</style>

在这里插入图片描述

<style media="(min-device-width: 200px) and (max-device-width: 400px)">
    .div0 div {
        /* 给子元素统一设置宽度 */
        width: 100%;
    }
</style>
<style media="(min-device-width: 401px) and (max-device-width: 500px)">
    .div0 div {
        width: 50%;
    }
</style>
<style media="(min-device-width: 501px)">
    .div0 div {
        width: 33.3%;
    }
</style>

在这里插入图片描述

2、百分比布局

子元素中的百分比
子元素的heightwidth使用百分比,是相对直接父元素的widthheight
子元素的topbottomleftright 是相对非static定位的父元素的高度
子元素的paddingmargin是相对直接父元素的width与父元素的height无关
border-radiustranslatebackground-size是相对自身的宽度

用百分比单位来实现响应式的布局,有明显的以下两个缺点:
计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。
可以看出,各个属性中如果使用百分比,相对父元素的属性并不是唯一的。比如width和height相对于父元素的width和height,而margin、padding不管垂直还是水平方向都相对比父元素的宽度、border-radius则是相对于元素自身等等,造成我们使用百分比单位容易使布局问题变得复杂。

3、rem布局

rem是css3新增的,移动端支持度很高
rem是相对单位,相对根元素html的font-size来决定大小(em是相对父元素的)
通过rem实现响应式布局只需要动态改变font-size即可

rem布局思想:

  • 一般不给元素设置具体的宽度,但是相对于一些小图标可以设置具体宽度值
  • 高度设置固定值即可
  • 所有固定值使用rem作为单位

rem布局的缺点:
必须通过js来动态控制根元素font-size的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前

    /*上述代码中将视图容器分为10份,font-size用十分之一的宽度来表示,最后在header标签中执行这段代码,就可以动态定义font-size的大小
    ,从而1rem在不同的视觉容器中表示不同的大小,用rem固定单位可以实现不同容器内布局的自适应。*/
function refreshRem() {
  
    var docEl = document.documentElement;
    var width = docEl.getBoundingClientRect().width;
    var rem = width / 10;
    console.log(width, rem);
    docEl.style.fontSize = rem + 'px';
    // flexible.rem = window.rem = rem;
  
}
window.addEventListener('resize', refreshRem);

REM布局也是目前多屏幕适配的最佳方式。默认情况下我们html标签的font-size为16px,我们利用媒体查询,设置在不同设备下的字体大小。

/* pc width > 1100px */
html{ font-size: 100%;}
body {
    background-color: yellow;
    font-size: 1.5rem;
}
/* ipad pro */
@media screen and (max-width: 1024px) {
    body {
      background-color: #FF00FF;
      font-size: 1.4rem;
    }
}
/* ipad */
@media screen and (max-width: 768px) {
    body {
      background-color: green;
      font-size: 1.3rem;
    }
}
/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
    body {
      background-color: blue;
      font-size: 1.25rem;
    }
}
/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
    body {
      background-color: #0FF000;
      font-size: 1.125rem;
    }
}
/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
    body {
      background-color: #0FF000;
      font-size: 1rem;
    }
}
/* iphone5 */
@media screen and (max-width: 320px) {
    body {
      background-color: #0FF000;
      font-size: 0.75rem;
    }
}

4.视口单位

css3中引入了一个新的单位vw/vh,与视图窗口有关,vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度,除了vw和vh外,还有vmin和vmax两个相关的单位。各个单位具体的含义如下

单位 含义
vw 相对于视窗的宽度,1vw 等于视口宽度的1%,即视窗宽度是100vw
vh 相对于视窗的高度,1vh 等于视口高度的1%,即视窗高度是100vh
vmin vw和vh中的较小值
vmax vw和vh中的较大值

在这里插入图片描述

用视口单位度量,视口宽度为100vw,高度为100vh(左侧为竖屏情况,右侧为横屏情况)。例如,在桌面端浏览器视口尺寸为650px,那么 1vw = 650 * 1% = 6.5px(这是理论推算的出,如果浏览器不支持0.5px,那么实际渲染结果可能是7px)。
那么vw或者vh很类似百分比单位。vw和%的区别为:

单位 含义
% 大部分相对于祖先元素,也有相对于自身的情况比如(border-radius、translate等)
vw/vh 相对于视窗的尺寸

5.图片响应式

这里的图片响应式包括两个方面,一个就是大小自适应,这样能够保证图片在不同的屏幕分辨率下出现压缩、拉伸的情况;一个就是根据不同的屏幕分辨率和设备像素比来尽可能选择高分辨率的图片,也就是当在小屏幕上不需要高清图或大图,这样我们用小图代替,就可以减少网络带宽了。

1.使用max-width(图片自适应):

图片自适应意思就是图片能随着容器的大小进行缩放,可以采用如下代码:

img {
    display: inline-block;
    max-width: 100%;
    height: auto;
}

inline-block 元素相对于它周围的内容以内联形式呈现,但与内联不同的是,这种情况下我们可以设置宽度和高度。
max-width保证了图片能够随着容器的进行等宽扩充(容器大1000px,图片小如400px, 则图片会占据自身的100%即400px。 容器小300px, 图片大400px, 则图片占容器的100% 300px)
而height为auto可以保证图片进行等比缩放而不至于失真。如果是背景图片的话要灵活运用background-size属性
那么为什么不能用width:100%呢?因为这条规则会导致它显示得跟它的容器一样宽。在容器比图片宽得多的情况下,图片会被无谓地拉伸。

2.使用srcset

<img srcset="photo_w350.jpg 1x, photo_w640.jpg 2x" src="photo_w350.jpg" alt="">

如果屏幕的dpi = 1的话则加载1倍图,而dpi = 2则加载2倍图,手机和mac基本上dpi都达到了2以上,这样子对于普通屏幕来说不会浪费流量,而对于视网膜屏来说又有高清的体验。
如果浏览器不支持srcset,则默认加载src里面的图片。

但是你会发现实际情况并不是如此,在Mac上的Chrome它会同时加载srcset里面的那张2x的,还会再去加载src里面的那张,加载两张图片。顺序是先把所有srcset里面的加载完了,再去加载src的。这个可能是因为浏览器认为,既然有srcset就不用写src了,如果写了src,用户可能是有用的。而使用picture就不会加载两张

3.使用background-image

.banner{
  background-image: url(/static/large.jpg);
}

@media screen and (max-width: 767px){
  background-image: url(/static/small.jpg);
}

总结:响应式布局的实现可以通过媒体查询+px,媒体查询+百分比,媒体查询+rem+js,vm/vh,vm/vh +rem这几种方式来实现。但每一种方式都是有缺点的,媒体查询需要选取主流设备宽度尺寸作为断点针对性写额外的样式进行适配,但这样做会比较麻烦,只能在选取的几个主流设备尺寸下呈现完美适配,另外用户体验也不友好,布局在响应断点范围内的分辨率下维持不变,而在响应断点切换的瞬间,布局带来断层式的切换变化,如同卡带的唱机般“咔咔咔”地一下又一下。通过百分比来适配首先是计算麻烦,第二各个属性中如果使用百分比,其相对的元素的属性并不是唯一的,这样就造成我们使用百分比单位容易使布局问题变得复杂。通过采用rem单位的动态计算的弹性布局,则是需要在头部内嵌一段脚本来进行监听分辨率的变化来动态改变根元素字体大小,使得CSS与JS 耦合了在一起。通过利用纯css视口单位实现适配的页面,是既能解决响应式断层问题,又能解决脚本依赖的问题的,但是兼容性还没有完全能结构接受。
响应式布局的成型方案
现在的css,UI框架等都已经考虑到了适配不同屏幕分辨率的问题,实际项目中我们可以直接使用这些新特性和框架来实现响应式布局。可以有以下选择方案:

利用上面的方法自己来实现,比如CSS3 Media Query,rem,vw等
Flex弹性布局,兼容性较差
Grid网格布局,兼容性较差
Columns栅格系统,往往需要依赖某个UI库,如Bootstrap

响应式布局的要点
在实际项目中,我们可能需要综合上面的方案,比如用rem来做字体的适配,用srcset来做图片的响应式,宽度可以用rem,flex,栅格系统等来实现响应式,然后可能还需要利用媒体查询来作为响应式布局的基础,因此综合上面的实现方案,项目中实现响应式布局需要注意下面几点:

设置viewport
媒体查询
字体的适配(字体单位)
百分比布局
图片的适配(图片的响应式)
结合flex,grid,BFC,栅格系统等已经成型的方案

参考文章:

响应式布局的常用解决方案对比(媒体查询、百分比、rem和vw/vh)
纯CSS3使用vw和vh视口单位实现自适应
你真的了解响应式布局吗?
移动端H5页面 iphone6的适配技巧
响应式开发心得
详解前端响应式布局、响应式图片,与自制栅格系统
基于媒体查询和 rem 的响应式布局实践
从网易与淘宝的font-size思考前端设计稿与工作流
移动端前端适配方案对比

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: <div style="width: 100%; overflow: hidden;"> <div style="width: 50%; float: left;"> <div style="width: 100%; height: 20px; background-color: #e6e6e6;"></div> <div style="width: 100%; height: 20px; background-color: #f2f2f2;"></div> <div style="width: 100%; height: 20px; background-color: #e6e6e6;"></div> </div> <div style="width: 50%; float: left;"> <div style="width: 100%; height: 20px; background-color: #f2f2f2;"></div> <div style="width: 100%; height: 20px; background-color: #e6e6e6;"></div> <div style="width: 100%; height: 20px; background-color: #f2f2f2;"></div> </div> </div> ### 回答2: 当然,我可以帮你写一段前端响应式布局的代码。 首先,我们需要使用HTMLCSS来实现这个布局。以下是一段简单的代码示例,展示了如何创建一个响应式的布局: ```html <!DOCTYPE html> <html> <head> <style> .container { display: flex; flex-wrap: wrap; } .item { width: 100%; padding: 20px; box-sizing: border-box; } @media screen and (min-width: 600px) { .item { width: 50%; } } @media screen and (min-width: 900px) { .item { width: 33.33%; } } </style> </head> <body> <div class="container"> <div class="item" style="background-color: #F44336;">Item 1</div> <div class="item" style="background-color: #E91E63;">Item 2</div> <div class="item" style="background-color: #9C27B0;">Item 3</div> <div class="item" style="background-color: #673AB7;">Item 4</div> <div class="item" style="background-color: #3F51B5;">Item 5</div> <div class="item" style="background-color: #2196F3;">Item 6</div> <div class="item" style="background-color: #4CAF50;">Item 7</div> <div class="item" style="background-color: #FF9800;">Item 8</div> <div class="item" style="background-color: #795548;">Item 9</div> </div> </body> </html> ``` 在这个示例中,我们使用了Flexbox来创建布局。`.container`类定义了一个Flex容器,`.item`类定义了Flex项(子元素)。在不同的屏幕宽度下,`.item`的宽度会有所调整,从而实现响应式布局。 通过`@media`查询,我们可以在特定的屏幕宽度下设置不同的样式。在示例中,当屏幕宽度大于等于600像素时,每个`.item`的宽度为50%;当屏幕宽度大于等于900像素时,每个`.item`的宽度为33.33%。 你可以根据需要修改`.item`的样式和媒体查询的条件来适应你的具体需求。希望这段代码能够对你有帮助! ### 回答3: 前端响应式布局是指根据设备的屏幕大小和分辨率自动调整网页布局,使得网页能够在不同的设备上呈现出最佳效果。下面是一个简单的前端响应式布局代码示例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>响应式布局示例</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .container { display: flex; flex-wrap: wrap; justify-content: space-between; } .item { width: 300px; margin-bottom: 20px; background-color: lightblue; padding: 20px; } @media (max-width: 768px) { .item { width: 100%; } } </style> </head> <body> <div class="container"> <div class="item">Item 1</div> <div class="item">Item 2</div> <div class="item">Item 3</div> <div class="item">Item 4</div> </div> </body> </html> ``` 在上述代码中,我们使用了Flexbox布局(`.container`),使得四个`.item`元素能够水平排布,并且间距相等。每个`.item`元素的宽度为300px。但是当设备的宽度小于768px时,我们使用了媒体查询(`@media`)来改变`.item`的宽度为100%,使得它们能够自动适应不同设备的屏幕大小。 这段代码是一个简单的响应式布局示例,你可以根据实际需求进行修改和扩展,以适应你的项目需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值