前端响应式解决方案

1,280 阅读11分钟

前端页面需要考虑兼容不同分辨率的设备,在不同设备页面呈现的效果往往并不理想,

主要有以下解决方案:

  • 针对不同浏览器用户设置不同的样式
  • 使用JS动态调整页面
  • 使用前端框架

针对不同浏览器用户设置不同的样式

即针对不同的分辨率,开发者都需要提供不一样的CSS样式。
主要通过以下两种方式达到目的:

  • 根据不同分辨率都写一套样式文件,在页面初始化时判断需要引用哪个分辨率文件解决
  • 使用@media查询

相比较而言第一种方式,很复杂。由于大众使用的设备千变万化,分辨率种类奇多,开发者都写一套不太现实,也不好维护。这里不推荐使用

@media查询会更有优势,使用@media查询,你可以针对不同的媒体类型定义不同的样式。
@media可以针对不同的屏幕尺寸设置不同的样式,特别是如果你需要设置设计响应式的页面。

假设,我们需要在宽度1024分辨率以下使用黑色的网页背景。

代码如下:

@media screen and (max-width: 1024px) {
    body {
        background: black> 前端页面通过浏览器实现跨设备(平台),不同设备(平台)拥有其各自的分辨率。  
> 只有兼容好这些设备(平台),才能开发出优先的前端页面。
> 本文主要通过响应式解决方案,解决以上问题。

### 常见的解决方案:
- 在不同浏览器视口宽度下切换样式
- 通过JavaScript根据视口宽度改样式
- 响应式解决方案

## 在不同浏览器视口宽度下切换样式
即指对不同浏览器视口宽度,提供多套样式。  
主要通过以下两种方式:

- 提供多套样式文件,切换样式文件引用
- 通过`@media`(媒体查询)

第一种可行,但很复杂。用户使用的设备(平台)种类奇多,每一种都要提供一套样式,难度大且不好维护。并**不推荐使用**。  

而使用`@media`(媒体查询)会更好,通过它能直接在样式代码中根据视口宽度切换不同样式。  

比如,我们需要在宽度1024分辨率以下启用黑色的网页背景。  
代码如下:
```css
@media screen and (max-width: 1024px) {
    body {
        background: black;
    }
}

是不是简单很多,再比如我们需要在宽度1920分辨率以上启用黑色背景。
代码如下:

@media screen and (min-width: 1920px) {
    body {
        background: black;
    }
}

如果我们把它们连起来写。 代码如下:

@media screen and (max-width: 1024px) and (min-width: 1920px) {
    body {
        background: black;
    }
}

这样就能实现视窗宽度1024分辨率以下或宽度1920分辨率以上使用黑色背景了。 哈哈,就是这么简单。这里有份设备分辨率列表有兴趣可以看下。

参考资料:CSS3 @media 媒体查询

通过JavaScript根据视口宽度改样式

使用这种方法,往往我们是通过控制class来间接控制页面的。直接操作DOM必然导致页面重绘,可能导致页面重排。性能方面会很有压力,不推荐大家使用它解决分辨率问题。但根据业务需要,使用JS控制DOM渲染还有很有必要的,毕竟它就是干这个的。

由于JS可以直接获取屏幕宽度/高度/分辨率。
可以通过以下方法:

  • 通过控制class间接控制
  • 通过改变元素style属性控制

还是实现宽度1024分辨率以下或宽度1920分辨率以上使用黑色背景。
通过控制class间接控制,代码如下:

.black {
    background: black;
}
const screenw = screen.width;
if (screenw < 1366 || screenw > 1920) {
    document.body.className = 'black';
}

通过改变元素style属性控制,代码如下:

const screenw = screen.width;
if (screenw < 1366 || screenw > 1920) {
    document.body.style.backgroundColor = 'black';
}

参考资料:JavaScript HTML DOM 元素

响应式解决方案

响应式布局主要有一下五种实现方式:

  • 百分比布局(%
  • @media(媒体查询)
  • rem方式
  • vw方式
  • flex弹性布局

百分比布局(%

当浏览器的宽度或者高度发生变化时,可通过百分比单位,通过百分比单位可以使得浏览器中的元素的宽和高随着浏览器的变化而变化,从而实现响应式的效果。

height, width属性的百分比依托于父标签的宽高。但paddingbordermargin等属性的情况又不太一样?

子元素的topbottom如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度。同样,子元素的leftright如果设置百分比,则相对于直接非static定位(默认定位)的父元素的宽度。

子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。

子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width

border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度。

缺点: 计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。
各个属性中如果使用百分比,由于相对父元素的属性并不是唯一的。会造成我们使用百分比单位容易使布局问题变得很复杂,不推荐使用。

@media(媒体查询)

使用@media媒体查询可以针对不同的媒体类型定义不同的样式,特别是响应式页面,可以针对不同屏幕的大小,编写多套样式,从而达到自适应的效果。

在前面“针对不同浏览器用户设置不同的样式”有举例。

缺点: 如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。

rem方式

rem单位是相对于字体大小的html元素,也称为根元素。 默认情况下,html元素的font-size20px。所以此时1rem = 20px

利用rem和媒体查询,在分辨率发生变换时,给它不同的font-size


body {
   font-size: 40px;
}

@media screen and (max-width: 1024px) {
    body {
        font-size: 20px;
    }
}

div {
    width: 20rem;
}

以上代码,当分辨率小于1024px时,div宽度缩小到原来大小的一半。

vw方式

css3中引入了一个新的单位vw/vh,与视图窗口有关,vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一。

与百分比布局很相似,但更好用。

flex弹性布局

弹性布局是一种十分方便的,只需要依赖于css样式的实现响应式布局的方式,也是最多用到的一种实现响应式的方法。

这里就不展开了, 给一份资料。

参考资料:了解一下CSS3弹性布局

结束语

最后,再提供一种方案,将页面整体缩放,也能适配不同设备(平台),就不展开了。
设备(平台)兼容性问题很常见。讲的不好还请大家见谅。

}

}

是不是简单很多,再比如我们需要在宽度1920分辨率以上使用黑色背景。  
代码如下:
```css
@media screen and (min-width: 1920px) {
    body {
        background: black;
    }
}

那现在我们把它们连起来写。 代码如下:

@media screen and (max-width: 1024px) and (min-width: 1920px) {
    body {
        background: black;
    }
}

这样是不是就是宽度1024分辨率以下或宽度1920分辨率以上使用黑色背景呢。
的确如此,如果想了解目前更多分辨率请点击这里

参考资料:CSS3 @media 查询

使用JS动态调整页面

使用这种方法,往往我们是通过控制class来间接控制页面的。直接操作DOM必然导致页面重绘,可能导致页面重排。性能方面会很有压力,不推荐大家使用它解决分辨率问题。但根据业务需要,使用JS控制DOM渲染还有很有必要的,毕竟它就是干这个的。

由于JS可以直接获取屏幕宽度/高度/分辨率。
可以通过以下方法:

  • 通过控制class间接控制
  • 通过改变元素style属性控制

还是实现宽度1024分辨率以下或宽度1920分辨率以上使用黑色背景。
通过控制class间接控制,代码如下:

.black {
    background: black;
}
const screenw = screen.width;
if (screenw < 1366 || screenw > 1920) {
    document.body.className = 'black';
}

通过改变元素style属性控制,代码如下:

const screenw = screen.width;
if (screenw < 1366 || screenw > 1920) {
    document.body.style.backgroundColor = 'black';
}

参考资料:JavaScript HTML DOM 元素

使用前端框架

框架主要通过实现响应式布局,让客户有更好的体验。而响应式布局有一下五种实现方式:

  • 百分比布局(%)
  • 媒体查询布局
  • rem响应式布局
  • vw响应式布局
  • flex弹性布局

百分比布局(%)

当浏览器的宽度或者高度发生变化时,可通过百分比单位,通过百分比单位可以使得浏览器中的元素的宽和高随着浏览器的变化而变化,从而实现响应式的效果。

height, width属性的百分比依托于父标签的宽高。但paddingbordermargin等属性的情况又不太一样?

子元素的topbottom如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度。同样,子元素的leftright如果设置百分比,则相对于直接非static定位(默认定位)的父元素的宽度。

子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。

子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width

border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度。

缺点: 计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。
各个属性中如果使用百分比,由于相对父元素的属性并不是唯一的。会造成我们使用百分比单位容易使布局问题变得很复杂,不推荐使用。

媒体查询布局

使用@media媒体查询可以针对不同的媒体类型定义不同的样式,特别是响应式页面,可以针对不同屏幕的大小,编写多套样式,从而达到自适应的效果。

在前面“针对不同浏览器用户设置不同的样式”有举例。

缺点: 如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。

rem响应式布局

rem单位是相对于字体大小的html元素,也称为根元素。 默认情况下,html元素的font-size20px。所以此时1rem = 20px

利用rem和媒体查询,在分辨率发生变换时,给它不同的font-size


body {
   font-size: 40px;
}

@media screen and (max-width: 1024px) {
    body {
        font-size: 20px;
    }
}

div {
    width: 20rem;
}

以上代码,当分辨率小于1024px时,div宽度缩小到原来大小的一半。

vw响应式布局

css3中引入了一个新的单位vw/vh,与视图窗口有关,vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一。

与百分比布局很相似,但更好用。

flex弹性布局

弹性布局是一种十分方便的,只需要依赖于css样式的实现响应式布局的方式,也是最多用到的一种实现响应式的方法。

这里就不展开了, 给一份资料。

参考资料:了解一下CSS3弹性布局

结论

其实还有一种方式,就是整页缩放适配不同分辨率。这个也很常用就不展开了。 分辨率问题非常常见,个人还是喜欢通过响应式的方式解决该问题。